From dfc517b05395d925a4d7b1ce9633a849f9468e70 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 23 Feb 2006 15:52:24 +0000 Subject: r13658: More moving around of files: - Collect the generic utility functions into a lib/util/ (a la GLib is for the GNOME folks) - Remove even more files from include/ (This used to be commit ba62880f5b05c2a505dc7f54676b231197a7e707) --- source4/dynconfig.c | 43 + source4/dynconfig.h | 43 + source4/heimdal_build/config.mk | 1 + source4/include/byteorder.h | 224 ----- source4/include/core.h | 6 +- source4/include/dynconfig.h | 43 - source4/include/enums.h | 38 - source4/include/includes.h | 24 +- source4/include/ioctl.h | 33 - source4/include/safe_string.h | 55 -- source4/include/smb_macros.h | 73 -- source4/include/structs.h | 4 - source4/include/trans2.h | 435 --------- source4/lib/basic.mk | 42 +- source4/lib/capability.c | 112 --- source4/lib/data_blob.c | 209 ----- source4/lib/debug.c | 205 ----- source4/lib/debug.h | 66 -- source4/lib/dprintf.c | 107 --- source4/lib/fault.c | 213 ----- source4/lib/fsusage.c | 149 --- source4/lib/gencache.c | 375 -------- source4/lib/gencache/gencache.c | 375 ++++++++ source4/lib/genrand.c | 314 ------- source4/lib/idtree.c | 384 -------- source4/lib/module.c | 97 -- source4/lib/ms_fnmatch.c | 219 ----- source4/lib/mutex.c | 52 -- source4/lib/mutex.h | 69 -- source4/lib/pidfile.c | 116 --- source4/lib/select.c | 169 ---- source4/lib/signal.c | 140 --- source4/lib/substitute.c | 165 ---- source4/lib/system.c | 98 -- source4/lib/time.c | 596 ------------ source4/lib/unix_privs.c | 68 -- source4/lib/util.c | 737 --------------- source4/lib/util/README | 296 ++++++ source4/lib/util/byteorder.h | 224 +++++ source4/lib/util/capability.c | 112 +++ source4/lib/util/config.mk | 34 + source4/lib/util/data_blob.c | 209 +++++ source4/lib/util/debug.c | 205 +++++ source4/lib/util/debug.h | 66 ++ source4/lib/util/dprintf.c | 107 +++ source4/lib/util/fault.c | 213 +++++ source4/lib/util/fsusage.c | 149 +++ source4/lib/util/genrand.c | 314 +++++++ source4/lib/util/idtree.c | 384 ++++++++ source4/lib/util/module.c | 97 ++ source4/lib/util/ms_fnmatch.c | 219 +++++ source4/lib/util/mutex.c | 52 ++ source4/lib/util/mutex.h | 71 ++ source4/lib/util/pidfile.c | 116 +++ source4/lib/util/safe_string.h | 55 ++ source4/lib/util/select.c | 169 ++++ source4/lib/util/signal.c | 140 +++ source4/lib/util/substitute.c | 165 ++++ source4/lib/util/system.c | 98 ++ source4/lib/util/time.c | 596 ++++++++++++ source4/lib/util/unix_privs.c | 68 ++ source4/lib/util/util.c | 737 +++++++++++++++ source4/lib/util/util.h | 81 ++ source4/lib/util/util_file.c | 385 ++++++++ source4/lib/util/util_getent.c | 284 ++++++ source4/lib/util/util_pw.c | 89 ++ source4/lib/util/util_sock.c | 128 +++ source4/lib/util/util_str.c | 1209 +++++++++++++++++++++++++ source4/lib/util/util_strlist.c | 292 ++++++ source4/lib/util/util_unistr.c | 150 +++ source4/lib/util/xfile.c | 384 ++++++++ source4/lib/util/xfile.h | 49 + source4/lib/util_file.c | 385 -------- source4/lib/util_getent.c | 284 ------ source4/lib/util_pw.c | 89 -- source4/lib/util_sock.c | 128 --- source4/lib/util_str.c | 1209 ------------------------- source4/lib/util_strlist.c | 292 ------ source4/lib/util_unistr.c | 150 --- source4/lib/version.c | 63 -- source4/lib/xfile.c | 384 -------- source4/lib/xfile.h | 49 - source4/libcli/clifile.c | 1 + source4/libcli/raw/interfaces.h | 2 - source4/libcli/raw/ioctl.h | 33 + source4/libcli/raw/signing.h | 4 + source4/libcli/raw/trans2.h | 435 +++++++++ source4/librpc/rpc/dcerpc_smb2.c | 2 +- source4/main.mk | 2 +- source4/ntvfs/common/brlock.c | 7 +- source4/ntvfs/config.mk | 15 +- source4/ntvfs/posix/config.mk | 2 +- source4/ntvfs/posix/pvfs_ioctl.c | 2 +- source4/ntvfs/print/vfs_print.c | 2 +- source4/ntvfs/unixuid/config.mk | 2 - source4/param/loadparm.c | 2 + source4/rpc_server/lsa/dcesrv_lsa.c | 1 + source4/rpc_server/unixinfo/dcesrv_unixinfo.c | 1 + source4/script/mkversion.sh | 4 +- source4/smb_server/smb_server.h | 2 + source4/torture/raw/ioctl.c | 2 +- source4/torture/torture.c | 2 +- source4/winbind/wb_samba3_cmd.c | 2 +- 103 files changed, 8923 insertions(+), 8681 deletions(-) create mode 100644 source4/dynconfig.h delete mode 100644 source4/include/byteorder.h delete mode 100644 source4/include/dynconfig.h delete mode 100644 source4/include/enums.h delete mode 100644 source4/include/ioctl.h delete mode 100644 source4/include/safe_string.h delete mode 100644 source4/include/smb_macros.h delete mode 100644 source4/include/trans2.h delete mode 100644 source4/lib/capability.c delete mode 100644 source4/lib/data_blob.c delete mode 100644 source4/lib/debug.c delete mode 100644 source4/lib/debug.h delete mode 100644 source4/lib/dprintf.c delete mode 100644 source4/lib/fault.c delete mode 100644 source4/lib/fsusage.c delete mode 100644 source4/lib/gencache.c create mode 100644 source4/lib/gencache/gencache.c delete mode 100644 source4/lib/genrand.c delete mode 100644 source4/lib/idtree.c delete mode 100644 source4/lib/module.c delete mode 100644 source4/lib/ms_fnmatch.c delete mode 100644 source4/lib/mutex.c delete mode 100644 source4/lib/mutex.h delete mode 100644 source4/lib/pidfile.c delete mode 100644 source4/lib/select.c delete mode 100644 source4/lib/signal.c delete mode 100644 source4/lib/substitute.c delete mode 100644 source4/lib/system.c delete mode 100644 source4/lib/time.c delete mode 100644 source4/lib/unix_privs.c delete mode 100644 source4/lib/util.c create mode 100644 source4/lib/util/README create mode 100644 source4/lib/util/byteorder.h create mode 100644 source4/lib/util/capability.c create mode 100644 source4/lib/util/config.mk create mode 100644 source4/lib/util/data_blob.c create mode 100644 source4/lib/util/debug.c create mode 100644 source4/lib/util/debug.h create mode 100644 source4/lib/util/dprintf.c create mode 100644 source4/lib/util/fault.c create mode 100644 source4/lib/util/fsusage.c create mode 100644 source4/lib/util/genrand.c create mode 100644 source4/lib/util/idtree.c create mode 100644 source4/lib/util/module.c create mode 100644 source4/lib/util/ms_fnmatch.c create mode 100644 source4/lib/util/mutex.c create mode 100644 source4/lib/util/mutex.h create mode 100644 source4/lib/util/pidfile.c create mode 100644 source4/lib/util/safe_string.h create mode 100644 source4/lib/util/select.c create mode 100644 source4/lib/util/signal.c create mode 100644 source4/lib/util/substitute.c create mode 100644 source4/lib/util/system.c create mode 100644 source4/lib/util/time.c create mode 100644 source4/lib/util/unix_privs.c create mode 100644 source4/lib/util/util.c create mode 100644 source4/lib/util/util.h create mode 100644 source4/lib/util/util_file.c create mode 100644 source4/lib/util/util_getent.c create mode 100644 source4/lib/util/util_pw.c create mode 100644 source4/lib/util/util_sock.c create mode 100644 source4/lib/util/util_str.c create mode 100644 source4/lib/util/util_strlist.c create mode 100644 source4/lib/util/util_unistr.c create mode 100644 source4/lib/util/xfile.c create mode 100644 source4/lib/util/xfile.h delete mode 100644 source4/lib/util_file.c delete mode 100644 source4/lib/util_getent.c delete mode 100644 source4/lib/util_pw.c delete mode 100644 source4/lib/util_sock.c delete mode 100644 source4/lib/util_str.c delete mode 100644 source4/lib/util_strlist.c delete mode 100644 source4/lib/util_unistr.c delete mode 100644 source4/lib/version.c delete mode 100644 source4/lib/xfile.c delete mode 100644 source4/lib/xfile.h create mode 100644 source4/libcli/raw/ioctl.h create mode 100644 source4/libcli/raw/trans2.h diff --git a/source4/dynconfig.c b/source4/dynconfig.c index 742c96df2a2..c72b64bcac6 100644 --- a/source4/dynconfig.c +++ b/source4/dynconfig.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. Copyright (C) 2001 by Martin Pool Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003. + Copyright (C) Stefan Metzmacher 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,6 +19,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "includes.h" +#include "version.h" + /** * @file dynconfig.c * @@ -90,3 +94,42 @@ const char *dyn_JSDIR = JSDIR; const char *dyn_WINBINDD_SOCKET_DIR = WINBINDD_SOCKET_DIR; +const char *samba_version_string(void) +{ + const char *official_string = SAMBA_VERSION_OFFICIAL_STRING; +#ifdef SAMBA_VERSION_RELEASE_NICKNAME + const char *release_nickname = SAMBA_VERSION_RELEASE_NICKNAME; +#else + const char *release_nickname = NULL; +#endif +#ifdef SAMBA_VERSION_VENDOR_SUFFIX + const char *vendor_suffix = SAMBA_VERSION_VENDOR_SUFFIX; +#else + const char *vendor_suffix = NULL; +#endif +#ifdef SAMBA_VERSION_VENDOR_PATCH + const char *vendor_patch = SAMBA_VERSION_VENDOR_PATCH; +#else + const char *vendor_patch = NULL; +#endif + static char *samba_version; + static BOOL init_samba_version; + + if (init_samba_version) { + return samba_version; + } + + samba_version = talloc_asprintf(talloc_autofree_context(), + "%s%s%s%s%s%s%s%s", + official_string, + (vendor_suffix?"-":""), + (vendor_suffix?vendor_suffix:""), + (vendor_patch?"-":""), + (vendor_patch?vendor_patch:""), + (release_nickname?" (":""), + (release_nickname?release_nickname:""), + (release_nickname?")":"")); + + init_samba_version = True; + return samba_version; +} diff --git a/source4/dynconfig.h b/source4/dynconfig.h new file mode 100644 index 00000000000..5acf5b7338a --- /dev/null +++ b/source4/dynconfig.h @@ -0,0 +1,43 @@ +/* + Unix SMB/CIFS implementation. + Copyright (C) 2001 by Martin Pool + Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003. + + + 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. +*/ + +/** + * @file dynconfig.h + * + * @brief Exported global configurations. + **/ + +extern const char *dyn_SBINDIR, *dyn_BINDIR; +extern const char *dyn_CONFIGFILE; +extern const char *dyn_NCALRPCDIR; +extern const char *dyn_LOGFILEBASE; +extern const char *dyn_LMHOSTSFILE; +extern const char *dyn_LIBDIR; +extern const char *dyn_MODULESDIR; +extern const char *dyn_SHLIBEXT; +extern const char *dyn_LOCKDIR; +extern const char *dyn_PIDDIR; +extern const char *dyn_SMB_PASSWD_FILE; +extern const char *dyn_PRIVATE_DIR; +extern const char *dyn_SWATDIR; +extern const char *dyn_JSDIR; +extern const char *dyn_SETUPDIR; +extern const char *dyn_WINBINDD_SOCKET_DIR; diff --git a/source4/heimdal_build/config.mk b/source4/heimdal_build/config.mk index 0e652665268..a9d49f6082f 100644 --- a/source4/heimdal_build/config.mk +++ b/source4/heimdal_build/config.mk @@ -345,6 +345,7 @@ NOPROTO = YES # Start SUBSYSTEM HEIMDAL_GLUE [SUBSYSTEM::HEIMDAL_GLUE] OBJ_FILES = glue.o +REQUIRED_SUBSYSTEMS = LIBNETIF # End SUBSYSTEM HEIMDAL_GLUE ####################### diff --git a/source4/include/byteorder.h b/source4/include/byteorder.h deleted file mode 100644 index 941dee9e88f..00000000000 --- a/source4/include/byteorder.h +++ /dev/null @@ -1,224 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SMB Byte handling - Copyright (C) Andrew Tridgell 1992-1998 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 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. -*/ - -#ifndef _BYTEORDER_H -#define _BYTEORDER_H - -/* - This file implements macros for machine independent short and - int manipulation - -Here is a description of this file that I emailed to the samba list once: - -> I am confused about the way that byteorder.h works in Samba. I have -> looked at it, and I would have thought that you might make a distinction -> between LE and BE machines, but you only seem to distinguish between 386 -> and all other architectures. -> -> Can you give me a clue? - -sure. - -The distinction between 386 and other architectures is only there as -an optimisation. You can take it out completely and it will make no -difference. The routines (macros) in byteorder.h are totally byteorder -independent. The 386 optimsation just takes advantage of the fact that -the x86 processors don't care about alignment, so we don't have to -align ints on int boundaries etc. If there are other processors out -there that aren't alignment sensitive then you could also define -CAREFUL_ALIGNMENT=0 on those processors as well. - -Ok, now to the macros themselves. I'll take a simple example, say we -want to extract a 2 byte integer from a SMB packet and put it into a -type called uint16_t that is in the local machines byte order, and you -want to do it with only the assumption that uint16_t is _at_least_ 16 -bits long (this last condition is very important for architectures -that don't have any int types that are 2 bytes long) - -You do this: - -#define CVAL(buf,pos) (((uint8_t *)(buf))[pos]) -#define PVAL(buf,pos) ((uint_t)CVAL(buf,pos)) -#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8) - -then to extract a uint16_t value at offset 25 in a buffer you do this: - -char *buffer = foo_bar(); -uint16_t xx = SVAL(buffer,25); - -We are using the byteoder independence of the ANSI C bitshifts to do -the work. A good optimising compiler should turn this into efficient -code, especially if it happens to have the right byteorder :-) - -I know these macros can be made a bit tidier by removing some of the -casts, but you need to look at byteorder.h as a whole to see the -reasoning behind them. byteorder.h defines the following macros: - -SVAL(buf,pos) - extract a 2 byte SMB value -IVAL(buf,pos) - extract a 4 byte SMB value -SVALS(buf,pos) signed version of SVAL() -IVALS(buf,pos) signed version of IVAL() - -SSVAL(buf,pos,val) - put a 2 byte SMB value into a buffer -SIVAL(buf,pos,val) - put a 4 byte SMB value into a buffer -SSVALS(buf,pos,val) - signed version of SSVAL() -SIVALS(buf,pos,val) - signed version of SIVAL() - -RSVAL(buf,pos) - like SVAL() but for NMB byte ordering -RSVALS(buf,pos) - like SVALS() but for NMB byte ordering -RIVAL(buf,pos) - like IVAL() but for NMB byte ordering -RIVALS(buf,pos) - like IVALS() but for NMB byte ordering -RSSVAL(buf,pos,val) - like SSVAL() but for NMB ordering -RSIVAL(buf,pos,val) - like SIVAL() but for NMB ordering -RSIVALS(buf,pos,val) - like SIVALS() but for NMB ordering - -it also defines lots of intermediate macros, just ignore those :-) - -*/ - - -/* - on powerpc we can use the magic instructions to load/store - in little endian -*/ -#if (defined(__powerpc__) && defined(__GNUC__)) -static __inline__ uint16_t ld_le16(const uint16_t *addr) -{ - uint16_t val; - __asm__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr)); - return val; -} - -static __inline__ void st_le16(uint16_t *addr, const uint16_t val) -{ - __asm__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); -} - -static __inline__ uint32_t ld_le32(const uint32_t *addr) -{ - uint32_t val; - __asm__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr)); - return val; -} - -static __inline__ void st_le32(uint32_t *addr, const uint32_t val) -{ - __asm__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); -} -#define HAVE_ASM_BYTEORDER 1 -#endif - - - -#undef CAREFUL_ALIGNMENT - -/* we know that the 386 can handle misalignment and has the "right" - byteorder */ -#if defined(__i386__) -#define CAREFUL_ALIGNMENT 0 -#endif - -#ifndef CAREFUL_ALIGNMENT -#define CAREFUL_ALIGNMENT 1 -#endif - -#define CVAL(buf,pos) ((uint_t)(((const uint8_t *)(buf))[pos])) -#define CVAL_NC(buf,pos) (((uint8_t *)(buf))[pos]) /* Non-const version of CVAL */ -#define PVAL(buf,pos) (CVAL(buf,pos)) -#define SCVAL(buf,pos,val) (CVAL_NC(buf,pos) = (val)) - -#if HAVE_ASM_BYTEORDER - -#define _PTRPOS(buf,pos) (((const uint8_t *)buf)+(pos)) -#define SVAL(buf,pos) ld_le16((const uint16_t *)_PTRPOS(buf,pos)) -#define IVAL(buf,pos) ld_le32((const uint32_t *)_PTRPOS(buf,pos)) -#define SSVAL(buf,pos,val) st_le16((uint16_t *)_PTRPOS(buf,pos), val) -#define SIVAL(buf,pos,val) st_le32((uint32_t *)_PTRPOS(buf,pos), val) -#define SVALS(buf,pos) ((int16_t)SVAL(buf,pos)) -#define IVALS(buf,pos) ((int32_t)IVAL(buf,pos)) -#define SSVALS(buf,pos,val) SSVAL((buf),(pos),((int16_t)(val))) -#define SIVALS(buf,pos,val) SIVAL((buf),(pos),((int32_t)(val))) - -#elif CAREFUL_ALIGNMENT - -#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8) -#define IVAL(buf,pos) (SVAL(buf,pos)|SVAL(buf,(pos)+2)<<16) -#define SSVALX(buf,pos,val) (CVAL_NC(buf,pos)=(uint8_t)((val)&0xFF),CVAL_NC(buf,pos+1)=(uint8_t)((val)>>8)) -#define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16)) -#define SVALS(buf,pos) ((int16_t)SVAL(buf,pos)) -#define IVALS(buf,pos) ((int32_t)IVAL(buf,pos)) -#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((uint16_t)(val))) -#define SIVAL(buf,pos,val) SIVALX((buf),(pos),((uint32_t)(val))) -#define SSVALS(buf,pos,val) SSVALX((buf),(pos),((int16_t)(val))) -#define SIVALS(buf,pos,val) SIVALX((buf),(pos),((int32_t)(val))) - -#else /* CAREFUL_ALIGNMENT */ - -/* this handles things for architectures like the 386 that can handle - alignment errors */ -/* - WARNING: This section is dependent on the length of int16_t and int32_t - being correct -*/ - -/* get single value from an SMB buffer */ -#define SVAL(buf,pos) (*(const uint16_t *)((const char *)(buf) + (pos))) -#define SVAL_NC(buf,pos) (*(uint16_t *)((char *)(buf) + (pos))) /* Non const version of above. */ -#define IVAL(buf,pos) (*(const uint32_t *)((const char *)(buf) + (pos))) -#define IVAL_NC(buf,pos) (*(uint32_t *)((char *)(buf) + (pos))) /* Non const version of above. */ -#define SVALS(buf,pos) (*(const int16_t *)((const char *)(buf) + (pos))) -#define SVALS_NC(buf,pos) (*(int16_t *)((char *)(buf) + (pos))) /* Non const version of above. */ -#define IVALS(buf,pos) (*(const int32_t *)((const char *)(buf) + (pos))) -#define IVALS_NC(buf,pos) (*(int32_t *)((char *)(buf) + (pos))) /* Non const version of above. */ - -/* store single value in an SMB buffer */ -#define SSVAL(buf,pos,val) SVAL_NC(buf,pos)=((uint16_t)(val)) -#define SIVAL(buf,pos,val) IVAL_NC(buf,pos)=((uint32_t)(val)) -#define SSVALS(buf,pos,val) SVALS_NC(buf,pos)=((int16_t)(val)) -#define SIVALS(buf,pos,val) IVALS_NC(buf,pos)=((int32_t)(val)) - -#endif /* CAREFUL_ALIGNMENT */ - -/* now the reverse routines - these are used in nmb packets (mostly) */ -#define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF)) -#define IREV(x) ((SREV(x)<<16) | (SREV((x)>>16))) - -#define RSVAL(buf,pos) SREV(SVAL(buf,pos)) -#define RSVALS(buf,pos) SREV(SVALS(buf,pos)) -#define RIVAL(buf,pos) IREV(IVAL(buf,pos)) -#define RIVALS(buf,pos) IREV(IVALS(buf,pos)) -#define RSSVAL(buf,pos,val) SSVAL(buf,pos,SREV(val)) -#define RSSVALS(buf,pos,val) SSVALS(buf,pos,SREV(val)) -#define RSIVAL(buf,pos,val) SIVAL(buf,pos,IREV(val)) -#define RSIVALS(buf,pos,val) SIVALS(buf,pos,IREV(val)) - -/* Alignment macros. */ -#define ALIGN4(p,base) ((p) + ((4 - (PTR_DIFF((p), (base)) & 3)) & 3)) -#define ALIGN2(p,base) ((p) + ((2 - (PTR_DIFF((p), (base)) & 1)) & 1)) - - -/* macros for accessing SMB protocol elements */ -#define VWV(vwv) ((vwv)*2) - -/* 64 bit macros */ -#define SBVAL(p, ofs, v) (SIVAL(p,ofs,(v)&0xFFFFFFFF), SIVAL(p,(ofs)+4,((uint64_t)(v))>>32)) -#define BVAL(p, ofs) (IVAL(p,ofs) | (((uint64_t)IVAL(p,(ofs)+4)) << 32)) - -#endif /* _BYTEORDER_H */ diff --git a/source4/include/core.h b/source4/include/core.h index d0c92880de0..0ffbeea6a40 100644 --- a/source4/include/core.h +++ b/source4/include/core.h @@ -24,10 +24,6 @@ #ifndef _SAMBA_CORE_H #define _SAMBA_CORE_H -/* - * Define VOLATILE if needed. - */ - #define False (0) #define True (1) #define Auto (2) @@ -54,4 +50,4 @@ typedef uint64_t NTTIME; typedef NTSTATUS (*init_module_fn) (void); -#endif /* _SMB_H */ +#endif /* _SAMBA_CORE_H */ diff --git a/source4/include/dynconfig.h b/source4/include/dynconfig.h deleted file mode 100644 index 5acf5b7338a..00000000000 --- a/source4/include/dynconfig.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Copyright (C) 2001 by Martin Pool - Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003. - - - 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. -*/ - -/** - * @file dynconfig.h - * - * @brief Exported global configurations. - **/ - -extern const char *dyn_SBINDIR, *dyn_BINDIR; -extern const char *dyn_CONFIGFILE; -extern const char *dyn_NCALRPCDIR; -extern const char *dyn_LOGFILEBASE; -extern const char *dyn_LMHOSTSFILE; -extern const char *dyn_LIBDIR; -extern const char *dyn_MODULESDIR; -extern const char *dyn_SHLIBEXT; -extern const char *dyn_LOCKDIR; -extern const char *dyn_PIDDIR; -extern const char *dyn_SMB_PASSWD_FILE; -extern const char *dyn_PRIVATE_DIR; -extern const char *dyn_SWATDIR; -extern const char *dyn_JSDIR; -extern const char *dyn_SETUPDIR; -extern const char *dyn_WINBINDD_SOCKET_DIR; diff --git a/source4/include/enums.h b/source4/include/enums.h deleted file mode 100644 index 6003dfc7a00..00000000000 --- a/source4/include/enums.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Copyright (C) Andrew Tridgell 2003 - - 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. -*/ - -/* - this header declares basic enumerated types -*/ - -/* protocol types. It assumes that higher protocols include lower protocols - as subsets */ -enum protocol_types {PROTOCOL_NONE,PROTOCOL_CORE,PROTOCOL_COREPLUS,PROTOCOL_LANMAN1,PROTOCOL_LANMAN2,PROTOCOL_NT1}; - -/* security levels */ -enum security_types {SEC_SHARE,SEC_USER}; - -/* passed to br lock code */ -enum brl_type {READ_LOCK, WRITE_LOCK, PENDING_READ_LOCK, PENDING_WRITE_LOCK}; - -enum smb_signing_state {SMB_SIGNING_OFF, SMB_SIGNING_SUPPORTED, - SMB_SIGNING_REQUIRED, SMB_SIGNING_AUTO}; - - diff --git a/source4/include/includes.h b/source4/include/includes.h index 444feab6fcf..8bede51721e 100644 --- a/source4/include/includes.h +++ b/source4/include/includes.h @@ -86,28 +86,31 @@ struct ipv4_addr { uint32_t addr; }; +/* protocol types. It assumes that higher protocols include lower protocols + as subsets. FIXME: Move to one of the smb-specific headers */ +enum protocol_types {PROTOCOL_NONE,PROTOCOL_CORE,PROTOCOL_COREPLUS,PROTOCOL_LANMAN1,PROTOCOL_LANMAN2,PROTOCOL_NT1}; + +/* passed to br lock code. FIXME: Move to one of the smb-specific headers */ +enum brl_type {READ_LOCK, WRITE_LOCK, PENDING_READ_LOCK, PENDING_WRITE_LOCK}; + #define _PRINTF_ATTRIBUTE(a1, a2) PRINTF_ATTRIBUTE(a1, a2) #include "lib/replace/replace.h" /* Lists, trees, caching, database... */ -#include "xfile.h" -#include "talloc/talloc.h" #include "nt_status.h" +#include "talloc/talloc.h" +#include "core.h" +#include "charset/charset.h" #include "structs.h" -#include "trans2.h" +#include "util/util.h" #include "libcli/util/nterr.h" -#include "charset/charset.h" -#include "core.h" -#include "debug.h" #include "libcli/util/doserr.h" -#include "enums.h" -#include "smb_macros.h" -#include "byteorder.h" #include "librpc/ndr/libndr.h" #include "librpc/gen_ndr/dcerpc.h" #include "librpc/ndr/ndr_orpc.h" #include "librpc/gen_ndr/orpc.h" #include "librpc/rpc/dcerpc.h" +#include "libcli/raw/trans2.h" #include "libcli/raw/interfaces.h" #include "auth/credentials/credentials.h" #include "libcli/nbt/libnbt.h" @@ -116,12 +119,11 @@ struct ipv4_addr { #define _PRINTF_ATTRIBUTE(a1, a2) /***** automatically generated prototypes *****/ -#include "basic.h" #include "include/proto.h" /* String routines */ -#include "safe_string.h" +#include "util/safe_string.h" #ifndef HAVE_PIPE #define SYNC_DNS 1 diff --git a/source4/include/ioctl.h b/source4/include/ioctl.h deleted file mode 100644 index cd658c121b5..00000000000 --- a/source4/include/ioctl.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - Unix SMB/CIFS implementation. - ioctl and fsctl definitions - - Copyright (C) Andrew Tridgell 2003 - - 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. -*/ - - -/* ioctl codes */ -#define IOCTL_QUERY_JOB_INFO 0x530060 - - -/* filesystem control codes */ -#define FSCTL_FILESYSTEM 0x90000 -#define FSCTL_SET_SPARSE (FSCTL_FILESYSTEM | (49<<2)) -#define FSCTL_REQUEST_BATCH_OPLOCK (FSCTL_FILESYSTEM | (2<<2)) - -#define FSCTL_NAMED_PIPE 0x110000 -#define FSCTL_NAMED_PIPE_READ_WRITE (FSCTL_NAMED_PIPE | 0xc017) diff --git a/source4/include/safe_string.h b/source4/include/safe_string.h deleted file mode 100644 index 43e094467cc..00000000000 --- a/source4/include/safe_string.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Safe string handling routines. - Copyright (C) Andrew Tridgell 1994-1998 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 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. -*/ - -#ifndef _SAFE_STRING_H -#define _SAFE_STRING_H - -#ifndef _SPLINT_ /* http://www.splint.org */ -/* Some macros to ensure people don't use buffer overflow vulnerable string - functions. */ - -#ifdef bcopy -#undef bcopy -#endif /* bcopy */ -#define bcopy(src,dest,size) __ERROR__XX__NEVER_USE_BCOPY___; - -#ifdef strcpy -#undef strcpy -#endif /* strcpy */ -#define strcpy(dest,src) __ERROR__XX__NEVER_USE_STRCPY___; - -#ifdef strcat -#undef strcat -#endif /* strcat */ -#define strcat(dest,src) __ERROR__XX__NEVER_USE_STRCAT___; - -#ifdef sprintf -#undef sprintf -#endif /* sprintf */ -#define sprintf __ERROR__XX__NEVER_USE_SPRINTF__; - -#endif /* !_SPLINT_ */ - -/* replace some string functions with multi-byte - versions */ -#define strlower(s) strlower_m(s) -#define strupper(s) strupper_m(s) - -#endif diff --git a/source4/include/smb_macros.h b/source4/include/smb_macros.h deleted file mode 100644 index 956b0709ca7..00000000000 --- a/source4/include/smb_macros.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Some convenient macros - Copyright (C) Andrew Tridgell 1992-1999 - Copyright (C) John H Terpstra 1996-1999 - Copyright (C) Luke Kenneth Casson Leighton 1996-1999 - Copyright (C) Paul Ashton 1998 - 1999 - - 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. -*/ - -#ifndef _SMB_MACROS_H -#define _SMB_MACROS_H - -/* zero a structure */ -#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x)) - -/* zero a structure given a pointer to the structure */ -#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0) - -/* zero a structure given a pointer to the structure - no zero check */ -#define ZERO_STRUCTPN(x) memset((char *)(x), 0, sizeof(*(x))) - -/* pointer difference macro */ -#define PTR_DIFF(p1,p2) ((ptrdiff_t)(((const char *)(p1)) - (const char *)(p2))) - -/* work out how many elements there are in a static array */ -#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) - -/* assert macros */ -#define SMB_ASSERT(b) do { if (!(b)) { \ - DEBUG(0,("PANIC: assert failed at %s(%d)\n", __FILE__, __LINE__)); \ - smb_panic("assert failed"); }} while (0) - -#ifndef MIN -#define MIN(a,b) ((a)<(b)?(a):(b)) -#endif - -#ifndef MAX -#define MAX(a,b) ((a)>(b)?(a):(b)) -#endif - -#ifndef ABS -#define ABS(a) ((a)>0?(a):(-(a))) -#endif - -#ifndef SAFE_FREE /* Oh no this is also defined in tdb.h */ -/** - * Free memory if the pointer and zero the pointer. - * - * @note You are explicitly allowed to pass NULL pointers -- they will - * always be ignored. - **/ -#define SAFE_FREE(x) do { if ((x) != NULL) {free(discard_const_p(void *, (x))); (x)=NULL;} } while(0) -#endif - -#define malloc_p(type) (type *)malloc(sizeof(type)) -#define malloc_array_p(type, count) (type *)realloc_array(NULL, sizeof(type), count) -#define realloc_p(p, type, count) (type *)realloc_array(p, sizeof(type), count) - -#endif /* _SMB_MACROS_H */ diff --git a/source4/include/structs.h b/source4/include/structs.h index 60ec1eae672..7bfe3262341 100644 --- a/source4/include/structs.h +++ b/source4/include/structs.h @@ -133,8 +133,6 @@ struct wb_sid_object; struct cldap_socket; struct cldapd_server; -struct mutex_ops; - struct websrv_context; struct wbsrv_call; @@ -161,6 +159,4 @@ struct nbtd_interface; struct smbcli_session; struct smbcli_state; -struct substitute_context; - struct model_ops; diff --git a/source4/include/trans2.h b/source4/include/trans2.h deleted file mode 100644 index a3f6e28a2af..00000000000 --- a/source4/include/trans2.h +++ /dev/null @@ -1,435 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SMB transaction2 handling - Copyright (C) Jeremy Allison 1994-2002. - Copyright (C) Andrew Tridgell 1995-2003. - - 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. -*/ - -#ifndef _TRANS2_H_ -#define _TRANS2_H_ - -/* These are the TRANS2 sub commands */ -#define TRANSACT2_OPEN 0 -#define TRANSACT2_FINDFIRST 1 -#define TRANSACT2_FINDNEXT 2 -#define TRANSACT2_QFSINFO 3 -#define TRANSACT2_SETFSINFO 4 -#define TRANSACT2_QPATHINFO 5 -#define TRANSACT2_SETPATHINFO 6 -#define TRANSACT2_QFILEINFO 7 -#define TRANSACT2_SETFILEINFO 8 -#define TRANSACT2_FSCTL 9 -#define TRANSACT2_IOCTL 0xA -#define TRANSACT2_FINDNOTIFYFIRST 0xB -#define TRANSACT2_FINDNOTIFYNEXT 0xC -#define TRANSACT2_MKDIR 0xD -#define TRANSACT2_SESSION_SETUP 0xE -#define TRANSACT2_GET_DFS_REFERRAL 0x10 -#define TRANSACT2_REPORT_DFS_INCONSISTANCY 0x11 - - -/* trans2 Query FS info levels */ -/* -w2k3 TRANS2ALIASES: -Checking for QFSINFO aliases - Found level 1 (0x001) of size 18 (0x12) - Found level 2 (0x002) of size 12 (0x0c) - Found level 258 (0x102) of size 26 (0x1a) - Found level 259 (0x103) of size 24 (0x18) - Found level 260 (0x104) of size 8 (0x08) - Found level 261 (0x105) of size 20 (0x14) - Found level 1001 (0x3e9) of size 26 (0x1a) - Found level 1003 (0x3eb) of size 24 (0x18) - Found level 1004 (0x3ec) of size 8 (0x08) - Found level 1005 (0x3ed) of size 20 (0x14) - Found level 1006 (0x3ee) of size 48 (0x30) - Found level 1007 (0x3ef) of size 32 (0x20) - Found level 1008 (0x3f0) of size 64 (0x40) -Found 13 levels with success status - Level 261 (0x105) and level 1005 (0x3ed) are possible aliases - Level 260 (0x104) and level 1004 (0x3ec) are possible aliases - Level 259 (0x103) and level 1003 (0x3eb) are possible aliases - Level 258 (0x102) and level 1001 (0x3e9) are possible aliases -Found 4 aliased levels -*/ -#define SMB_QFS_ALLOCATION 1 -#define SMB_QFS_VOLUME 2 -#define SMB_QFS_VOLUME_INFO 0x102 -#define SMB_QFS_SIZE_INFO 0x103 -#define SMB_QFS_DEVICE_INFO 0x104 -#define SMB_QFS_ATTRIBUTE_INFO 0x105 -#define SMB_QFS_UNIX_INFO 0x200 -#define SMB_QFS_POSIX_INFO 0x201 -#define SMB_QFS_VOLUME_INFORMATION 1001 -#define SMB_QFS_SIZE_INFORMATION 1003 -#define SMB_QFS_DEVICE_INFORMATION 1004 -#define SMB_QFS_ATTRIBUTE_INFORMATION 1005 -#define SMB_QFS_QUOTA_INFORMATION 1006 -#define SMB_QFS_FULL_SIZE_INFORMATION 1007 -#define SMB_QFS_OBJECTID_INFORMATION 1008 - - -/* trans2 qfileinfo/qpathinfo */ -/* w2k3 TRANS2ALIASES: -Checking for QPATHINFO aliases -setting up complex file \qpathinfo_aliases.txt - Found level 1 (0x001) of size 22 (0x16) - Found level 2 (0x002) of size 26 (0x1a) - Found level 4 (0x004) of size 41 (0x29) - Found level 6 (0x006) of size 0 (0x00) - Found level 257 (0x101) of size 40 (0x28) - Found level 258 (0x102) of size 24 (0x18) - Found level 259 (0x103) of size 4 (0x04) - Found level 260 (0x104) of size 48 (0x30) - Found level 263 (0x107) of size 126 (0x7e) - Found level 264 (0x108) of size 28 (0x1c) - Found level 265 (0x109) of size 38 (0x26) - Found level 267 (0x10b) of size 16 (0x10) - Found level 1004 (0x3ec) of size 40 (0x28) - Found level 1005 (0x3ed) of size 24 (0x18) - Found level 1006 (0x3ee) of size 8 (0x08) - Found level 1007 (0x3ef) of size 4 (0x04) - Found level 1008 (0x3f0) of size 4 (0x04) - Found level 1009 (0x3f1) of size 48 (0x30) - Found level 1014 (0x3f6) of size 8 (0x08) - Found level 1016 (0x3f8) of size 4 (0x04) - Found level 1017 (0x3f9) of size 4 (0x04) - Found level 1018 (0x3fa) of size 126 (0x7e) - Found level 1021 (0x3fd) of size 28 (0x1c) - Found level 1022 (0x3fe) of size 38 (0x26) - Found level 1028 (0x404) of size 16 (0x10) - Found level 1034 (0x40a) of size 56 (0x38) - Found level 1035 (0x40b) of size 8 (0x08) -Found 27 levels with success status - Level 267 (0x10b) and level 1028 (0x404) are possible aliases - Level 265 (0x109) and level 1022 (0x3fe) are possible aliases - Level 264 (0x108) and level 1021 (0x3fd) are possible aliases - Level 263 (0x107) and level 1018 (0x3fa) are possible aliases - Level 260 (0x104) and level 1009 (0x3f1) are possible aliases - Level 259 (0x103) and level 1007 (0x3ef) are possible aliases - Level 258 (0x102) and level 1005 (0x3ed) are possible aliases - Level 257 (0x101) and level 1004 (0x3ec) are possible aliases -Found 8 aliased levels -*/ -#define SMB_QFILEINFO_STANDARD 1 -#define SMB_QFILEINFO_EA_SIZE 2 -#define SMB_QFILEINFO_EA_LIST 3 -#define SMB_QFILEINFO_ALL_EAS 4 -#define SMB_QFILEINFO_IS_NAME_VALID 6 /* only for QPATHINFO */ -#define SMB_QFILEINFO_BASIC_INFO 0x101 -#define SMB_QFILEINFO_STANDARD_INFO 0x102 -#define SMB_QFILEINFO_EA_INFO 0x103 -#define SMB_QFILEINFO_NAME_INFO 0x104 -#define SMB_QFILEINFO_ALL_INFO 0x107 -#define SMB_QFILEINFO_ALT_NAME_INFO 0x108 -#define SMB_QFILEINFO_STREAM_INFO 0x109 -#define SMB_QFILEINFO_COMPRESSION_INFO 0x10b -#define SMB_QFILEINFO_UNIX_BASIC 0x200 -#define SMB_QFILEINFO_UNIX_LINK 0x201 -#define SMB_QFILEINFO_BASIC_INFORMATION 1004 -#define SMB_QFILEINFO_STANDARD_INFORMATION 1005 -#define SMB_QFILEINFO_INTERNAL_INFORMATION 1006 -#define SMB_QFILEINFO_EA_INFORMATION 1007 -#define SMB_QFILEINFO_ACCESS_INFORMATION 1008 -#define SMB_QFILEINFO_NAME_INFORMATION 1009 -#define SMB_QFILEINFO_POSITION_INFORMATION 1014 -#define SMB_QFILEINFO_MODE_INFORMATION 1016 -#define SMB_QFILEINFO_ALIGNMENT_INFORMATION 1017 -#define SMB_QFILEINFO_ALL_INFORMATION 1018 -#define SMB_QFILEINFO_ALT_NAME_INFORMATION 1021 -#define SMB_QFILEINFO_STREAM_INFORMATION 1022 -#define SMB_QFILEINFO_COMPRESSION_INFORMATION 1028 -#define SMB_QFILEINFO_NETWORK_OPEN_INFORMATION 1034 -#define SMB_QFILEINFO_ATTRIBUTE_TAG_INFORMATION 1035 - - - -/* trans2 setfileinfo/setpathinfo levels */ -/* -w2k3 TRANS2ALIASES -Checking for SETFILEINFO aliases -setting up complex file \setfileinfo_aliases.txt - Found level 1 (0x001) of size 2 (0x02) - Found level 2 (0x002) of size 2 (0x02) - Found level 257 (0x101) of size 40 (0x28) - Found level 258 (0x102) of size 2 (0x02) - Found level 259 (0x103) of size 8 (0x08) - Found level 260 (0x104) of size 8 (0x08) - Found level 1004 (0x3ec) of size 40 (0x28) - Found level 1010 (0x3f2) of size 2 (0x02) - Found level 1013 (0x3f5) of size 2 (0x02) - Found level 1014 (0x3f6) of size 8 (0x08) - Found level 1016 (0x3f8) of size 4 (0x04) - Found level 1019 (0x3fb) of size 8 (0x08) - Found level 1020 (0x3fc) of size 8 (0x08) - Found level 1023 (0x3ff) of size 8 (0x08) - Found level 1025 (0x401) of size 16 (0x10) - Found level 1029 (0x405) of size 72 (0x48) - Found level 1032 (0x408) of size 56 (0x38) - Found level 1039 (0x40f) of size 8 (0x08) - Found level 1040 (0x410) of size 8 (0x08) -Found 19 valid levels - -Checking for SETPATHINFO aliases - Found level 1004 (0x3ec) of size 40 (0x28) - Found level 1010 (0x3f2) of size 2 (0x02) - Found level 1013 (0x3f5) of size 2 (0x02) - Found level 1014 (0x3f6) of size 8 (0x08) - Found level 1016 (0x3f8) of size 4 (0x04) - Found level 1019 (0x3fb) of size 8 (0x08) - Found level 1020 (0x3fc) of size 8 (0x08) - Found level 1023 (0x3ff) of size 8 (0x08) - Found level 1025 (0x401) of size 16 (0x10) - Found level 1029 (0x405) of size 72 (0x48) - Found level 1032 (0x408) of size 56 (0x38) - Found level 1039 (0x40f) of size 8 (0x08) - Found level 1040 (0x410) of size 8 (0x08) -Found 13 valid levels -*/ -#define SMB_SFILEINFO_STANDARD 1 -#define SMB_SFILEINFO_EA_SET 2 -#define SMB_SFILEINFO_BASIC_INFO 0x101 -#define SMB_SFILEINFO_DISPOSITION_INFO 0x102 -#define SMB_SFILEINFO_ALLOCATION_INFO 0x103 -#define SMB_SFILEINFO_END_OF_FILE_INFO 0x104 -#define SMB_SFILEINFO_UNIX_BASIC 0x200 -#define SMB_SFILEINFO_UNIX_LINK 0x201 -#define SMB_SPATHINFO_UNIX_HLINK 0x203 -#define SMB_SPATHINFO_POSIX_ACL 0x204 -#define SMB_SPATHINFO_XATTR 0x205 -#define SMB_SFILEINFO_ATTR_FLAGS 0x206 -#define SMB_SFILEINFO_BASIC_INFORMATION 1004 -#define SMB_SFILEINFO_RENAME_INFORMATION 1010 -#define SMB_SFILEINFO_DISPOSITION_INFORMATION 1013 -#define SMB_SFILEINFO_POSITION_INFORMATION 1014 -#define SMB_SFILEINFO_MODE_INFORMATION 1016 -#define SMB_SFILEINFO_ALLOCATION_INFORMATION 1019 -#define SMB_SFILEINFO_END_OF_FILE_INFORMATION 1020 - -/* filemon shows FilePipeInformation */ -#define SMB_SFILEINFO_1023 1023 - -/* filemon shows FilePipeRemoteInformation */ -#define SMB_SFILEINFO_1025 1025 - -/* filemon shows CopyOnWriteInformation */ -#define SMB_SFILEINFO_1029 1029 - -/* filemon shows OleClassIdInformation */ -#define SMB_SFILEINFO_1032 1032 - -/* seems to be the file size - perhaps valid data size? - filemon shows 'InheritContentIndexInfo' -*/ -#define SMB_SFILEINFO_1039 1039 - -/* OLE_INFORMATION? */ -#define SMB_SFILEINFO_1040 1040 - - -/* trans2 findfirst levels */ -/* -w2k3 TRANS2ALIASES: -Checking for FINDFIRST aliases - Found level 1 (0x001) of size 68 (0x44) - Found level 2 (0x002) of size 70 (0x46) - Found level 257 (0x101) of size 108 (0x6c) - Found level 258 (0x102) of size 116 (0x74) - Found level 259 (0x103) of size 60 (0x3c) - Found level 260 (0x104) of size 140 (0x8c) - Found level 261 (0x105) of size 124 (0x7c) - Found level 262 (0x106) of size 148 (0x94) -Found 8 levels with success status -Found 0 aliased levels -*/ -#define SMB_FIND_STANDARD 1 -#define SMB_FIND_EA_SIZE 2 -#define SMB_FIND_EA_LIST 3 -#define SMB_FIND_DIRECTORY_INFO 0x101 -#define SMB_FIND_FULL_DIRECTORY_INFO 0x102 -#define SMB_FIND_NAME_INFO 0x103 -#define SMB_FIND_BOTH_DIRECTORY_INFO 0x104 -#define SMB_FIND_ID_FULL_DIRECTORY_INFO 0x105 -#define SMB_FIND_ID_BOTH_DIRECTORY_INFO 0x106 -#define SMB_FIND_UNIX_INFO 0x202 - -/* flags on trans2 findfirst/findnext that control search */ -#define FLAG_TRANS2_FIND_CLOSE 0x1 -#define FLAG_TRANS2_FIND_CLOSE_IF_END 0x2 -#define FLAG_TRANS2_FIND_REQUIRE_RESUME 0x4 -#define FLAG_TRANS2_FIND_CONTINUE 0x8 -#define FLAG_TRANS2_FIND_BACKUP_INTENT 0x10 - -/* - * DeviceType and Characteristics returned in a - * SMB_QFS_DEVICE_INFO call. - */ -#define QFS_DEVICETYPE_CD_ROM 0x2 -#define QFS_DEVICETYPE_CD_ROM_FILE_SYSTEM 0x3 -#define QFS_DEVICETYPE_DISK 0x7 -#define QFS_DEVICETYPE_DISK_FILE_SYSTEM 0x8 -#define QFS_DEVICETYPE_FILE_SYSTEM 0x9 - -/* Characteristics. */ -#define QFS_TYPE_REMOVABLE_MEDIA 0x1 -#define QFS_TYPE_READ_ONLY_DEVICE 0x2 -#define QFS_TYPE_FLOPPY 0x4 -#define QFS_TYPE_WORM 0x8 -#define QFS_TYPE_REMOTE 0x10 -#define QFS_TYPE_MOUNTED 0x20 -#define QFS_TYPE_VIRTUAL 0x40 - - -/* - * Thursby MAC extensions.... - */ - -/* - * MAC CIFS Extensions have the range 0x300 - 0x2FF reserved. - * Supposedly Microsoft have agreed to this. - */ - -#define MIN_MAC_INFO_LEVEL 0x300 -#define MAX_MAC_INFO_LEVEL 0x3FF -#define SMB_QFS_MAC_FS_INFO 0x301 - - - -/* UNIX CIFS Extensions - created by HP */ -/* - * UNIX CIFS Extensions have the range 0x200 - 0x2FF reserved. - * Supposedly Microsoft have agreed to this. - */ - -#define MIN_UNIX_INFO_LEVEL 0x200 -#define MAX_UNIX_INFO_LEVEL 0x2FF - -#define INFO_LEVEL_IS_UNIX(level) (((level) >= MIN_UNIX_INFO_LEVEL) && ((level) <= MAX_UNIX_INFO_LEVEL)) - -#define SMB_QFILEINFO_UNIX_BASIC 0x200 /* UNIX File Info*/ -#define SMB_SFILEINFO_UNIX_BASIC 0x200 - -#define SMB_MODE_NO_CHANGE 0xFFFFFFFF /* file mode value which */ - /* means "don't change it" */ -#define SMB_UID_NO_CHANGE 0xFFFFFFFF -#define SMB_GID_NO_CHANGE 0xFFFFFFFF - -#define SMB_SIZE_NO_CHANGE_LO 0xFFFFFFFF -#define SMB_SIZE_NO_CHANGE_HI 0xFFFFFFFF - -#define SMB_TIME_NO_CHANGE_LO 0xFFFFFFFF -#define SMB_TIME_NO_CHANGE_HI 0xFFFFFFFF - -/* -Offset Size Name -0 LARGE_INTEGER EndOfFile File size -8 LARGE_INTEGER Blocks Number of bytes used on disk (st_blocks). -16 LARGE_INTEGER CreationTime Creation time -24 LARGE_INTEGER LastAccessTime Last access time -32 LARGE_INTEGER LastModificationTime Last modification time -40 LARGE_INTEGER Uid Numeric user id for the owner -48 LARGE_INTEGER Gid Numeric group id of owner -56 ULONG Type Enumeration specifying the pathname type: - 0 -- File - 1 -- Directory - 2 -- Symbolic link - 3 -- Character device - 4 -- Block device - 5 -- FIFO (named pipe) - 6 -- Unix domain socket - -60 LARGE_INTEGER devmajor Major device number if type is device -68 LARGE_INTEGER devminor Minor device number if type is device -76 LARGE_INTEGER uniqueid This is a server-assigned unique id for the file. The client - will typically map this onto an inode number. The scope of - uniqueness is the share. -84 LARGE_INTEGER permissions Standard UNIX file permissions - see below. -92 LARGE_INTEGER nlinks The number of directory entries that map to this entry - (number of hard links) - -100 - end. -*/ - -/* UNIX filetype mappings. */ - -#define UNIX_TYPE_FILE 0 -#define UNIX_TYPE_DIR 1 -#define UNIX_TYPE_SYMLINK 2 -#define UNIX_TYPE_CHARDEV 3 -#define UNIX_TYPE_BLKDEV 4 -#define UNIX_TYPE_FIFO 5 -#define UNIX_TYPE_SOCKET 6 -#define UNIX_TYPE_UNKNOWN 0xFFFFFFFF - -/* - * Oh this is fun. "Standard UNIX permissions" has no - * meaning in POSIX. We need to define the mapping onto - * and off the wire as this was not done in the original HP - * spec. JRA. - */ - -#define UNIX_X_OTH 0000001 -#define UNIX_W_OTH 0000002 -#define UNIX_R_OTH 0000004 -#define UNIX_X_GRP 0000010 -#define UNIX_W_GRP 0000020 -#define UNIX_R_GRP 0000040 -#define UNIX_X_USR 0000100 -#define UNIX_W_USR 0000200 -#define UNIX_R_USR 0000400 -#define UNIX_STICKY 0001000 -#define UNIX_SET_GID 0002000 -#define UNIX_SET_UID 0004000 - -/* Masks for the above */ -#define UNIX_OTH_MASK 0000007 -#define UNIX_GRP_MASK 0000070 -#define UNIX_USR_MASK 0000700 -#define UNIX_PERM_MASK 0000777 -#define UNIX_EXTRA_MASK 0007000 -#define UNIX_ALL_MASK 0007777 - -#define SMB_QFILEINFO_UNIX_LINK 0x201 -#define SMB_SFILEINFO_UNIX_LINK 0x201 -#define SMB_SFILEINFO_UNIX_HLINK 0x203 - -#define SMB_FIND_FILE_UNIX 0x202 - -/* - Info level for QVOLINFO - returns version of CIFS UNIX extensions, plus - 64-bits worth of capability fun :-). -*/ - -#define SMB_QUERY_CIFS_UNIX_INFO 0x200 - -/* Returns the following. - - UINT16 major version number - UINT16 minor version number - LARGE_INTEGER capability bitfield - -*/ - -#define CIFS_UNIX_MAJOR_VERSION 1 -#define CIFS_UNIX_MINOR_VERSION 0 - -#define CIFS_UNIX_FCNTL_LOCKS_CAP 0x1 -#define CIFS_UNIX_POSIX_ACLS_CAP 0x2 - -/* ... more as we think of them :-). */ - -#endif diff --git a/source4/lib/basic.mk b/source4/lib/basic.mk index d5bff95f012..51ca3378a24 100644 --- a/source4/lib/basic.mk +++ b/source4/lib/basic.mk @@ -16,6 +16,7 @@ include socket_wrapper/config.mk include appweb/config.mk include replace/config.mk include stream/config.mk +include util/config.mk ############################## # Start SUBSYSTEM LIBNETIF @@ -57,50 +58,13 @@ OBJ_FILES = \ ################################################ [SUBSYSTEM::GENCACHE] -PRIVATE_PROTO_HEADER = gencache.h +PRIVATE_PROTO_HEADER = gencache/gencache.h OBJ_FILES = \ - gencache.o \ - -############################## -# Start SUBSYSTEM LIBBASIC -[SUBSYSTEM::LIBBASIC] -PRIVATE_PROTO_HEADER = basic.h -OBJ_FILES = version.o \ - xfile.o \ - debug.o \ - fault.o \ - signal.o \ - system.o \ - time.o \ - genrand.o \ - dprintf.o \ - util_str.o \ - util_strlist.o \ - util_unistr.o \ - util_file.o \ - data_blob.o \ - util.o \ - util_sock.o \ - substitute.o \ - fsusage.o \ - ms_fnmatch.o \ - select.o \ - mutex.o \ - idtree.o \ - module.o -REQUIRED_SUBSYSTEMS = \ - CHARSET LIBREPLACE LIBNETIF LIBCRYPTO EXT_LIB_DL LIBTALLOC \ - SOCKET_WRAPPER CONFIG -# End SUBSYSTEM LIBBASIC -############################## + gencache/gencache.o \ [SUBSYSTEM::DB_WRAP] OBJ_FILES = db_wrap.o \ gendb.o REQUIRED_SUBSYSTEMS = LIBLDB LIBTDB -[SUBSYSTEM::PIDFILE] -OBJ_FILES = pidfile.o -[SUBSYSTEM::UNIX_PRIVS] -OBJ_FILES = unix_privs.o diff --git a/source4/lib/capability.c b/source4/lib/capability.c deleted file mode 100644 index 0cebd333032..00000000000 --- a/source4/lib/capability.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Copyright (C) Andrew Tridgell 1992-1998 - Copyright (C) Jeremy Allison 1998-2002 - - 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. -*/ - -/* - capabilities fns - will be needed when we enable kernel oplocks -*/ - -#include "includes.h" -#include "system/network.h" -#include "system/wait.h" -#include "system/filesys.h" - - -#if defined(HAVE_IRIX_SPECIFIC_CAPABILITIES) -/************************************************************************** - Try and abstract process capabilities (for systems that have them). -****************************************************************************/ -static BOOL set_process_capability( uint32_t cap_flag, BOOL enable ) -{ - if(cap_flag == KERNEL_OPLOCK_CAPABILITY) { - cap_t cap = cap_get_proc(); - - if (cap == NULL) { - DEBUG(0,("set_process_capability: cap_get_proc failed. Error was %s\n", - strerror(errno))); - return False; - } - - if(enable) - cap->cap_effective |= CAP_NETWORK_MGT; - else - cap->cap_effective &= ~CAP_NETWORK_MGT; - - if (cap_set_proc(cap) == -1) { - DEBUG(0,("set_process_capability: cap_set_proc failed. Error was %s\n", - strerror(errno))); - cap_free(cap); - return False; - } - - cap_free(cap); - - DEBUG(10,("set_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n")); - } - return True; -} - -/************************************************************************** - Try and abstract inherited process capabilities (for systems that have them). -****************************************************************************/ - -static BOOL set_inherited_process_capability( uint32_t cap_flag, BOOL enable ) -{ - if(cap_flag == KERNEL_OPLOCK_CAPABILITY) { - cap_t cap = cap_get_proc(); - - if (cap == NULL) { - DEBUG(0,("set_inherited_process_capability: cap_get_proc failed. Error was %s\n", - strerror(errno))); - return False; - } - - if(enable) - cap->cap_inheritable |= CAP_NETWORK_MGT; - else - cap->cap_inheritable &= ~CAP_NETWORK_MGT; - - if (cap_set_proc(cap) == -1) { - DEBUG(0,("set_inherited_process_capability: cap_set_proc failed. Error was %s\n", - strerror(errno))); - cap_free(cap); - return False; - } - - cap_free(cap); - - DEBUG(10,("set_inherited_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n")); - } - return True; -} -#endif - -/**************************************************************************** - Gain the oplock capability from the kernel if possible. -****************************************************************************/ - -void oplock_set_capability(BOOL this_process, BOOL inherit) -{ -#if HAVE_KERNEL_OPLOCKS_IRIX - set_process_capability(KERNEL_OPLOCK_CAPABILITY,this_process); - set_inherited_process_capability(KERNEL_OPLOCK_CAPABILITY,inherit); -#endif -} - diff --git a/source4/lib/data_blob.c b/source4/lib/data_blob.c deleted file mode 100644 index c6471fbf540..00000000000 --- a/source4/lib/data_blob.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Easy management of byte-length data - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Andrew Bartlett 2001 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 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. -*/ - -#include "includes.h" - -/******************************************************************* - construct a data blob, must be freed with data_blob_free() - you can pass NULL for p and get a blank data blob -*******************************************************************/ -DATA_BLOB data_blob_named(const void *p, size_t length, const char *name) -{ - DATA_BLOB ret; - - if (p == NULL && length == 0) { - ZERO_STRUCT(ret); - return ret; - } - - if (p) { - ret.data = talloc_memdup(NULL, p, length); - } else { - ret.data = talloc_size(NULL, length); - } - if (ret.data == NULL) { - ret.length = 0; - return ret; - } - talloc_set_name_const(ret.data, name); - ret.length = length; - return ret; -} - -/******************************************************************* - construct a data blob, using supplied TALLOC_CTX -*******************************************************************/ -DATA_BLOB data_blob_talloc_named(TALLOC_CTX *mem_ctx, const void *p, size_t length, const char *name) -{ - DATA_BLOB ret = data_blob_named(p, length, name); - - if (ret.data) { - talloc_steal(mem_ctx, ret.data); - } - return ret; -} - - -/******************************************************************* - reference a data blob, to the supplied TALLOC_CTX. - Returns a NULL DATA_BLOB on failure -*******************************************************************/ -DATA_BLOB data_blob_talloc_reference(TALLOC_CTX *mem_ctx, DATA_BLOB *blob) -{ - DATA_BLOB ret = *blob; - - ret.data = talloc_reference(mem_ctx, blob->data); - - if (!ret.data) { - return data_blob(NULL, 0); - } - return ret; -} - -/******************************************************************* - construct a zero data blob, using supplied TALLOC_CTX. - use this sparingly as it initialises data - better to initialise - yourself if you want specific data in the blob -*******************************************************************/ -DATA_BLOB data_blob_talloc_zero(TALLOC_CTX *mem_ctx, size_t length) -{ - DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, length); - data_blob_clear(&blob); - return blob; -} - -/******************************************************************* -free a data blob -*******************************************************************/ -void data_blob_free(DATA_BLOB *d) -{ - if (d) { - talloc_free(d->data); - d->data = NULL; - d->length = 0; - } -} - -/******************************************************************* -clear a DATA_BLOB's contents -*******************************************************************/ -void data_blob_clear(DATA_BLOB *d) -{ - if (d->data) { - memset(d->data, 0, d->length); - } -} - -/******************************************************************* -free a data blob and clear its contents -*******************************************************************/ -void data_blob_clear_free(DATA_BLOB *d) -{ - data_blob_clear(d); - data_blob_free(d); -} - - -/******************************************************************* -check if two data blobs are equal -*******************************************************************/ -BOOL data_blob_equal(const DATA_BLOB *d1, const DATA_BLOB *d2) -{ - if (d1->length != d2->length) { - return False; - } - if (d1->data == d2->data) { - return True; - } - if (d1->data == NULL || d2->data == NULL) { - return False; - } - if (memcmp(d1->data, d2->data, d1->length) == 0) { - return True; - } - return False; -} - -/******************************************************************* -print the data_blob as hex string -*******************************************************************/ -char *data_blob_hex_string(TALLOC_CTX *mem_ctx, DATA_BLOB *blob) -{ - int i; - char *hex_string; - - hex_string = talloc_array(mem_ctx, char, (blob->length*2)+1); - if (!hex_string) { - return NULL; - } - - for (i = 0; i < blob->length; i++) - slprintf(&hex_string[i*2], 3, "%02X", blob->data[i]); - - return hex_string; -} - -/* - useful for constructing data blobs in test suites, while - avoiding const warnings -*/ -DATA_BLOB data_blob_string_const(const char *str) -{ - DATA_BLOB blob; - blob.data = discard_const(str); - blob.length = strlen(str); - return blob; -} - -DATA_BLOB data_blob_const(const void *p, size_t length) -{ - DATA_BLOB blob; - blob.data = discard_const(p); - blob.length = length; - return blob; -} - - -/* - realloc a data_blob -*/ -NTSTATUS data_blob_realloc(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, size_t length) -{ - blob->data = talloc_realloc_size(mem_ctx, blob->data, length); - NT_STATUS_HAVE_NO_MEMORY(blob->data); - blob->length = length; - return NT_STATUS_OK; -} - -/* - append some data to a data blob -*/ -NTSTATUS data_blob_append(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, - const void *p, size_t length) -{ - blob->data = talloc_realloc_size(mem_ctx, blob->data, - blob->length + length); - NT_STATUS_HAVE_NO_MEMORY(blob->data); - memcpy(blob->data + blob->length, p, length); - blob->length += length; - return NT_STATUS_OK; -} - diff --git a/source4/lib/debug.c b/source4/lib/debug.c deleted file mode 100644 index 9df6e573b09..00000000000 --- a/source4/lib/debug.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba debug functions - Copyright (C) Andrew Tridgell 2003 - Copyright (C) James J Myers 2003 - - 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. -*/ - -#include "includes.h" -#include "system/filesys.h" -#include "system/time.h" -#include "dynconfig.h" - -/* this global variable determines what messages are printed */ -int DEBUGLEVEL; - - -/* the registered mutex handlers */ -static struct { - const char *name; - struct debug_ops ops; -} debug_handlers; - -/* state variables for the debug system */ -static struct { - int fd; - enum debug_logtype logtype; - const char *prog_name; -} state; - -/* - the backend for debug messages. Note that the DEBUG() macro has already - ensured that the log level has been met before this is called -*/ -void do_debug_header(int level, const char *location, const char *func) -{ - log_timestring(level, location, func); - log_task_id(); -} - -/* - the backend for debug messages. Note that the DEBUG() macro has already - ensured that the log level has been met before this is called -*/ -void do_debug(const char *format, ...) -{ - va_list ap; - char *s = NULL; - - if (state.fd == 0) { - reopen_logs(); - } - - if (state.fd <= 0) return; - - va_start(ap, format); - vasprintf(&s, format, ap); - va_end(ap); - - write(state.fd, s, strlen(s)); - free(s); -} - -/* - reopen the log file (usually called because the log file name might have changed) -*/ -void reopen_logs(void) -{ - const char *logfile = lp_logfile(); - char *fname = NULL; - int old_fd = state.fd; - - switch (state.logtype) { - case DEBUG_STDOUT: - state.fd = 1; - break; - - case DEBUG_STDERR: - state.fd = 2; - break; - - case DEBUG_FILE: - if ((*logfile) == '/') { - fname = strdup(logfile); - } else { - asprintf(&fname, "%s/%s.log", dyn_LOGFILEBASE, state.prog_name); - } - if (fname) { - int newfd = open(fname, O_CREAT|O_APPEND|O_WRONLY, 0600); - if (newfd == -1) { - DEBUG(1, ("Failed to open new logfile: %s\n", fname)); - } else { - state.fd = newfd; - } - free(fname); - } else { - DEBUG(1, ("Failed to find name for file-based logfile!\n")); - } - - break; - } - - if (old_fd > 2) { - close(old_fd); - } -} - -/* - control the name of the logfile and whether logging will be to stdout, stderr - or a file -*/ -void setup_logging(const char *prog_name, enum debug_logtype new_logtype) -{ - if (state.logtype < new_logtype) { - state.logtype = new_logtype; - } - if (prog_name) { - state.prog_name = prog_name; - } - reopen_logs(); -} - -/* - return a string constant containing n tabs - no more than 10 tabs are returned -*/ -const char *do_debug_tab(uint_t n) -{ - const char *tabs[] = {"", "\t", "\t\t", "\t\t\t", "\t\t\t\t", "\t\t\t\t\t", - "\t\t\t\t\t\t", "\t\t\t\t\t\t\t", "\t\t\t\t\t\t\t\t", - "\t\t\t\t\t\t\t\t\t", "\t\t\t\t\t\t\t\t\t\t"}; - return tabs[MIN(n, 10)]; -} - - -/* - log/print suspicious usage - print comments and backtrace -*/ -void log_suspicious_usage(const char *from, const char *info) -{ - if (debug_handlers.ops.log_suspicious_usage) { - debug_handlers.ops.log_suspicious_usage(from, info); - } -} -void print_suspicious_usage(const char* from, const char* info) -{ - if (debug_handlers.ops.print_suspicious_usage) { - debug_handlers.ops.print_suspicious_usage(from, info); - } -} - -void log_timestring(int level, const char *location, const char *func) -{ - char *t = NULL; - char *s = NULL; - - if (state.logtype != DEBUG_FILE) return; - - t = timestring(NULL, time(NULL)); - if (!t) return; - - asprintf(&s, "[%s, %d %s:%s()]\n", t, level, location, func); - talloc_free(t); - if (!s) return; - - write(state.fd, s, strlen(s)); - free(s); -} - -uint32_t get_task_id(void) -{ - if (debug_handlers.ops.get_task_id) { - return debug_handlers.ops.get_task_id(); - } - return getpid(); -} - -void log_task_id(void) -{ - if (debug_handlers.ops.log_task_id) { - debug_handlers.ops.log_task_id(state.fd); - } -} - -/* - register a set of debug handlers. -*/ -void register_debug_handlers(const char *name, struct debug_ops *ops) -{ - debug_handlers.name = name; - debug_handlers.ops = *ops; -} diff --git a/source4/lib/debug.h b/source4/lib/debug.h deleted file mode 100644 index 8ff937e7b93..00000000000 --- a/source4/lib/debug.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba debug defines - Copyright (C) Andrew Tridgell 2003 - - 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. -*/ - -/* If we have these macros, we can add additional info to the header. */ - -#ifdef HAVE_FUNCTION_MACRO -#define FUNCTION_MACRO (__FUNCTION__) -#else -#define FUNCTION_MACRO ("") -#endif - -/* the debug operations structure - contains function pointers to - various debug implementations of each operation */ -struct debug_ops { - /* function to log (using DEBUG) suspicious usage of data structure */ - void (*log_suspicious_usage)(const char* from, const char* info); - - /* function to log (using printf) suspicious usage of data structure. - * To be used in circumstances when using DEBUG would cause loop. */ - void (*print_suspicious_usage)(const char* from, const char* info); - - /* function to return process/thread id */ - uint32_t (*get_task_id)(void); - - /* function to log process/thread id */ - void (*log_task_id)(int fd); -}; - -void do_debug_header(int level, const char *location, const char *func); -void do_debug(const char *, ...) PRINTF_ATTRIBUTE(1,2); - -extern int DEBUGLEVEL; - -#define DEBUGLVL(level) ((level) <= DEBUGLEVEL) -#define _DEBUG(level, body, header) do { \ - if (DEBUGLVL(level)) { \ - if (header) { \ - do_debug_header(level, __location__, FUNCTION_MACRO); \ - } \ - do_debug body; \ - } \ -} while (0) -#define DEBUG(level, body) _DEBUG(level, body, True) -#define DEBUGADD(level, body) _DEBUG(level, body, False) -#define DEBUGC(class, level, body) DEBUG(level, body) -#define DEBUGADDC(class, level, body) DEBUGADD(level, body) -#define DEBUGTAB(n) do_debug_tab(n) - -enum debug_logtype {DEBUG_STDOUT = 0, DEBUG_FILE = 1, DEBUG_STDERR = 2}; diff --git a/source4/lib/dprintf.c b/source4/lib/dprintf.c deleted file mode 100644 index 64227148fd9..00000000000 --- a/source4/lib/dprintf.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - Unix SMB/CIFS implementation. - display print functions - Copyright (C) Andrew Tridgell 2001 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 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. -*/ - - -/* - this module provides functions for printing internal strings in the "display charset" - This charset may be quite different from the chosen unix charset - - Eventually these functions will need to take care of column count constraints - - The d_ prefix on print functions in Samba refers to the display character set - conversion -*/ - -#include "includes.h" - -int d_vfprintf(FILE *f, const char *format, va_list ap) _PRINTF_ATTRIBUTE(2,0) -{ - char *p, *p2; - int ret, maxlen, clen; - va_list ap2; - - /* do any message translations */ - VA_COPY(ap2, ap); - - ret = vasprintf(&p, format, ap2); - - if (ret <= 0) return ret; - - /* now we have the string in unix format, convert it to the display - charset, but beware of it growing */ - maxlen = ret*2; -again: - p2 = malloc(maxlen); - if (!p2) { - SAFE_FREE(p); - return -1; - } - clen = convert_string(CH_UNIX, CH_DISPLAY, p, ret, p2, maxlen); - - if (clen >= maxlen) { - /* it didn't fit - try a larger buffer */ - maxlen *= 2; - SAFE_FREE(p2); - goto again; - } - - /* good, its converted OK */ - SAFE_FREE(p); - ret = fwrite(p2, 1, clen, f); - SAFE_FREE(p2); - - return ret; -} - - -int d_fprintf(FILE *f, const char *format, ...) _PRINTF_ATTRIBUTE(2,3) -{ - int ret; - va_list ap; - - va_start(ap, format); - ret = d_vfprintf(f, format, ap); - va_end(ap); - - return ret; -} - -static FILE *outfile; - -int d_printf(const char *format, ...) _PRINTF_ATTRIBUTE(1,2) -{ - int ret; - va_list ap; - - if (!outfile) outfile = stdout; - - va_start(ap, format); - ret = d_vfprintf(outfile, format, ap); - va_end(ap); - - return ret; -} - -/* interactive programs need a way of tell d_*() to write to stderr instead - of stdout */ -void display_set_stderr(void) -{ - outfile = stderr; -} diff --git a/source4/lib/fault.c b/source4/lib/fault.c deleted file mode 100644 index 3670575dcc7..00000000000 --- a/source4/lib/fault.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Critical Fault handling - Copyright (C) Andrew Tridgell 1992-1998 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 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. -*/ - -#include "includes.h" -#include "version.h" -#include "system/wait.h" -#include "system/filesys.h" - -/* the registered fault handler */ -static struct { - const char *name; - void (*fault_handler)(int sig); -} fault_handlers; - -static const char *progname; - -#ifdef HAVE_BACKTRACE -#include -#define BACKTRACE_STACK_SIZE 64 -#elif HAVE_LIBEXC_H -#include -#endif - -void call_backtrace(void) -{ -#ifdef HAVE_BACKTRACE -#define BACKTRACE_STACK_SIZE 64 - void *backtrace_stack[BACKTRACE_STACK_SIZE]; - size_t backtrace_size; - char **backtrace_strings; - - /* get the backtrace (stack frames) */ - backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE); - backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size); - - DEBUG(0, ("BACKTRACE: %lu stack frames:\n", - (unsigned long)backtrace_size)); - - if (backtrace_strings) { - int i; - - for (i = 0; i < backtrace_size; i++) - DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i])); - - /* 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); - - for (i = 0; i < BACKTRACE_STACK_SIZE; i++) { - names[i] = namebuf + (i * NAMESIZE); - } - - levels = trace_back_stack(0, addrs, names, - BACKTRACE_STACK_SIZE, NAMESIZE); - - 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 -} - -/******************************************************************* - Something really nasty happened - panic ! -********************************************************************/ -void smb_panic(const char *why) -{ - const char *cmd = lp_panic_action(); - int result; - - if (cmd && *cmd) { - char pidstr[20]; - char cmdstring[200]; - safe_strcpy(cmdstring, cmd, sizeof(cmdstring)); - snprintf(pidstr, sizeof(pidstr), "%u", getpid()); - all_string_sub(cmdstring, "%PID%", pidstr, sizeof(cmdstring)); - if (progname) { - all_string_sub(cmdstring, "%PROG%", progname, sizeof(cmdstring)); - } - DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmdstring)); - result = system(cmdstring); - - if (result == -1) - DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n", - strerror(errno))); - else - DEBUG(0, ("smb_panic(): action returned status %d\n", - WEXITSTATUS(result))); - } - DEBUG(0,("PANIC: %s\n", why)); - - call_backtrace(); - -#ifdef SIGABRT - CatchSignal(SIGABRT,SIGNAL_CAST SIG_DFL); -#endif - abort(); -} - -/******************************************************************* -report a fault -********************************************************************/ -static void fault_report(int sig) -{ - static int counter; - - if (counter) _exit(1); - - DEBUG(0,("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n")); - DEBUG(0,("INTERNAL ERROR: Signal %d in pid %d (%s)",sig,(int)getpid(),SAMBA_VERSION_STRING)); - DEBUG(0,("\nPlease read the file BUGS.txt in the distribution\n")); - DEBUG(0,("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n")); - - smb_panic("internal error"); - - exit(1); -} - -/**************************************************************************** -catch serious errors -****************************************************************************/ -static void sig_fault(int sig) -{ - if (fault_handlers.fault_handler) { - /* we have a fault handler, call it. It may not return. */ - fault_handlers.fault_handler(sig); - } - /* If it returns or doean't exist, use regular reporter */ - fault_report(sig); -} - -/******************************************************************* -setup our fault handlers -********************************************************************/ -void fault_setup(const char *pname) -{ - if (progname == NULL) { - progname = pname; - } -#ifdef SIGSEGV - CatchSignal(SIGSEGV,SIGNAL_CAST sig_fault); -#endif -#ifdef SIGBUS - CatchSignal(SIGBUS,SIGNAL_CAST sig_fault); -#endif -#ifdef SIGABRT - CatchSignal(SIGABRT,SIGNAL_CAST sig_fault); -#endif -#ifdef SIGFPE - CatchSignal(SIGFPE,SIGNAL_CAST sig_fault); -#endif -} - -/* - register a fault handler. - Should only be called once in the execution of smbd. -*/ -BOOL register_fault_handler(const char *name, void (*fault_handler)(int sig)) -{ - if (fault_handlers.name != NULL) { - /* it's already registered! */ - DEBUG(2,("fault handler '%s' already registered - failed '%s'\n", - fault_handlers.name, name)); - return False; - } - - fault_handlers.name = name; - fault_handlers.fault_handler = fault_handler; - - DEBUG(2,("fault handler '%s' registered\n", name)); - return True; -} diff --git a/source4/lib/fsusage.c b/source4/lib/fsusage.c deleted file mode 100644 index f8176725447..00000000000 --- a/source4/lib/fsusage.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - Unix SMB/CIFS implementation. - functions to calculate the free disk space - Copyright (C) Andrew Tridgell 1998-2000 - - 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. -*/ - -#include "includes.h" -#include "system/filesys.h" - - -/* Return the number of TOSIZE-byte blocks used by - BLOCKS FROMSIZE-byte blocks, rounding away from zero. -*/ -static uint64_t adjust_blocks(uint64_t blocks, uint64_t fromsize, uint64_t tosize) -{ - if (fromsize == tosize) /* e.g., from 512 to 512 */ - return blocks; - else if (fromsize > tosize) /* e.g., from 2048 to 512 */ - return blocks * (fromsize / tosize); - else /* e.g., from 256 to 512 */ - return (blocks + 1) / (tosize / fromsize); -} - -/* this does all of the system specific guff to get the free disk space. - It is derived from code in the GNU fileutils package, but has been - considerably mangled for use here - - results are returned in *dfree and *dsize, in 512 byte units -*/ -int sys_fsusage(const char *path, uint64_t *dfree, uint64_t *dsize) -{ -#ifdef STAT_STATFS3_OSF1 -#define CONVERT_BLOCKS(B) adjust_blocks ((uint64_t)(B), (uint64_t)fsd.f_fsize, (uint64_t)512) - struct statfs fsd; - - if (statfs (path, &fsd, sizeof (struct statfs)) != 0) - return -1; -#endif /* STAT_STATFS3_OSF1 */ - -#ifdef STAT_STATFS2_FS_DATA /* Ultrix */ -#define CONVERT_BLOCKS(B) adjust_blocks ((uint64_t)(B), (uint64_t)1024, (uint64_t)512) - struct fs_data fsd; - - if (statfs (path, &fsd) != 1) - return -1; - - (*dsize) = CONVERT_BLOCKS (fsd.fd_req.btot); - (*dfree) = CONVERT_BLOCKS (fsd.fd_req.bfreen); -#endif /* STAT_STATFS2_FS_DATA */ - -#ifdef STAT_STATFS2_BSIZE /* 4.3BSD, SunOS 4, HP-UX, AIX */ -#define CONVERT_BLOCKS(B) adjust_blocks ((uint64_t)(B), (uint64_t)fsd.f_bsize, (uint64_t)512) - struct statfs fsd; - - if (statfs (path, &fsd) < 0) - return -1; - -#ifdef STATFS_TRUNCATES_BLOCK_COUNTS - /* In SunOS 4.1.2, 4.1.3, and 4.1.3_U1, the block counts in the - struct statfs are truncated to 2GB. These conditions detect that - truncation, presumably without botching the 4.1.1 case, in which - the values are not truncated. The correct counts are stored in - undocumented spare fields. */ - if (fsd.f_blocks == 0x1fffff && fsd.f_spare[0] > 0) { - fsd.f_blocks = fsd.f_spare[0]; - fsd.f_bfree = fsd.f_spare[1]; - fsd.f_bavail = fsd.f_spare[2]; - } -#endif /* STATFS_TRUNCATES_BLOCK_COUNTS */ -#endif /* STAT_STATFS2_BSIZE */ - - -#ifdef STAT_STATFS2_FSIZE /* 4.4BSD */ -#define CONVERT_BLOCKS(B) adjust_blocks ((uint64_t)(B), (uint64_t)fsd.f_fsize, (uint64_t)512) - - struct statfs fsd; - - if (statfs (path, &fsd) < 0) - return -1; -#endif /* STAT_STATFS2_FSIZE */ - -#ifdef STAT_STATFS4 /* SVR3, Dynix, Irix, AIX */ -# if _AIX || defined(_CRAY) -# define CONVERT_BLOCKS(B) adjust_blocks ((uint64_t)(B), (uint64_t)fsd.f_bsize, (uint64_t)512) -# ifdef _CRAY -# define f_bavail f_bfree -# endif -# else -# define CONVERT_BLOCKS(B) ((uint64_t)B) -# ifndef _SEQUENT_ /* _SEQUENT_ is DYNIX/ptx */ -# ifndef DOLPHIN /* DOLPHIN 3.8.alfa/7.18 has f_bavail */ -# define f_bavail f_bfree -# endif -# endif -# endif - - struct statfs fsd; - - if (statfs (path, &fsd, sizeof fsd, 0) < 0) - return -1; - /* Empirically, the block counts on most SVR3 and SVR3-derived - systems seem to always be in terms of 512-byte blocks, - no matter what value f_bsize has. */ - -#endif /* STAT_STATFS4 */ - -#if defined(STAT_STATVFS) || defined(STAT_STATVFS64) /* SVR4 */ -# define CONVERT_BLOCKS(B) \ - adjust_blocks ((uint64_t)(B), fsd.f_frsize ? (uint64_t)fsd.f_frsize : (uint64_t)fsd.f_bsize, (uint64_t)512) - -#ifdef STAT_STATVFS64 - struct statvfs64 fsd; - if (statvfs64(path, &fsd) < 0) return -1; -#else - struct statvfs fsd; - if (statvfs(path, &fsd) < 0) return -1; -#endif - - /* f_frsize isn't guaranteed to be supported. */ - -#endif /* STAT_STATVFS */ - -#ifndef CONVERT_BLOCKS - /* we don't have any dfree code! */ - return -1; -#else -#if !defined(STAT_STATFS2_FS_DATA) - /* !Ultrix */ - (*dsize) = CONVERT_BLOCKS (fsd.f_blocks); - (*dfree) = CONVERT_BLOCKS (fsd.f_bavail); -#endif /* not STAT_STATFS2_FS_DATA */ -#endif - - return 0; -} diff --git a/source4/lib/gencache.c b/source4/lib/gencache.c deleted file mode 100644 index de8c47ada59..00000000000 --- a/source4/lib/gencache.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Generic, persistent and shared between processes cache mechanism for use - by various parts of the Samba code - - Copyright (C) Rafal Szczesniak 2002 - - 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. -*/ - -#include "includes.h" -#include "lib/tdb/include/tdbutil.h" -#include "system/time.h" -#include "system/filesys.h" -#include "db_wrap.h" - -#define TIMEOUT_LEN 12 -#define CACHE_DATA_FMT "%12u/%s" - -static struct tdb_wrap *cache; - -/** - * @file gencache.c - * @brief Generic, persistent and shared between processes cache mechanism - * for use by various parts of the Samba code - * - **/ - - -/** - * Cache initialisation function. Opens cache tdb file or creates - * it if does not exist. - * - * @return true on successful initialisation of the cache or - * false on failure - **/ - -BOOL gencache_init(void) -{ - char* cache_fname = NULL; - - /* skip file open if it's already opened */ - if (cache) return True; - - asprintf(&cache_fname, "%s/%s", lp_lockdir(), "gencache.tdb"); - if (cache_fname) - DEBUG(5, ("Opening cache file at %s\n", cache_fname)); - else { - DEBUG(0, ("Filename allocation failed.\n")); - return False; - } - - cache = tdb_wrap_open(NULL, cache_fname, 0, TDB_DEFAULT, - O_RDWR|O_CREAT, 0644); - - SAFE_FREE(cache_fname); - if (!cache) { - DEBUG(5, ("Attempt to open gencache.tdb has failed.\n")); - return False; - } - return True; -} - - -/** - * Cache shutdown function. Closes opened cache tdb file. - * - * @return true on successful closing the cache or - * false on failure during cache shutdown - **/ - -BOOL gencache_shutdown(void) -{ - if (!cache) return False; - DEBUG(5, ("Closing cache file\n")); - talloc_free(cache); - return True; -} - - -/** - * Set an entry in the cache file. If there's no such - * one, then add it. - * - * @param keystr string that represents a key of this entry - * @param value text representation value being cached - * @param timeout time when the value is expired - * - * @retval true when entry is successfuly stored - * @retval false on failure - **/ - -BOOL gencache_set(const char *keystr, const char *value, time_t timeout) -{ - int ret; - TDB_DATA keybuf, databuf; - char* valstr = NULL; - - /* fail completely if get null pointers passed */ - SMB_ASSERT(keystr && value); - - if (!gencache_init()) return False; - - asprintf(&valstr, CACHE_DATA_FMT, (int)timeout, value); - if (!valstr) - return False; - - keybuf.dptr = strdup(keystr); - keybuf.dsize = strlen(keystr)+1; - databuf.dptr = strdup(valstr); - databuf.dsize = strlen(valstr)+1; - DEBUG(10, ("Adding cache entry with key = %s; value = %s and timeout \ - = %s (%d seconds %s)\n", keybuf.dptr, value, ctime(&timeout), - (int)(timeout - time(NULL)), timeout > time(NULL) ? "ahead" : "in the past")); - - ret = tdb_store(cache->tdb, keybuf, databuf, 0); - SAFE_FREE(valstr); - SAFE_FREE(keybuf.dptr); - SAFE_FREE(databuf.dptr); - - return ret == 0; -} - - -/** - * Set existing entry to the cache file. - * - * @param keystr string that represents a key of this entry - * @param valstr text representation value being cached - * @param timeout time when the value is expired - * - * @retval true when entry is successfuly set - * @retval false on failure - **/ - -BOOL gencache_set_only(const char *keystr, const char *valstr, time_t timeout) -{ - int ret = -1; - TDB_DATA keybuf, databuf; - char *old_valstr, *datastr; - time_t old_timeout; - - /* fail completely if get null pointers passed */ - SMB_ASSERT(keystr && valstr); - - if (!gencache_init()) return False; - - /* - * Check whether entry exists in the cache - * Don't verify gencache_get exit code, since the entry may be expired - */ - gencache_get(keystr, &old_valstr, &old_timeout); - - if (!(old_valstr && old_timeout)) return False; - - DEBUG(10, ("Setting cache entry with key = %s; old value = %s and old timeout \ - = %s\n", keystr, old_valstr, ctime(&old_timeout))); - - asprintf(&datastr, CACHE_DATA_FMT, (int)timeout, valstr); - keybuf.dptr = strdup(keystr); - keybuf.dsize = strlen(keystr)+1; - databuf.dptr = strdup(datastr); - databuf.dsize = strlen(datastr)+1; - DEBUGADD(10, ("New value = %s, new timeout = %s (%d seconds %s)", valstr, - ctime(&timeout), (int)(timeout - time(NULL)), - timeout > time(NULL) ? "ahead" : "in the past")); - - - ret = tdb_store(cache->tdb, keybuf, databuf, TDB_REPLACE); - - SAFE_FREE(datastr); - SAFE_FREE(old_valstr); - SAFE_FREE(keybuf.dptr); - SAFE_FREE(databuf.dptr); - - return ret == 0; -} - - -/** - * Delete one entry from the cache file. - * - * @param keystr string that represents a key of this entry - * - * @retval true upon successful deletion - * @retval false in case of failure - **/ - -BOOL gencache_del(const char *keystr) -{ - int ret; - TDB_DATA keybuf; - - /* fail completely if get null pointers passed */ - SMB_ASSERT(keystr); - - if (!gencache_init()) return False; - - keybuf.dptr = strdup(keystr); - keybuf.dsize = strlen(keystr)+1; - DEBUG(10, ("Deleting cache entry (key = %s)\n", keystr)); - ret = tdb_delete(cache->tdb, keybuf); - - SAFE_FREE(keybuf.dptr); - return ret == 0; -} - - -/** - * Get existing entry from the cache file. - * - * @param keystr string that represents a key of this entry - * @param valstr buffer that is allocated and filled with the entry value - * buffer's disposing must be done outside - * @param timeout pointer to a time_t that is filled with entry's - * timeout - * - * @retval true when entry is successfuly fetched - * @retval False for failure - **/ - -BOOL gencache_get(const char *keystr, char **valstr, time_t *timeout) -{ - TDB_DATA keybuf, databuf; - - /* fail completely if get null pointers passed */ - SMB_ASSERT(keystr); - - if (!gencache_init()) - return False; - - keybuf.dptr = strdup(keystr); - keybuf.dsize = strlen(keystr)+1; - databuf = tdb_fetch(cache->tdb, keybuf); - SAFE_FREE(keybuf.dptr); - - if (databuf.dptr && databuf.dsize > TIMEOUT_LEN) { - char* entry_buf = strndup(databuf.dptr, databuf.dsize); - char *v; - time_t t; - unsigned i; - - v = malloc_array_p(char, databuf.dsize - TIMEOUT_LEN); - - SAFE_FREE(databuf.dptr); - sscanf(entry_buf, CACHE_DATA_FMT, (int*)&i, v); - SAFE_FREE(entry_buf); - t = i; - - DEBUG(10, ("Returning %s cache entry: key = %s, value = %s, " - "timeout = %s\n", t > time(NULL) ? "valid" : - "expired", keystr, v, ctime(&t))); - - if (valstr) - *valstr = v; - else - SAFE_FREE(v); - - if (timeout) - *timeout = t; - - return t > time(NULL); - - } else { - SAFE_FREE(databuf.dptr); - - if (valstr) - *valstr = NULL; - - if (timeout) - timeout = NULL; - - DEBUG(10, ("Cache entry with key = %s couldn't be found\n", - keystr)); - - return False; - } -} - - -/** - * Iterate through all entries which key matches to specified pattern - * - * @param fn pointer to the function that will be supplied with each single - * matching cache entry (key, value and timeout) as an arguments - * @param data void pointer to an arbitrary data that is passed directly to the fn - * function on each call - * @param keystr_pattern pattern the existing entries' keys are matched to - * - **/ - -void gencache_iterate(void (*fn)(const char* key, const char *value, time_t timeout, void* dptr), - void* data, const char* keystr_pattern) -{ - TDB_LIST_NODE *node, *first_node; - TDB_DATA databuf; - char *keystr = NULL, *valstr = NULL, *entry = NULL; - time_t timeout = 0; - unsigned i; - - /* fail completely if get null pointers passed */ - SMB_ASSERT(fn && keystr_pattern); - - if (!gencache_init()) return; - - DEBUG(5, ("Searching cache keys with pattern %s\n", keystr_pattern)); - node = tdb_search_keys(cache->tdb, keystr_pattern); - first_node = node; - - while (node) { - /* ensure null termination of the key string */ - keystr = strndup(node->node_key.dptr, node->node_key.dsize); - - /* - * We don't use gencache_get function, because we need to iterate through - * all of the entries. Validity verification is up to fn routine. - */ - databuf = tdb_fetch(cache->tdb, node->node_key); - if (!databuf.dptr || databuf.dsize <= TIMEOUT_LEN) { - SAFE_FREE(databuf.dptr); - SAFE_FREE(keystr); - node = node->next; - continue; - } - entry = strndup(databuf.dptr, databuf.dsize); - SAFE_FREE(databuf.dptr); - valstr = malloc_array_p(char, databuf.dsize - TIMEOUT_LEN); - sscanf(entry, CACHE_DATA_FMT, (int*)(&i), valstr); - timeout = i; - - DEBUG(10, ("Calling function with arguments (key = %s, value = %s, timeout = %s)\n", - keystr, valstr, ctime(&timeout))); - fn(keystr, valstr, timeout, data); - - SAFE_FREE(valstr); - SAFE_FREE(entry); - SAFE_FREE(keystr); - node = node->next; - } - - tdb_search_list_free(first_node); -} - -/******************************************************************** - lock a key -********************************************************************/ - -int gencache_lock_entry( const char *key ) -{ - return tdb_lock_bystring(cache->tdb, key); -} - -/******************************************************************** - unlock a key -********************************************************************/ - -void gencache_unlock_entry( const char *key ) -{ - tdb_unlock_bystring(cache->tdb, key); -} - - diff --git a/source4/lib/gencache/gencache.c b/source4/lib/gencache/gencache.c new file mode 100644 index 00000000000..de8c47ada59 --- /dev/null +++ b/source4/lib/gencache/gencache.c @@ -0,0 +1,375 @@ +/* + Unix SMB/CIFS implementation. + + Generic, persistent and shared between processes cache mechanism for use + by various parts of the Samba code + + Copyright (C) Rafal Szczesniak 2002 + + 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. +*/ + +#include "includes.h" +#include "lib/tdb/include/tdbutil.h" +#include "system/time.h" +#include "system/filesys.h" +#include "db_wrap.h" + +#define TIMEOUT_LEN 12 +#define CACHE_DATA_FMT "%12u/%s" + +static struct tdb_wrap *cache; + +/** + * @file gencache.c + * @brief Generic, persistent and shared between processes cache mechanism + * for use by various parts of the Samba code + * + **/ + + +/** + * Cache initialisation function. Opens cache tdb file or creates + * it if does not exist. + * + * @return true on successful initialisation of the cache or + * false on failure + **/ + +BOOL gencache_init(void) +{ + char* cache_fname = NULL; + + /* skip file open if it's already opened */ + if (cache) return True; + + asprintf(&cache_fname, "%s/%s", lp_lockdir(), "gencache.tdb"); + if (cache_fname) + DEBUG(5, ("Opening cache file at %s\n", cache_fname)); + else { + DEBUG(0, ("Filename allocation failed.\n")); + return False; + } + + cache = tdb_wrap_open(NULL, cache_fname, 0, TDB_DEFAULT, + O_RDWR|O_CREAT, 0644); + + SAFE_FREE(cache_fname); + if (!cache) { + DEBUG(5, ("Attempt to open gencache.tdb has failed.\n")); + return False; + } + return True; +} + + +/** + * Cache shutdown function. Closes opened cache tdb file. + * + * @return true on successful closing the cache or + * false on failure during cache shutdown + **/ + +BOOL gencache_shutdown(void) +{ + if (!cache) return False; + DEBUG(5, ("Closing cache file\n")); + talloc_free(cache); + return True; +} + + +/** + * Set an entry in the cache file. If there's no such + * one, then add it. + * + * @param keystr string that represents a key of this entry + * @param value text representation value being cached + * @param timeout time when the value is expired + * + * @retval true when entry is successfuly stored + * @retval false on failure + **/ + +BOOL gencache_set(const char *keystr, const char *value, time_t timeout) +{ + int ret; + TDB_DATA keybuf, databuf; + char* valstr = NULL; + + /* fail completely if get null pointers passed */ + SMB_ASSERT(keystr && value); + + if (!gencache_init()) return False; + + asprintf(&valstr, CACHE_DATA_FMT, (int)timeout, value); + if (!valstr) + return False; + + keybuf.dptr = strdup(keystr); + keybuf.dsize = strlen(keystr)+1; + databuf.dptr = strdup(valstr); + databuf.dsize = strlen(valstr)+1; + DEBUG(10, ("Adding cache entry with key = %s; value = %s and timeout \ + = %s (%d seconds %s)\n", keybuf.dptr, value, ctime(&timeout), + (int)(timeout - time(NULL)), timeout > time(NULL) ? "ahead" : "in the past")); + + ret = tdb_store(cache->tdb, keybuf, databuf, 0); + SAFE_FREE(valstr); + SAFE_FREE(keybuf.dptr); + SAFE_FREE(databuf.dptr); + + return ret == 0; +} + + +/** + * Set existing entry to the cache file. + * + * @param keystr string that represents a key of this entry + * @param valstr text representation value being cached + * @param timeout time when the value is expired + * + * @retval true when entry is successfuly set + * @retval false on failure + **/ + +BOOL gencache_set_only(const char *keystr, const char *valstr, time_t timeout) +{ + int ret = -1; + TDB_DATA keybuf, databuf; + char *old_valstr, *datastr; + time_t old_timeout; + + /* fail completely if get null pointers passed */ + SMB_ASSERT(keystr && valstr); + + if (!gencache_init()) return False; + + /* + * Check whether entry exists in the cache + * Don't verify gencache_get exit code, since the entry may be expired + */ + gencache_get(keystr, &old_valstr, &old_timeout); + + if (!(old_valstr && old_timeout)) return False; + + DEBUG(10, ("Setting cache entry with key = %s; old value = %s and old timeout \ + = %s\n", keystr, old_valstr, ctime(&old_timeout))); + + asprintf(&datastr, CACHE_DATA_FMT, (int)timeout, valstr); + keybuf.dptr = strdup(keystr); + keybuf.dsize = strlen(keystr)+1; + databuf.dptr = strdup(datastr); + databuf.dsize = strlen(datastr)+1; + DEBUGADD(10, ("New value = %s, new timeout = %s (%d seconds %s)", valstr, + ctime(&timeout), (int)(timeout - time(NULL)), + timeout > time(NULL) ? "ahead" : "in the past")); + + + ret = tdb_store(cache->tdb, keybuf, databuf, TDB_REPLACE); + + SAFE_FREE(datastr); + SAFE_FREE(old_valstr); + SAFE_FREE(keybuf.dptr); + SAFE_FREE(databuf.dptr); + + return ret == 0; +} + + +/** + * Delete one entry from the cache file. + * + * @param keystr string that represents a key of this entry + * + * @retval true upon successful deletion + * @retval false in case of failure + **/ + +BOOL gencache_del(const char *keystr) +{ + int ret; + TDB_DATA keybuf; + + /* fail completely if get null pointers passed */ + SMB_ASSERT(keystr); + + if (!gencache_init()) return False; + + keybuf.dptr = strdup(keystr); + keybuf.dsize = strlen(keystr)+1; + DEBUG(10, ("Deleting cache entry (key = %s)\n", keystr)); + ret = tdb_delete(cache->tdb, keybuf); + + SAFE_FREE(keybuf.dptr); + return ret == 0; +} + + +/** + * Get existing entry from the cache file. + * + * @param keystr string that represents a key of this entry + * @param valstr buffer that is allocated and filled with the entry value + * buffer's disposing must be done outside + * @param timeout pointer to a time_t that is filled with entry's + * timeout + * + * @retval true when entry is successfuly fetched + * @retval False for failure + **/ + +BOOL gencache_get(const char *keystr, char **valstr, time_t *timeout) +{ + TDB_DATA keybuf, databuf; + + /* fail completely if get null pointers passed */ + SMB_ASSERT(keystr); + + if (!gencache_init()) + return False; + + keybuf.dptr = strdup(keystr); + keybuf.dsize = strlen(keystr)+1; + databuf = tdb_fetch(cache->tdb, keybuf); + SAFE_FREE(keybuf.dptr); + + if (databuf.dptr && databuf.dsize > TIMEOUT_LEN) { + char* entry_buf = strndup(databuf.dptr, databuf.dsize); + char *v; + time_t t; + unsigned i; + + v = malloc_array_p(char, databuf.dsize - TIMEOUT_LEN); + + SAFE_FREE(databuf.dptr); + sscanf(entry_buf, CACHE_DATA_FMT, (int*)&i, v); + SAFE_FREE(entry_buf); + t = i; + + DEBUG(10, ("Returning %s cache entry: key = %s, value = %s, " + "timeout = %s\n", t > time(NULL) ? "valid" : + "expired", keystr, v, ctime(&t))); + + if (valstr) + *valstr = v; + else + SAFE_FREE(v); + + if (timeout) + *timeout = t; + + return t > time(NULL); + + } else { + SAFE_FREE(databuf.dptr); + + if (valstr) + *valstr = NULL; + + if (timeout) + timeout = NULL; + + DEBUG(10, ("Cache entry with key = %s couldn't be found\n", + keystr)); + + return False; + } +} + + +/** + * Iterate through all entries which key matches to specified pattern + * + * @param fn pointer to the function that will be supplied with each single + * matching cache entry (key, value and timeout) as an arguments + * @param data void pointer to an arbitrary data that is passed directly to the fn + * function on each call + * @param keystr_pattern pattern the existing entries' keys are matched to + * + **/ + +void gencache_iterate(void (*fn)(const char* key, const char *value, time_t timeout, void* dptr), + void* data, const char* keystr_pattern) +{ + TDB_LIST_NODE *node, *first_node; + TDB_DATA databuf; + char *keystr = NULL, *valstr = NULL, *entry = NULL; + time_t timeout = 0; + unsigned i; + + /* fail completely if get null pointers passed */ + SMB_ASSERT(fn && keystr_pattern); + + if (!gencache_init()) return; + + DEBUG(5, ("Searching cache keys with pattern %s\n", keystr_pattern)); + node = tdb_search_keys(cache->tdb, keystr_pattern); + first_node = node; + + while (node) { + /* ensure null termination of the key string */ + keystr = strndup(node->node_key.dptr, node->node_key.dsize); + + /* + * We don't use gencache_get function, because we need to iterate through + * all of the entries. Validity verification is up to fn routine. + */ + databuf = tdb_fetch(cache->tdb, node->node_key); + if (!databuf.dptr || databuf.dsize <= TIMEOUT_LEN) { + SAFE_FREE(databuf.dptr); + SAFE_FREE(keystr); + node = node->next; + continue; + } + entry = strndup(databuf.dptr, databuf.dsize); + SAFE_FREE(databuf.dptr); + valstr = malloc_array_p(char, databuf.dsize - TIMEOUT_LEN); + sscanf(entry, CACHE_DATA_FMT, (int*)(&i), valstr); + timeout = i; + + DEBUG(10, ("Calling function with arguments (key = %s, value = %s, timeout = %s)\n", + keystr, valstr, ctime(&timeout))); + fn(keystr, valstr, timeout, data); + + SAFE_FREE(valstr); + SAFE_FREE(entry); + SAFE_FREE(keystr); + node = node->next; + } + + tdb_search_list_free(first_node); +} + +/******************************************************************** + lock a key +********************************************************************/ + +int gencache_lock_entry( const char *key ) +{ + return tdb_lock_bystring(cache->tdb, key); +} + +/******************************************************************** + unlock a key +********************************************************************/ + +void gencache_unlock_entry( const char *key ) +{ + tdb_unlock_bystring(cache->tdb, key); +} + + diff --git a/source4/lib/genrand.c b/source4/lib/genrand.c deleted file mode 100644 index 1149314d0b4..00000000000 --- a/source4/lib/genrand.c +++ /dev/null @@ -1,314 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Functions to create reasonable random numbers for crypto use. - - Copyright (C) Jeremy Allison 2001 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 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. -*/ - -#include "includes.h" -#include "system/iconv.h" -#include "system/filesys.h" -#include "lib/crypto/crypto.h" - -static unsigned char hash[258]; -static uint32_t counter; - -static BOOL done_reseed = False; -static void (*reseed_callback)(int *newseed); - -/**************************************************************** - Copy any user given reseed data. -*****************************************************************/ - -void set_rand_reseed_callback(void (*fn)(int *)) -{ - reseed_callback = fn; - set_need_random_reseed(); -} - -void set_need_random_reseed(void) -{ - done_reseed = False; -} - -static void get_rand_reseed_data(int *reseed_data) -{ - if (reseed_callback) { - reseed_callback(reseed_data); - } else { - *reseed_data = 0; - } -} - -/**************************************************************** - Setup the seed. -*****************************************************************/ - -static void seed_random_stream(unsigned char *seedval, size_t seedlen) -{ - unsigned char j = 0; - size_t ind; - - for (ind = 0; ind < 256; ind++) - hash[ind] = (unsigned char)ind; - - for( ind = 0; ind < 256; ind++) { - unsigned char tc; - - j += (hash[ind] + seedval[ind%seedlen]); - - tc = hash[ind]; - hash[ind] = hash[j]; - hash[j] = tc; - } - - hash[256] = 0; - hash[257] = 0; -} - -/**************************************************************** - Get datasize bytes worth of random data. -*****************************************************************/ - -static void get_random_stream(unsigned char *data, size_t datasize) -{ - unsigned char index_i = hash[256]; - unsigned char index_j = hash[257]; - size_t ind; - - for( ind = 0; ind < datasize; ind++) { - unsigned char tc; - unsigned char t; - - index_i++; - index_j += hash[index_i]; - - tc = hash[index_i]; - hash[index_i] = hash[index_j]; - hash[index_j] = tc; - - t = hash[index_i] + hash[index_j]; - data[ind] = hash[t]; - } - - hash[256] = index_i; - hash[257] = index_j; -} - -/**************************************************************** - Get a 16 byte hash from the contents of a file. - - Note that the hash is initialised, because the extra entropy is not - worth the valgrind pain. -*****************************************************************/ - -static void do_filehash(const char *fname, unsigned char *the_hash) -{ - unsigned char buf[1011]; /* deliberate weird size */ - unsigned char tmp_md4[16]; - int fd, n; - - ZERO_STRUCT(tmp_md4); - - fd = open(fname,O_RDONLY,0); - if (fd == -1) - return; - - while ((n = read(fd, (char *)buf, sizeof(buf))) > 0) { - mdfour(tmp_md4, buf, n); - for (n=0;n<16;n++) - the_hash[n] ^= tmp_md4[n]; - } - close(fd); -} - -/************************************************************** - Try and get a good random number seed. Try a number of - different factors. Firstly, try /dev/urandom - use if exists. - - We use /dev/urandom as a read of /dev/random can block if - the entropy pool dries up. This leads clients to timeout - or be very slow on connect. - - If we can't use /dev/urandom then seed the stream random generator - above... -**************************************************************/ - -static int do_reseed(BOOL use_fd, int fd) -{ - unsigned char seed_inbuf[40]; - uint32_t v1, v2; struct timeval tval; pid_t mypid; - int reseed_data = 0; - - if (use_fd) { - if (fd != -1) - return fd; - - fd = open( "/dev/urandom", O_RDONLY,0); - if(fd >= 0) - return fd; - } - - /* Add in some secret file contents */ - - do_filehash("/etc/shadow", &seed_inbuf[0]); - - /* - * Add the counter, time of day, and pid. - */ - - GetTimeOfDay(&tval); - mypid = getpid(); - v1 = (counter++) + mypid + tval.tv_sec; - v2 = (counter++) * mypid + tval.tv_usec; - - SIVAL(seed_inbuf, 32, v1 ^ IVAL(seed_inbuf, 32)); - SIVAL(seed_inbuf, 36, v2 ^ IVAL(seed_inbuf, 36)); - - /* - * Add any user-given reseed data. - */ - - get_rand_reseed_data(&reseed_data); - if (reseed_data) { - size_t i; - for (i = 0; i < sizeof(seed_inbuf); i++) - seed_inbuf[i] ^= ((char *)(&reseed_data))[i % sizeof(reseed_data)]; - } - - seed_random_stream(seed_inbuf, sizeof(seed_inbuf)); - - return -1; -} - -/* - Interface to the (hopefully) good crypto random number generator. -*/ -void generate_random_buffer(uint8_t *out, int len) -{ - static int urand_fd = -1; - unsigned char md4_buf[64]; - unsigned char tmp_buf[16]; - unsigned char *p; - - if(!done_reseed) { - urand_fd = do_reseed(True, urand_fd); - done_reseed = True; - } - - if (urand_fd != -1 && len > 0) { - - if (read(urand_fd, out, len) == len) - return; /* len bytes of random data read from urandom. */ - - /* Read of urand error, drop back to non urand method. */ - close(urand_fd); - urand_fd = -1; - do_reseed(False, -1); - done_reseed = True; - } - - /* - * Generate random numbers in chunks of 64 bytes, - * then md4 them & copy to the output buffer. - * This way the raw state of the stream is never externally - * seen. - */ - - p = out; - while(len > 0) { - int copy_len = len > 16 ? 16 : len; - - get_random_stream(md4_buf, sizeof(md4_buf)); - mdfour(tmp_buf, md4_buf, sizeof(md4_buf)); - memcpy(p, tmp_buf, copy_len); - p += copy_len; - len -= copy_len; - } -} - -/* - generate a single random uint32_t -*/ -uint32_t generate_random(void) -{ - uint8_t v[4]; - generate_random_buffer(v, 4); - return IVAL(v, 0); -} - - -/* - very basic password quality checker -*/ -BOOL check_password_quality(const char *s) -{ - int has_digit=0, has_capital=0, has_lower=0; - while (*s) { - if (isdigit((unsigned char)*s)) { - has_digit++; - } else if (isupper((unsigned char)*s)) { - has_capital++; - } else if (islower((unsigned char)*s)) { - has_lower++; - } - s++; - } - - return has_digit && has_lower && has_capital; -} - -/******************************************************************* - Use the random number generator to generate a random string. -********************************************************************/ - -char *generate_random_str_list(TALLOC_CTX *mem_ctx, size_t len, const char *list) -{ - size_t i; - size_t list_len = strlen(list); - - char *retstr = talloc_array(mem_ctx, char, len + 1); - if (!retstr) return NULL; - - generate_random_buffer((uint8_t *)retstr, len); - for (i = 0; i < len; i++) { - retstr[i] = list[retstr[i] % list_len]; - } - retstr[i] = '\0'; - - return retstr; -} - -char *generate_random_str(TALLOC_CTX *mem_ctx, size_t len) -{ - char *retstr; - const char *c_list = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_-#.,"; - -again: - retstr = generate_random_str_list(mem_ctx, len, c_list); - if (!retstr) return NULL; - - /* we need to make sure the random string passes basic quality tests - or it might be rejected by windows as a password */ - if (len >= 7 && !check_password_quality(retstr)) { - talloc_free(retstr); - goto again; - } - - return retstr; -} diff --git a/source4/lib/idtree.c b/source4/lib/idtree.c deleted file mode 100644 index a67a80940a0..00000000000 --- a/source4/lib/idtree.c +++ /dev/null @@ -1,384 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - very efficient functions to manage mapping a id (such as a fnum) to - a pointer. This is used for fnum and search id allocation. - - Copyright (C) Andrew Tridgell 2004 - - This code is derived from lib/idr.c in the 2.6 Linux kernel, which was - written by Jim Houston jim.houston@ccur.com, and is - Copyright (C) 2002 by Concurrent Computer Corporation - - 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. -*/ - -/* - see the section marked "public interface" below for documentation -*/ - -#include "includes.h" - -#define IDR_BITS 5 -#define IDR_FULL 0xfffffffful -#define TOP_LEVEL_FULL (IDR_FULL >> 30) -#define IDR_SIZE (1 << IDR_BITS) -#define IDR_MASK ((1 << IDR_BITS)-1) -#define MAX_ID_SHIFT (sizeof(int)*8 - 1) -#define MAX_ID_BIT (1U << MAX_ID_SHIFT) -#define MAX_ID_MASK (MAX_ID_BIT - 1) -#define MAX_LEVEL (MAX_ID_SHIFT + IDR_BITS - 1) / IDR_BITS -#define IDR_FREE_MAX MAX_LEVEL + MAX_LEVEL - -#define set_bit(bit, v) (v) |= (1<<(bit)) -#define clear_bit(bit, v) (v) &= ~(1<<(bit)) -#define test_bit(bit, v) ((v) & (1<<(bit))) - -struct idr_layer { - uint32_t bitmap; - struct idr_layer *ary[IDR_SIZE]; - int count; -}; - -struct idr_context { - struct idr_layer *top; - struct idr_layer *id_free; - int layers; - int id_free_cnt; -}; - -static struct idr_layer *alloc_layer(struct idr_context *idp) -{ - struct idr_layer *p; - - if (!(p = idp->id_free)) - return NULL; - idp->id_free = p->ary[0]; - idp->id_free_cnt--; - p->ary[0] = NULL; - return p; -} - -static int find_next_bit(uint32_t bm, int maxid, int n) -{ - while (nary[0] = idp->id_free; - idp->id_free = p; - idp->id_free_cnt++; -} - -static int idr_pre_get(struct idr_context *idp) -{ - while (idp->id_free_cnt < IDR_FREE_MAX) { - struct idr_layer *new = talloc_zero(idp, struct idr_layer); - if(new == NULL) - return (0); - free_layer(idp, new); - } - return 1; -} - -static int sub_alloc(struct idr_context *idp, void *ptr, int *starting_id) -{ - int n, m, sh; - struct idr_layer *p, *new; - struct idr_layer *pa[MAX_LEVEL]; - int l, id; - uint32_t bm; - - id = *starting_id; - p = idp->top; - l = idp->layers; - pa[l--] = NULL; - while (1) { - /* - * We run around this while until we reach the leaf node... - */ - n = (id >> (IDR_BITS*l)) & IDR_MASK; - bm = ~p->bitmap; - m = find_next_bit(bm, IDR_SIZE, n); - if (m == IDR_SIZE) { - /* no space available go back to previous layer. */ - l++; - id = (id | ((1 << (IDR_BITS*l))-1)) + 1; - if (!(p = pa[l])) { - *starting_id = id; - return -2; - } - continue; - } - if (m != n) { - sh = IDR_BITS*l; - id = ((id >> sh) ^ n ^ m) << sh; - } - if ((id >= MAX_ID_BIT) || (id < 0)) - return -1; - if (l == 0) - break; - /* - * Create the layer below if it is missing. - */ - if (!p->ary[m]) { - if (!(new = alloc_layer(idp))) - return -1; - p->ary[m] = new; - p->count++; - } - pa[l--] = p; - p = p->ary[m]; - } - /* - * We have reached the leaf node, plant the - * users pointer and return the raw id. - */ - p->ary[m] = (struct idr_layer *)ptr; - set_bit(m, p->bitmap); - p->count++; - /* - * If this layer is full mark the bit in the layer above - * to show that this part of the radix tree is full. - * This may complete the layer above and require walking - * up the radix tree. - */ - n = id; - while (p->bitmap == IDR_FULL) { - if (!(p = pa[++l])) - break; - n = n >> IDR_BITS; - set_bit((n & IDR_MASK), p->bitmap); - } - return(id); -} - -static int idr_get_new_above_int(struct idr_context *idp, void *ptr, int starting_id) -{ - struct idr_layer *p, *new; - int layers, v, id; - - idr_pre_get(idp); - - id = starting_id; -build_up: - p = idp->top; - layers = idp->layers; - if (!p) { - if (!(p = alloc_layer(idp))) - return -1; - layers = 1; - } - /* - * Add a new layer to the top of the tree if the requested - * id is larger than the currently allocated space. - */ - while ((layers < MAX_LEVEL) && (id >= (1 << (layers*IDR_BITS)))) { - layers++; - if (!p->count) - continue; - if (!(new = alloc_layer(idp))) { - /* - * The allocation failed. If we built part of - * the structure tear it down. - */ - for (new = p; p && p != idp->top; new = p) { - p = p->ary[0]; - new->ary[0] = NULL; - new->bitmap = new->count = 0; - free_layer(idp, new); - } - return -1; - } - new->ary[0] = p; - new->count = 1; - if (p->bitmap == IDR_FULL) - set_bit(0, new->bitmap); - p = new; - } - idp->top = p; - idp->layers = layers; - v = sub_alloc(idp, ptr, &id); - if (v == -2) - goto build_up; - return(v); -} - -static int sub_remove(struct idr_context *idp, int shift, int id) -{ - struct idr_layer *p = idp->top; - struct idr_layer **pa[MAX_LEVEL]; - struct idr_layer ***paa = &pa[0]; - int n; - - *paa = NULL; - *++paa = &idp->top; - - while ((shift > 0) && p) { - n = (id >> shift) & IDR_MASK; - clear_bit(n, p->bitmap); - *++paa = &p->ary[n]; - p = p->ary[n]; - shift -= IDR_BITS; - } - n = id & IDR_MASK; - if (p != NULL && test_bit(n, p->bitmap)) { - clear_bit(n, p->bitmap); - p->ary[n] = NULL; - while(*paa && ! --((**paa)->count)){ - free_layer(idp, **paa); - **paa-- = NULL; - } - if ( ! *paa ) - idp->layers = 0; - return 0; - } - return -1; -} - -static void *_idr_find(struct idr_context *idp, int id) -{ - int n; - struct idr_layer *p; - - n = idp->layers * IDR_BITS; - p = idp->top; - /* - * This tests to see if bits outside the current tree are - * present. If so, tain't one of ours! - */ - if ((id & ~(~0 << MAX_ID_SHIFT)) >> (n + IDR_BITS)) - return NULL; - - /* Mask off upper bits we don't use for the search. */ - id &= MAX_ID_MASK; - - while (n > 0 && p) { - n -= IDR_BITS; - p = p->ary[(id >> n) & IDR_MASK]; - } - return((void *)p); -} - -static int _idr_remove(struct idr_context *idp, int id) -{ - struct idr_layer *p; - - /* Mask off upper bits we don't use for the search. */ - id &= MAX_ID_MASK; - - if (sub_remove(idp, (idp->layers - 1) * IDR_BITS, id) == -1) { - return -1; - } - - if ( idp->top && idp->top->count == 1 && - (idp->layers > 1) && - idp->top->ary[0]) { - /* We can drop a layer */ - p = idp->top->ary[0]; - idp->top->bitmap = idp->top->count = 0; - free_layer(idp, idp->top); - idp->top = p; - --idp->layers; - } - while (idp->id_free_cnt >= IDR_FREE_MAX) { - p = alloc_layer(idp); - talloc_free(p); - } - return 0; -} - -/************************************************************************ - this is the public interface -**************************************************************************/ - -/* - initialise a idr tree. The context return value must be passed to - all subsequent idr calls. To destroy the idr tree use talloc_free() - on this context - */ -struct idr_context *idr_init(TALLOC_CTX *mem_ctx) -{ - return talloc_zero(mem_ctx, struct idr_context); -} - -/* - allocate the next available id, and assign 'ptr' into its slot. - you can retrieve later this pointer using idr_find() -*/ -int idr_get_new(struct idr_context *idp, void *ptr, int limit) -{ - int ret = idr_get_new_above_int(idp, ptr, 0); - if (ret > limit) { - idr_remove(idp, ret); - return -1; - } - return ret; -} - -/* - allocate a new id, giving the first available value greater than or - equal to the given starting id -*/ -int idr_get_new_above(struct idr_context *idp, void *ptr, int starting_id, int limit) -{ - int ret = idr_get_new_above_int(idp, ptr, starting_id); - if (ret > limit) { - idr_remove(idp, ret); - return -1; - } - return ret; -} - -/* - allocate a new id randomly in the given range -*/ -int idr_get_new_random(struct idr_context *idp, void *ptr, int limit) -{ - int id; - - /* first try a random starting point in the whole range, and if that fails, - then start randomly in the bottom half of the range. This can only - fail if the range is over half full */ - id = idr_get_new_above(idp, ptr, 1+(generate_random() % limit), limit); - if (id == -1) { - id = idr_get_new_above(idp, ptr, 1+(generate_random()%(limit/2)), limit); - } - - return id; -} - -/* - find a pointer value previously set with idr_get_new given an id -*/ -void *idr_find(struct idr_context *idp, int id) -{ - return _idr_find(idp, id); -} - -/* - remove an id from the idr tree -*/ -int idr_remove(struct idr_context *idp, int id) -{ - int ret; - ret = _idr_remove((struct idr_context *)idp, id); - if (ret != 0) { - DEBUG(0,("WARNING: attempt to remove unset id %d in idtree\n", id)); - } - return ret; -} diff --git a/source4/lib/module.c b/source4/lib/module.c deleted file mode 100644 index 672d8df7cef..00000000000 --- a/source4/lib/module.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Copyright (C) Jelmer Vernooij 2005 - - 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. -*/ - -#include "includes.h" -#include "system/dir.h" - -static void *load_module(TALLOC_CTX *mem_ctx, const char *dir, const char *name) -{ - char *path; - void *handle; - void *init_fn; - - path = talloc_asprintf(mem_ctx, "%s/%s", dir, name); - - handle = dlopen(path, RTLD_NOW); - if (handle == NULL) { - DEBUG(0, ("Unable to open %s: %s\n", path, dlerror())); - talloc_free(path); - return NULL; - } - - init_fn = dlsym(handle, "init_module"); - - if (init_fn == NULL) { - DEBUG(0, ("Unable to find init_module() in %s: %s\n", path, dlerror())); - DEBUG(1, ("Loading module '%s' failed\n", path)); - dlclose(handle); - talloc_free(path); - return NULL; - } - - talloc_free(path); - - return init_fn; -} - -init_module_fn *load_modules(TALLOC_CTX *mem_ctx, const char *path) -{ - DIR *dir; - struct dirent *entry; - int success = 0; - init_module_fn *ret = talloc_array(mem_ctx, init_module_fn, 2); - - ret[0] = NULL; - - dir = opendir(path); - if (dir == NULL) { - talloc_free(ret); - return NULL; - } - - while((entry = readdir(dir))) { - if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) - continue; - - ret[success] = load_module(mem_ctx, path, entry->d_name); - if (ret[success]) { - ret = talloc_realloc(mem_ctx, ret, init_module_fn, success+2); - success++; - ret[success] = NULL; - } - } - - closedir(dir); - - return ret; -} - -BOOL run_init_functions(NTSTATUS (**fns) (void)) -{ - int i; - BOOL ret; - - if (fns == NULL) - return True; - - for (i = 0; fns[i]; i++) { ret &= NT_STATUS_IS_OK(fns[i]()); } - - return ret; -} diff --git a/source4/lib/ms_fnmatch.c b/source4/lib/ms_fnmatch.c deleted file mode 100644 index 699341bede5..00000000000 --- a/source4/lib/ms_fnmatch.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - Unix SMB/CIFS implementation. - filename matching routine - Copyright (C) Andrew Tridgell 1992-2004 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 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. -*/ - -/* - This module was originally based on fnmatch.c copyright by the Free - Software Foundation. It bears little (if any) resemblence to that - code now -*/ - - -#include "includes.h" - -static int null_match(const char *p) -{ - for (;*p;p++) { - if (*p != '*' && - *p != '<' && - *p != '"' && - *p != '>') return -1; - } - return 0; -} - -/* - the max_n structure is purely for efficiency, it doesn't contribute - to the matching algorithm except by ensuring that the algorithm does - not grow exponentially -*/ -struct max_n { - const char *predot; - const char *postdot; -}; - - -/* - p and n are the pattern and string being matched. The max_n array is - an optimisation only. The ldot pointer is NULL if the string does - not contain a '.', otherwise it points at the last dot in 'n'. -*/ -static int ms_fnmatch_core(const char *p, const char *n, - struct max_n *max_n, const char *ldot) -{ - codepoint_t c, c2; - int i; - size_t size, size_n; - - while ((c = next_codepoint(p, &size))) { - p += size; - - switch (c) { - case '*': - /* a '*' matches zero or more characters of any type */ - if (max_n->predot && max_n->predot <= n) { - return null_match(p); - } - for (i=0; n[i]; i += size_n) { - next_codepoint(n+i, &size_n); - if (ms_fnmatch_core(p, n+i, max_n+1, ldot) == 0) { - return 0; - } - } - if (!max_n->predot || max_n->predot > n) max_n->predot = n; - return null_match(p); - - case '<': - /* a '<' matches zero or more characters of - any type, but stops matching at the last - '.' in the string. */ - if (max_n->predot && max_n->predot <= n) { - return null_match(p); - } - if (max_n->postdot && max_n->postdot <= n && n <= ldot) { - return -1; - } - for (i=0; n[i]; i += size_n) { - next_codepoint(n+i, &size_n); - if (ms_fnmatch_core(p, n+i, max_n+1, ldot) == 0) return 0; - if (n+i == ldot) { - if (ms_fnmatch_core(p, n+i+size_n, max_n+1, ldot) == 0) return 0; - if (!max_n->postdot || max_n->postdot > n) max_n->postdot = n; - return -1; - } - } - if (!max_n->predot || max_n->predot > n) max_n->predot = n; - return null_match(p); - - case '?': - /* a '?' matches any single character */ - if (! *n) { - return -1; - } - next_codepoint(n, &size_n); - n += size_n; - break; - - case '>': - /* a '?' matches any single character, but - treats '.' specially */ - if (n[0] == '.') { - if (! n[1] && null_match(p) == 0) { - return 0; - } - break; - } - if (! *n) return null_match(p); - next_codepoint(n, &size_n); - n += size_n; - break; - - case '"': - /* a bit like a soft '.' */ - if (*n == 0 && null_match(p) == 0) { - return 0; - } - if (*n != '.') return -1; - next_codepoint(n, &size_n); - n += size_n; - break; - - default: - c2 = next_codepoint(n, &size_n); - if (c != c2 && codepoint_cmpi(c, c2) != 0) { - return -1; - } - n += size_n; - break; - } - } - - if (! *n) { - return 0; - } - - return -1; -} - -int ms_fnmatch(const char *pattern, const char *string, enum protocol_types protocol) -{ - int ret, count, i; - struct max_n *max_n = NULL; - - if (strcmp(string, "..") == 0) { - string = "."; - } - - if (strpbrk(pattern, "<>*?\"") == NULL) { - /* this is not just an optmisation - it is essential - for LANMAN1 correctness */ - return strcasecmp_m(pattern, string); - } - - if (protocol <= PROTOCOL_LANMAN2) { - char *p = talloc_strdup(NULL, pattern); - if (p == NULL) { - return -1; - } - /* - for older negotiated protocols it is possible to - translate the pattern to produce a "new style" - pattern that exactly matches w2k behaviour - */ - for (i=0;p[i];i++) { - if (p[i] == '?') { - p[i] = '>'; - } else if (p[i] == '.' && - (p[i+1] == '?' || - p[i+1] == '*' || - p[i+1] == 0)) { - p[i] = '"'; - } else if (p[i] == '*' && - p[i+1] == '.') { - p[i] = '<'; - } - } - ret = ms_fnmatch(p, string, PROTOCOL_NT1); - talloc_free(p); - return ret; - } - - for (count=i=0;pattern[i];i++) { - if (pattern[i] == '*' || pattern[i] == '<') count++; - } - - max_n = talloc_array(NULL, struct max_n, count); - if (!max_n) { - return -1; - } - memset(max_n, 0, sizeof(struct max_n) * count); - - ret = ms_fnmatch_core(pattern, string, max_n, strrchr(string, '.')); - - talloc_free(max_n); - - return ret; -} - - -/* a generic fnmatch function - uses for non-CIFS pattern matching */ -int gen_fnmatch(const char *pattern, const char *string) -{ - return ms_fnmatch(pattern, string, PROTOCOL_NT1); -} diff --git a/source4/lib/mutex.c b/source4/lib/mutex.c deleted file mode 100644 index 480ba92cc09..00000000000 --- a/source4/lib/mutex.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba mutex/lock functions - Copyright (C) Andrew Tridgell 2003 - Copyright (C) James J Myers 2003 - - 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. -*/ -#include "includes.h" -#include "mutex.h" - -/* the registered mutex handlers */ -static struct { - const char *name; - struct mutex_ops ops; -} mutex_handlers; - -/* read/write lock routines */ - - -/* - register a set of mutex/rwlock handlers. - Should only be called once in the execution of smbd. -*/ -BOOL register_mutex_handlers(const char *name, struct mutex_ops *ops) -{ - if (mutex_handlers.name != NULL) { - /* it's already registered! */ - DEBUG(2,("mutex handler '%s' already registered - failed '%s'\n", - mutex_handlers.name, name)); - return False; - } - - mutex_handlers.name = name; - mutex_handlers.ops = *ops; - - DEBUG(2,("mutex handler '%s' registered\n", name)); - return True; -} - diff --git a/source4/lib/mutex.h b/source4/lib/mutex.h deleted file mode 100644 index bb26c84f5dc..00000000000 --- a/source4/lib/mutex.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef _MUTEX_H_ -#define _MUTEX_H_ -/* - Unix SMB/CIFS implementation. - Samba mutex functions - Copyright (C) Andrew Tridgell 2003 - Copyright (C) James J Myers 2003 - - 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. -*/ - -/* To add a new read/write lock, add it to enum rwlock_id - */ -enum rwlock_id { RWLOCK_SMBD, /* global smbd lock */ - - RWLOCK_MAX /* this MUST be kept last */ -}; - -#define MUTEX_LOCK_BY_ID(mutex_index) smb_mutex_lock_by_id(mutex_index, #mutex_index) -#define MUTEX_UNLOCK_BY_ID(mutex_index) smb_mutex_unlock_by_id(mutex_index, #mutex_index) -#define MUTEX_INIT(mutex, name) smb_mutex_init(mutex, #name) -#define MUTEX_DESTROY(mutex, name) smb_mutex_destroy(mutex, #name) -#define MUTEX_LOCK(mutex, name) smb_mutex_lock(mutex, #name) -#define MUTEX_UNLOCK(mutex, name) smb_mutex_unlock(mutex, #name) - -#define RWLOCK_INIT(rwlock, name) smb_rwlock_init(rwlock, #name) -#define RWLOCK_DESTROY(rwlock, name) smb_rwlock_destroy(rwlock, #name) -#define RWLOCK_LOCK_WRITE(rwlock, name) smb_rwlock_lock_write(rwlock, #name) -#define RWLOCK_LOCK_READ(rwlock, name) smb_rwlock_lock_read(rwlock, #name) -#define RWLOCK_UNLOCK(rwlock, name) smb_rwlock_unlock(rwlock, #name) - - - -/* this null typedef ensures we get the types right and avoids the - pitfalls of void* */ -typedef struct smb_mutex { - void *mutex; -} smb_mutex_t; -typedef struct { - void *rwlock; -} smb_rwlock_t; - -/* the mutex model operations structure - contains function pointers to - the model-specific implementations of each operation */ -struct mutex_ops { - int (*mutex_init)(smb_mutex_t *mutex, const char *name); - int (*mutex_lock)(smb_mutex_t *mutex, const char *name); - int (*mutex_unlock)(smb_mutex_t *mutex, const char *name); - int (*mutex_destroy)(smb_mutex_t *mutex, const char *name); - int (*rwlock_init)(smb_rwlock_t *rwlock, const char *name); - int (*rwlock_lock_write)(smb_rwlock_t *rwlock, const char *name); - int (*rwlock_lock_read)(smb_rwlock_t *rwlock, const char *name); - int (*rwlock_unlock)(smb_rwlock_t *rwlock, const char *name); - int (*rwlock_destroy)(smb_rwlock_t *rwlock, const char *name); -}; - -#endif /* endif _MUTEX_H_ */ diff --git a/source4/lib/pidfile.c b/source4/lib/pidfile.c deleted file mode 100644 index 9a7c197f700..00000000000 --- a/source4/lib/pidfile.c +++ /dev/null @@ -1,116 +0,0 @@ -/* this code is broken - there is a race condition with the unlink (tridge) */ - -/* - Unix SMB/CIFS implementation. - pidfile handling - Copyright (C) Andrew Tridgell 1998 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 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. -*/ - -#include "includes.h" -#include "system/filesys.h" - -#ifndef O_NONBLOCK -#define O_NONBLOCK -#endif - -/* return the pid in a pidfile. return 0 if the process (or pidfile) - does not exist */ -pid_t pidfile_pid(const char *name) -{ - int fd; - char pidstr[20]; - uint_t ret; - char *pidFile; - - asprintf(&pidFile, "%s/%s.pid", lp_piddir(), name); - - fd = open(pidFile, O_NONBLOCK | O_RDONLY, 0644); - - if (fd == -1) { - SAFE_FREE(pidFile); - return 0; - } - - ZERO_STRUCT(pidstr); - - if (read(fd, pidstr, sizeof(pidstr)-1) <= 0) { - goto noproc; - } - - ret = atoi(pidstr); - - if (!process_exists((pid_t)ret)) { - goto noproc; - } - - if (fcntl_lock(fd,F_SETLK,0,1,F_RDLCK)) { - /* we could get the lock - it can't be a Samba process */ - goto noproc; - } - - close(fd); - SAFE_FREE(pidFile); - return (pid_t)ret; - - noproc: - close(fd); - unlink(pidFile); - SAFE_FREE(pidFile); - return 0; -} - -/* create a pid file in the pid directory. open it and leave it locked */ -void pidfile_create(const char *name) -{ - int fd; - char buf[20]; - char *pidFile; - pid_t pid; - - asprintf(&pidFile, "%s/%s.pid", lp_piddir(), name); - - pid = pidfile_pid(name); - if (pid != 0) { - DEBUG(0,("ERROR: %s is already running. File %s exists and process id %d is running.\n", - name, pidFile, (int)pid)); - exit(1); - } - - fd = open(pidFile, O_NONBLOCK | O_CREAT | O_WRONLY | O_EXCL, 0644); - if (fd == -1) { - DEBUG(0,("ERROR: can't open %s: Error was %s\n", pidFile, - strerror(errno))); - exit(1); - } - - if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False) { - DEBUG(0,("ERROR: %s : fcntl lock of file %s failed. Error was %s\n", - name, pidFile, strerror(errno))); - exit(1); - } - - memset(buf, 0, sizeof(buf)); - slprintf(buf, sizeof(buf) - 1, "%u\n", (uint_t) getpid()); - if (write(fd, buf, strlen(buf)) != (ssize_t)strlen(buf)) { - DEBUG(0,("ERROR: can't write to file %s: %s\n", - pidFile, strerror(errno))); - exit(1); - } - - /* Leave pid file open & locked for the duration... */ - SAFE_FREE(pidFile); -} diff --git a/source4/lib/select.c b/source4/lib/select.c deleted file mode 100644 index a1b2e04065b..00000000000 --- a/source4/lib/select.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 3.0 - Samba select/poll implementation - Copyright (C) Andrew Tridgell 1992-1998 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 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. -*/ - -#include "includes.h" -#include "system/filesys.h" - -/* This is here because it allows us to avoid a nasty race in signal handling. - We need to guarantee that when we get a signal we get out of a select immediately - but doing that involves a race condition. We can avoid the race by getting the - signal handler to write to a pipe that is in the select/poll list - - This means all Samba signal handlers should call sys_select_signal(). -*/ - -static pid_t initialised; -static int select_pipe[2]; -static VOLATILE unsigned pipe_written, pipe_read; - -/******************************************************************* - Call this from all Samba signal handlers if you want to avoid a - nasty signal race condition. -********************************************************************/ - -void sys_select_signal(void) -{ - char c = 1; - if (!initialised) return; - - if (pipe_written > pipe_read+256) return; - - if (write(select_pipe[1], &c, 1) == 1) pipe_written++; -} - -/******************************************************************* - Like select() but avoids the signal race using a pipe - it also guarantees that fds on return only ever contains bits set - for file descriptors that were readable. -********************************************************************/ - -int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval) -{ - int ret, saved_errno; - fd_set *readfds2, readfds_buf; - - if (initialised != getpid()) { - pipe(select_pipe); - - /* - * These next two lines seem to fix a bug with the Linux - * 2.0.x kernel (and probably other UNIXes as well) where - * the one byte read below can block even though the - * select returned that there is data in the pipe and - * the pipe_written variable was incremented. Thanks to - * HP for finding this one. JRA. - */ - - if(set_blocking(select_pipe[0],0)==-1) - smb_panic("select_pipe[0]: O_NONBLOCK failed.\n"); - if(set_blocking(select_pipe[1],0)==-1) - smb_panic("select_pipe[1]: O_NONBLOCK failed.\n"); - - initialised = getpid(); - } - - maxfd = MAX(select_pipe[0]+1, maxfd); - - /* If readfds is NULL we need to provide our own set. */ - if (readfds) { - readfds2 = readfds; - } else { - readfds2 = &readfds_buf; - FD_ZERO(readfds2); - } - FD_SET(select_pipe[0], readfds2); - - errno = 0; - ret = select(maxfd,readfds2,writefds,errorfds,tval); - - if (ret <= 0) { - FD_ZERO(readfds2); - if (writefds) - FD_ZERO(writefds); - if (errorfds) - FD_ZERO(errorfds); - } else if (FD_ISSET(select_pipe[0], readfds2)) { - char c; - saved_errno = errno; - if (read(select_pipe[0], &c, 1) == 1) { - pipe_read++; - /* Mark Weaver pointed out a critical - fix to ensure we don't lose signals. We must always - return -1 when the select pipe is set, otherwise if another - fd is also ready (so ret == 2) then we used to eat the - byte in the pipe and lose the signal. JRA. - */ - ret = -1; - errno = EINTR; - } else { - FD_CLR(select_pipe[0], readfds2); - ret--; - errno = saved_errno; - } - } - - return ret; -} - -/******************************************************************* - Similar to sys_select() but catch EINTR and continue. - This is what sys_select() used to do in Samba. -********************************************************************/ - -int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval) -{ - int ret; - fd_set *readfds2, readfds_buf, *writefds2, writefds_buf, *errorfds2, errorfds_buf; - struct timeval tval2, *ptval; - - readfds2 = (readfds ? &readfds_buf : NULL); - writefds2 = (writefds ? &writefds_buf : NULL); - errorfds2 = (errorfds ? &errorfds_buf : NULL); - ptval = (tval ? &tval2 : NULL); - - do { - if (readfds) - readfds_buf = *readfds; - if (writefds) - writefds_buf = *writefds; - if (errorfds) - errorfds_buf = *errorfds; - if (tval) - tval2 = *tval; - - /* We must use select and not sys_select here. If we use - sys_select we'd lose the fact a signal occurred when sys_select - read a byte from the pipe. Fix from Mark Weaver - - */ - - ret = select(maxfd, readfds2, writefds2, errorfds2, ptval); - } while (ret == -1 && errno == EINTR); - - if (readfds) - *readfds = readfds_buf; - if (writefds) - *writefds = writefds_buf; - if (errorfds) - *errorfds = errorfds_buf; - - return ret; -} diff --git a/source4/lib/signal.c b/source4/lib/signal.c deleted file mode 100644 index 6c0bb4007a1..00000000000 --- a/source4/lib/signal.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - Unix SMB/CIFS implementation. - signal handling functions - - Copyright (C) Andrew Tridgell 1998 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 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. -*/ - -#include "includes.h" -#include "system/wait.h" - -/**************************************************************************** - Catch child exits and reap the child zombie status. -****************************************************************************/ - -static void sig_cld(int signum) -{ - while (waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0) - ; - - /* - * Turns out it's *really* important not to - * restore the signal handler here if we have real POSIX - * signal handling. If we do, then we get the signal re-delivered - * immediately - hey presto - instant loop ! JRA. - */ - -#if !defined(HAVE_SIGACTION) - CatchSignal(SIGCLD, sig_cld); -#endif -} - -/**************************************************************************** -catch child exits - leave status; -****************************************************************************/ - -static void sig_cld_leave_status(int signum) -{ - /* - * Turns out it's *really* important not to - * restore the signal handler here if we have real POSIX - * signal handling. If we do, then we get the signal re-delivered - * immediately - hey presto - instant loop ! JRA. - */ - -#if !defined(HAVE_SIGACTION) - CatchSignal(SIGCLD, sig_cld_leave_status); -#endif -} - -/******************************************************************* - Block sigs. -********************************************************************/ - -void BlockSignals(BOOL block,int signum) -{ -#ifdef HAVE_SIGPROCMASK - sigset_t set; - sigemptyset(&set); - sigaddset(&set,signum); - sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL); -#elif defined(HAVE_SIGBLOCK) - if (block) { - sigblock(sigmask(signum)); - } else { - sigsetmask(siggetmask() & ~sigmask(signum)); - } -#else - /* yikes! This platform can't block signals? */ - static int done; - if (!done) { - DEBUG(0,("WARNING: No signal blocking available\n")); - done=1; - } -#endif -} - -/******************************************************************* - Catch a signal. This should implement the following semantics: - - 1) The handler remains installed after being called. - 2) The signal should be blocked during handler execution. -********************************************************************/ - -void (*CatchSignal(int signum,void (*handler)(int )))(int) -{ -#ifdef HAVE_SIGACTION - struct sigaction act; - struct sigaction oldact; - - ZERO_STRUCT(act); - - act.sa_handler = handler; -#ifdef SA_RESTART - /* - * We *want* SIGALRM to interrupt a system call. - */ - if(signum != SIGALRM) - act.sa_flags = SA_RESTART; -#endif - sigemptyset(&act.sa_mask); - sigaddset(&act.sa_mask,signum); - sigaction(signum,&act,&oldact); - return oldact.sa_handler; -#else /* !HAVE_SIGACTION */ - /* FIXME: need to handle sigvec and systems with broken signal() */ - return signal(signum, handler); -#endif -} - -/******************************************************************* - Ignore SIGCLD via whatever means is necessary for this OS. -********************************************************************/ - -void CatchChild(void) -{ - CatchSignal(SIGCLD, sig_cld); -} - -/******************************************************************* - Catch SIGCLD but leave the child around so it's status can be reaped. -********************************************************************/ - -void CatchChildLeaveStatus(void) -{ - CatchSignal(SIGCLD, sig_cld_leave_status); -} diff --git a/source4/lib/substitute.c b/source4/lib/substitute.c deleted file mode 100644 index 34a2ad9f82b..00000000000 --- a/source4/lib/substitute.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - Unix SMB/CIFS implementation. - string substitution functions - Copyright (C) Andrew Tridgell 1992-2000 - - 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. -*/ - - -#include "includes.h" -#include "smb_server/smb_server.h" - -/* oh bugger - I really didn't want to have a top-level context - anywhere, but until we change all lp_*() calls to take a context - argument this is needed */ -static struct substitute_context *sub; - -void sub_set_context(struct substitute_context *subptr) -{ - sub = subptr; -} - -/* - setup a string in the negotiate structure, using alpha_strcpy with SAFE_NETBIOS_CHARS -*/ -static void setup_string(char **dest, const char *str) -{ -#define SAFE_NETBIOS_CHARS ". -_" - char *s; - - s = strdup(str); - if (!s) { - return; - } - - alpha_strcpy(s, str, SAFE_NETBIOS_CHARS, strlen(s)+1); - - trim_string(s," "," "); - strlower(s); - - SAFE_FREE(*dest); - (*dest) = s; -} - -void sub_set_remote_proto(const char *str) -{ - if (!sub) return; - setup_string(&sub->remote_proto, str); -} - -void sub_set_remote_arch(const char *str) -{ - if (!sub) return; - setup_string(&sub->remote_arch, str); -} - -/* - setup the string used by %U substitution -*/ -void sub_set_user_name(const char *name) -{ - if (!sub) return; - setup_string(&sub->user_name, name); -} - -/**************************************************************************** -FOO -****************************************************************************/ -void standard_sub_basic(char *str,size_t len) -{ -} - -/**************************************************************************** - Do some standard substitutions in a string. - This function will return an allocated string that have to be freed. -****************************************************************************/ -char *talloc_sub_basic(TALLOC_CTX *mem_ctx, const char *smb_name, const char *str) -{ - return talloc_strdup(mem_ctx, str); -} - -char *alloc_sub_basic(const char *smb_name, const char *str) -{ - return strdup(str); -} - -/**************************************************************************** - Do some specific substitutions in a string. - This function will return an allocated string that have to be freed. -****************************************************************************/ - -char *talloc_sub_specified(TALLOC_CTX *mem_ctx, - const char *input_string, - const char *username, - const char *domain, - uid_t uid, - gid_t gid) -{ - return talloc_strdup(mem_ctx, input_string); -} - -char *alloc_sub_specified(const char *input_string, - const char *username, - const char *domain, - uid_t uid, - gid_t gid) -{ - return strdup(input_string); -} - -char *talloc_sub_advanced(TALLOC_CTX *mem_ctx, - int snum, - const char *user, - const char *connectpath, - gid_t gid, - const char *smb_name, - char *str) -{ - return talloc_strdup(mem_ctx, str); -} - -char *alloc_sub_advanced(int snum, const char *user, - const char *connectpath, gid_t gid, - const char *smb_name, char *str) -{ - return strdup(str); -} - -/**************************************************************************** - Do some standard substitutions in a string. -****************************************************************************/ - -void standard_sub_tcon(struct smbsrv_tcon *tcon, char *str, size_t len) -{ -} - -char *talloc_sub_tcon(TALLOC_CTX *mem_ctx, struct smbsrv_tcon *tcon, char *str) -{ - return talloc_strdup(mem_ctx, str); -} - -char *alloc_sub_tcon(struct smbsrv_tcon *tcon, char *str) -{ - return strdup(str); -} - -/**************************************************************************** - Like standard_sub but by snum. -****************************************************************************/ - -void standard_sub_snum(int snum, char *str, size_t len) -{ -} diff --git a/source4/lib/system.c b/source4/lib/system.c deleted file mode 100644 index 655b4a1054f..00000000000 --- a/source4/lib/system.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba system utilities - Copyright (C) Andrew Tridgell 1992-1998 - Copyright (C) Jeremy Allison 1998-2002 - - 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. -*/ - -#include "includes.h" -#include "system/network.h" -#include "system/filesys.h" - -/* - The idea is that this file will eventually have wrappers around all - important system calls in samba. The aims are: - - - to enable easier porting by putting OS dependent stuff in here - - - to allow for hooks into other "pseudo-filesystems" - - - to allow easier integration of things like the japanese extensions - - - to support the philosophy of Samba to expose the features of - the OS within the SMB model. In general whatever file/printer/variable - expansions/etc make sense to the OS should be acceptable to Samba. -*/ - -/************************************************************************** -A wrapper for gethostbyname() that tries avoids looking up hostnames -in the root domain, which can cause dial-on-demand links to come up for no -apparent reason. -****************************************************************************/ - -struct hostent *sys_gethostbyname(const char *name) -{ -#ifdef REDUCE_ROOT_DNS_LOOKUPS - char query[256], hostname[256]; - char *domain; - - /* Does this name have any dots in it? If so, make no change */ - - if (strchr_m(name, '.')) - return(gethostbyname(name)); - - /* Get my hostname, which should have domain name - attached. If not, just do the gethostname on the - original string. - */ - - gethostname(hostname, sizeof(hostname) - 1); - hostname[sizeof(hostname) - 1] = 0; - if ((domain = strchr_m(hostname, '.')) == NULL) - return(gethostbyname(name)); - - /* Attach domain name to query and do modified query. - If names too large, just do gethostname on the - original string. - */ - - if((strlen(name) + strlen(domain)) >= sizeof(query)) - return(gethostbyname(name)); - - slprintf(query, sizeof(query)-1, "%s%s", name, domain); - return(gethostbyname(query)); -#else /* REDUCE_ROOT_DNS_LOOKUPS */ - return(gethostbyname(name)); -#endif /* REDUCE_ROOT_DNS_LOOKUPS */ -} - -const char *sys_inet_ntoa(struct ipv4_addr in) -{ - struct in_addr in2; - in2.s_addr = in.addr; - return inet_ntoa(in2); -} - -struct ipv4_addr sys_inet_makeaddr(int net, int host) -{ - struct in_addr in; - struct ipv4_addr in2; - in = inet_makeaddr(net, host); - in2.addr = in.s_addr; - return in2; -} - diff --git a/source4/lib/time.c b/source4/lib/time.c deleted file mode 100644 index 7721a2c456c..00000000000 --- a/source4/lib/time.c +++ /dev/null @@ -1,596 +0,0 @@ -/* - Unix SMB/CIFS implementation. - time handling functions - - Copyright (C) Andrew Tridgell 1992-2004 - Copyright (C) Stefan (metze) Metzmacher 2002 - - 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. -*/ - -#include "includes.h" -#include "system/time.h" - -#ifndef TIME_T_MIN -/* we use 0 here, because (time_t)-1 means error */ -#define TIME_T_MIN 0 -#endif - -/* - * we use the INT32_MAX here as on 64 bit systems, - * gmtime() fails with INT64_MAX - */ - -#ifndef TIME_T_MAX -#define TIME_T_MAX MIN(INT32_MAX,_TYPE_MAXIMUM(time_t)) -#endif - -/******************************************************************* - External access to time_t_min and time_t_max. -********************************************************************/ -time_t get_time_t_max(void) -{ - return TIME_T_MAX; -} - -/******************************************************************* -a gettimeofday wrapper -********************************************************************/ -void GetTimeOfDay(struct timeval *tval) -{ -#ifdef HAVE_GETTIMEOFDAY_TZ - gettimeofday(tval,NULL); -#else - gettimeofday(tval); -#endif -} - - -#define TIME_FIXUP_CONSTANT 11644473600LL - -/**************************************************************************** -interpret an 8 byte "filetime" structure to a time_t -It's originally in "100ns units since jan 1st 1601" -****************************************************************************/ -time_t nt_time_to_unix(NTTIME nt) -{ - if (nt == 0) { - return 0; - } - if (nt == -1LL) { - return (time_t)-1; - } - nt += 1000*1000*10/2; - nt /= 1000*1000*10; - nt -= TIME_FIXUP_CONSTANT; - - if (TIME_T_MIN > nt || nt > TIME_T_MAX) { - return 0; - } - - return (time_t)nt; -} - - -/**************************************************************************** -put a 8 byte filetime from a time_t -This takes GMT as input -****************************************************************************/ -void unix_to_nt_time(NTTIME *nt, time_t t) -{ - uint64_t t2; - - if (t == (time_t)-1) { - *nt = (NTTIME)-1LL; - return; - } - if (t == 0) { - *nt = 0; - return; - } - - t2 = t; - t2 += TIME_FIXUP_CONSTANT; - t2 *= 1000*1000*10; - - *nt = t2; -} - - -/**************************************************************************** -check if it's a null unix time -****************************************************************************/ -BOOL null_time(time_t t) -{ - return t == 0 || - t == (time_t)0xFFFFFFFF || - t == (time_t)-1; -} - - -/**************************************************************************** -check if it's a null NTTIME -****************************************************************************/ -BOOL null_nttime(NTTIME t) -{ - return t == 0 || t == (NTTIME)-1; -} - -/******************************************************************* - create a 16 bit dos packed date -********************************************************************/ -static uint16_t make_dos_date1(struct tm *t) -{ - uint16_t ret=0; - ret = (((uint_t)(t->tm_mon+1)) >> 3) | ((t->tm_year-80) << 1); - ret = ((ret&0xFF)<<8) | (t->tm_mday | (((t->tm_mon+1) & 0x7) << 5)); - return ret; -} - -/******************************************************************* - create a 16 bit dos packed time -********************************************************************/ -static uint16_t make_dos_time1(struct tm *t) -{ - uint16_t ret=0; - ret = ((((uint_t)t->tm_min >> 3)&0x7) | (((uint_t)t->tm_hour) << 3)); - ret = ((ret&0xFF)<<8) | ((t->tm_sec/2) | ((t->tm_min & 0x7) << 5)); - return ret; -} - -/******************************************************************* - create a 32 bit dos packed date/time from some parameters - This takes a GMT time and returns a packed localtime structure -********************************************************************/ -static uint32_t make_dos_date(time_t unixdate, int zone_offset) -{ - struct tm *t; - uint32_t ret=0; - - if (unixdate == 0) { - return 0; - } - - unixdate -= zone_offset; - - t = gmtime(&unixdate); - if (!t) { - return 0xFFFFFFFF; - } - - ret = make_dos_date1(t); - ret = ((ret&0xFFFF)<<16) | make_dos_time1(t); - - return ret; -} - -/******************************************************************* -put a dos date into a buffer (time/date format) -This takes GMT time and puts local time in the buffer -********************************************************************/ -void push_dos_date(uint8_t *buf, int offset, time_t unixdate, int zone_offset) -{ - uint32_t x = make_dos_date(unixdate, zone_offset); - SIVAL(buf,offset,x); -} - -/******************************************************************* -put a dos date into a buffer (date/time format) -This takes GMT time and puts local time in the buffer -********************************************************************/ -void push_dos_date2(uint8_t *buf,int offset,time_t unixdate, int zone_offset) -{ - uint32_t x; - x = make_dos_date(unixdate, zone_offset); - x = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16); - SIVAL(buf,offset,x); -} - -/******************************************************************* -put a dos 32 bit "unix like" date into a buffer. This routine takes -GMT and converts it to LOCAL time before putting it (most SMBs assume -localtime for this sort of date) -********************************************************************/ -void push_dos_date3(uint8_t *buf,int offset,time_t unixdate, int zone_offset) -{ - if (!null_time(unixdate)) { - unixdate -= zone_offset; - } - SIVAL(buf,offset,unixdate); -} - -/******************************************************************* - interpret a 32 bit dos packed date/time to some parameters -********************************************************************/ -static void interpret_dos_date(uint32_t date,int *year,int *month,int *day,int *hour,int *minute,int *second) -{ - uint32_t p0,p1,p2,p3; - - p0=date&0xFF; p1=((date&0xFF00)>>8)&0xFF; - p2=((date&0xFF0000)>>16)&0xFF; p3=((date&0xFF000000)>>24)&0xFF; - - *second = 2*(p0 & 0x1F); - *minute = ((p0>>5)&0xFF) + ((p1&0x7)<<3); - *hour = (p1>>3)&0xFF; - *day = (p2&0x1F); - *month = ((p2>>5)&0xFF) + ((p3&0x1)<<3) - 1; - *year = ((p3>>1)&0xFF) + 80; -} - -/******************************************************************* - create a unix date (int GMT) from a dos date (which is actually in - localtime) -********************************************************************/ -time_t pull_dos_date(const uint8_t *date_ptr, int zone_offset) -{ - uint32_t dos_date=0; - struct tm t; - time_t ret; - - dos_date = IVAL(date_ptr,0); - - if (dos_date == 0) return (time_t)0; - - interpret_dos_date(dos_date,&t.tm_year,&t.tm_mon, - &t.tm_mday,&t.tm_hour,&t.tm_min,&t.tm_sec); - t.tm_isdst = -1; - - ret = timegm(&t); - - ret += zone_offset; - - return ret; -} - -/******************************************************************* -like make_unix_date() but the words are reversed -********************************************************************/ -time_t pull_dos_date2(const uint8_t *date_ptr, int zone_offset) -{ - uint32_t x,x2; - - x = IVAL(date_ptr,0); - x2 = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16); - SIVAL(&x,0,x2); - - return pull_dos_date((void *)&x, zone_offset); -} - -/******************************************************************* - create a unix GMT date from a dos date in 32 bit "unix like" format - these generally arrive as localtimes, with corresponding DST - ******************************************************************/ -time_t pull_dos_date3(const uint8_t *date_ptr, int zone_offset) -{ - time_t t = (time_t)IVAL(date_ptr,0); - if (!null_time(t)) { - t += zone_offset; - } - return t; -} - - -/*************************************************************************** -return a HTTP/1.0 time string - ***************************************************************************/ -char *http_timestring(TALLOC_CTX *mem_ctx, time_t t) -{ - char *buf; - char tempTime[60]; - struct tm *tm = localtime(&t); - - if (!tm) { - return talloc_asprintf(mem_ctx,"%ld seconds since the Epoch",(long)t); - } - -#ifndef HAVE_STRFTIME - buf = talloc_strdup(mem_ctx, asctime(tm)); - if (buf[strlen(buf)-1] == '\n') { - buf[strlen(buf)-1] = 0; - } -#else - strftime(tempTime, sizeof(tempTime)-1, "%a, %d %b %Y %H:%M:%S %Z", tm); - buf = talloc_strdup(mem_ctx, tempTime); -#endif /* !HAVE_STRFTIME */ - - return buf; -} - -/**************************************************************************** - Return the date and time as a string -****************************************************************************/ -char *timestring(TALLOC_CTX *mem_ctx, time_t t) -{ - char *TimeBuf; - char tempTime[80]; - struct tm *tm; - - tm = localtime(&t); - if (!tm) { - return talloc_asprintf(mem_ctx, - "%ld seconds since the Epoch", - (long)t); - } - -#ifdef HAVE_STRFTIME - /* some versions of gcc complain about using %c. This is a bug - in the gcc warning, not a bug in this code. See a recent - strftime() manual page for details. - */ - strftime(tempTime,sizeof(tempTime)-1,"%c %Z",tm); - TimeBuf = talloc_strdup(mem_ctx, tempTime); -#else - TimeBuf = talloc_strdup(mem_ctx, asctime(tm)); -#endif - - return TimeBuf; -} - -/* - return a talloced string representing a NTTIME for human consumption -*/ -const char *nt_time_string(TALLOC_CTX *mem_ctx, NTTIME nt) -{ - time_t t; - if (nt == 0) { - return "NTTIME(0)"; - } - t = nt_time_to_unix(nt); - return timestring(mem_ctx, t); -} - - -/* - put a NTTIME into a packet -*/ -void push_nttime(uint8_t *base, uint16_t offset, NTTIME t) -{ - SBVAL(base, offset, t); -} - -/* - pull a NTTIME from a packet -*/ -NTTIME pull_nttime(uint8_t *base, uint16_t offset) -{ - NTTIME ret = BVAL(base, offset); - return ret; -} - -/* - parse a nttime as a large integer in a string and return a NTTIME -*/ -NTTIME nttime_from_string(const char *s) -{ - return strtoull(s, NULL, 0); -} - -/* - return (tv1 - tv2) in microseconds -*/ -int64_t usec_time_diff(struct timeval *tv1, struct timeval *tv2) -{ - int64_t sec_diff = tv1->tv_sec - tv2->tv_sec; - return (sec_diff * 1000000) + (int64_t)(tv1->tv_usec - tv2->tv_usec); -} - - -/* - return a zero timeval -*/ -struct timeval timeval_zero(void) -{ - struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 0; - return tv; -} - -/* - return True if a timeval is zero -*/ -BOOL timeval_is_zero(const struct timeval *tv) -{ - return tv->tv_sec == 0 && tv->tv_usec == 0; -} - -/* - return a timeval for the current time -*/ -struct timeval timeval_current(void) -{ - struct timeval tv; - GetTimeOfDay(&tv); - return tv; -} - -/* - return a timeval struct with the given elements -*/ -struct timeval timeval_set(uint32_t secs, uint32_t usecs) -{ - struct timeval tv; - tv.tv_sec = secs; - tv.tv_usec = usecs; - return tv; -} - - -/* - return a timeval ofs microseconds after tv -*/ -struct timeval timeval_add(const struct timeval *tv, - uint32_t secs, uint32_t usecs) -{ - struct timeval tv2 = *tv; - const uint_t million = 1000000; - tv2.tv_sec += secs; - tv2.tv_usec += usecs; - tv2.tv_sec += tv2.tv_usec / million; - tv2.tv_usec = tv2.tv_usec % million; - return tv2; -} - -/* - return the sum of two timeval structures -*/ -struct timeval timeval_sum(const struct timeval *tv1, - const struct timeval *tv2) -{ - return timeval_add(tv1, tv2->tv_sec, tv2->tv_usec); -} - -/* - return a timeval secs/usecs into the future -*/ -struct timeval timeval_current_ofs(uint32_t secs, uint32_t usecs) -{ - struct timeval tv = timeval_current(); - return timeval_add(&tv, secs, usecs); -} - -/* - compare two timeval structures. - Return -1 if tv1 < tv2 - Return 0 if tv1 == tv2 - Return 1 if tv1 > tv2 -*/ -int timeval_compare(const struct timeval *tv1, const struct timeval *tv2) -{ - if (tv1->tv_sec > tv2->tv_sec) return 1; - if (tv1->tv_sec < tv2->tv_sec) return -1; - if (tv1->tv_usec > tv2->tv_usec) return 1; - if (tv1->tv_usec < tv2->tv_usec) return -1; - return 0; -} - -/* - return True if a timer is in the past -*/ -BOOL timeval_expired(const struct timeval *tv) -{ - struct timeval tv2 = timeval_current(); - if (tv2.tv_sec > tv->tv_sec) return True; - if (tv2.tv_sec < tv->tv_sec) return False; - return (tv2.tv_usec >= tv->tv_usec); -} - -/* - return the number of seconds elapsed between two times -*/ -double timeval_elapsed2(const struct timeval *tv1, const struct timeval *tv2) -{ - return (tv2->tv_sec - tv1->tv_sec) + - (tv2->tv_usec - tv1->tv_usec)*1.0e-6; -} - -/* - return the number of seconds elapsed since a given time -*/ -double timeval_elapsed(const struct timeval *tv) -{ - struct timeval tv2 = timeval_current(); - return timeval_elapsed2(tv, &tv2); -} - -/* - return the lesser of two timevals -*/ -struct timeval timeval_min(const struct timeval *tv1, - const struct timeval *tv2) -{ - if (tv1->tv_sec < tv2->tv_sec) return *tv1; - if (tv1->tv_sec > tv2->tv_sec) return *tv2; - if (tv1->tv_usec < tv2->tv_usec) return *tv1; - return *tv2; -} - -/* - return the greater of two timevals -*/ -struct timeval timeval_max(const struct timeval *tv1, - const struct timeval *tv2) -{ - if (tv1->tv_sec > tv2->tv_sec) return *tv1; - if (tv1->tv_sec < tv2->tv_sec) return *tv2; - if (tv1->tv_usec > tv2->tv_usec) return *tv1; - return *tv2; -} - -/* - return the difference between two timevals as a timeval - if tv1 comes after tv2, then return a zero timeval - (this is *tv2 - *tv1) -*/ -struct timeval timeval_until(const struct timeval *tv1, - const struct timeval *tv2) -{ - struct timeval t; - if (timeval_compare(tv1, tv2) >= 0) { - return timeval_zero(); - } - t.tv_sec = tv2->tv_sec - tv1->tv_sec; - if (tv1->tv_usec > tv2->tv_usec) { - t.tv_sec--; - t.tv_usec = 1000000 - (tv1->tv_usec - tv2->tv_usec); - } else { - t.tv_usec = tv2->tv_usec - tv1->tv_usec; - } - return t; -} - - -/* - convert a timeval to a NTTIME -*/ -NTTIME timeval_to_nttime(const struct timeval *tv) -{ - return 10*(tv->tv_usec + - ((TIME_FIXUP_CONSTANT + (uint64_t)tv->tv_sec) * 1000000)); -} - -/******************************************************************* -yield the difference between *A and *B, in seconds, ignoring leap seconds -********************************************************************/ -static int tm_diff(struct tm *a, struct tm *b) -{ - int ay = a->tm_year + (1900 - 1); - int by = b->tm_year + (1900 - 1); - int intervening_leap_days = - (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400); - int years = ay - by; - int days = 365*years + intervening_leap_days + (a->tm_yday - b->tm_yday); - int hours = 24*days + (a->tm_hour - b->tm_hour); - int minutes = 60*hours + (a->tm_min - b->tm_min); - int seconds = 60*minutes + (a->tm_sec - b->tm_sec); - - return seconds; -} - -/******************************************************************* - return the UTC offset in seconds west of UTC, or 0 if it cannot be determined - ******************************************************************/ -int get_time_zone(time_t t) -{ - struct tm *tm = gmtime(&t); - struct tm tm_utc; - if (!tm) - return 0; - tm_utc = *tm; - tm = localtime(&t); - if (!tm) - return 0; - return tm_diff(&tm_utc,tm); -} diff --git a/source4/lib/unix_privs.c b/source4/lib/unix_privs.c deleted file mode 100644 index 3c0f3197767..00000000000 --- a/source4/lib/unix_privs.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - gain/lose root privileges - - Copyright (C) Andrew Tridgell 2004 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 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. -*/ - -#include "includes.h" -#include "system/filesys.h" - -/* - there are times when smbd needs to temporarily gain root privileges - to do some operation. To do this you call root_privileges(), which - returns a talloc handle. To restore your previous privileges - talloc_free() this pointer. - - Note that this call is considered successful even if it does not - manage to gain root privileges, but it will call smb_abort() if it - fails to restore the privileges afterwards. The logic is that - failing to gain root access can be caught by whatever operation - needs to be run as root failing, but failing to lose the root - privileges is dangerous. - - This also means that this code is safe to be called from completely - unprivileged processes. -*/ - -struct saved_state { - uid_t uid; -}; - -static int privileges_destructor(void *ptr) -{ - struct saved_state *s = ptr; - if (geteuid() != s->uid && - seteuid(s->uid) != 0) { - smb_panic("Failed to restore privileges"); - } - return 0; -} - -void *root_privileges(void) -{ - struct saved_state *s; - s = talloc(NULL, struct saved_state); - if (!s) return NULL; - s->uid = geteuid(); - if (s->uid != 0) { - seteuid(0); - } - talloc_set_destructor(s, privileges_destructor); - return s; -} diff --git a/source4/lib/util.c b/source4/lib/util.c deleted file mode 100644 index 17dde332e1a..00000000000 --- a/source4/lib/util.c +++ /dev/null @@ -1,737 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba utility functions - Copyright (C) Andrew Tridgell 1992-1998 - Copyright (C) Jeremy Allison 2001-2002 - Copyright (C) Simo Sorce 2001 - Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003. - Copyright (C) James J Myers 2003 - - 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. -*/ - -#include "includes.h" -#include "dynconfig.h" -#include "system/network.h" -#include "system/iconv.h" -#include "system/filesys.h" - -/*************************************************************************** - Find a suitable temporary directory. The result should be copied immediately - as it may be overwritten by a subsequent call. -****************************************************************************/ -const char *tmpdir(void) -{ - char *p; - if ((p = getenv("TMPDIR"))) - return p; - return "/tmp"; -} - - -/******************************************************************* - Check if a file exists - call vfs_file_exist for samba files. -********************************************************************/ -BOOL file_exist(const char *fname) -{ - struct stat st; - - if (stat(fname, &st) != 0) { - return False; - } - - return ((S_ISREG(st.st_mode)) || (S_ISFIFO(st.st_mode))); -} - -/******************************************************************* - Check a files mod time. -********************************************************************/ - -time_t file_modtime(const char *fname) -{ - struct stat st; - - if (stat(fname,&st) != 0) - return(0); - - return(st.st_mtime); -} - -/******************************************************************* - Check if a directory exists. -********************************************************************/ - -BOOL directory_exist(const char *dname) -{ - struct stat st; - BOOL ret; - - if (stat(dname,&st) != 0) { - return False; - } - - ret = S_ISDIR(st.st_mode); - if(!ret) - errno = ENOTDIR; - return ret; -} - -BOOL directory_create_or_exist(const char *dname, uid_t uid, - mode_t dir_perms) -{ - mode_t old_umask; - struct stat st; - - old_umask = umask(0); - if (lstat(dname, &st) == -1) { - if (errno == ENOENT) { - /* Create directory */ - if (mkdir(dname, dir_perms) == -1) { - DEBUG(0, ("error creating directory " - "%s: %s\n", dname, - strerror(errno))); - umask(old_umask); - return False; - } - } else { - DEBUG(0, ("lstat failed on directory %s: %s\n", - dname, strerror(errno))); - umask(old_umask); - return False; - } - } else { - /* Check ownership and permission on existing directory */ - if (!S_ISDIR(st.st_mode)) { - DEBUG(0, ("directory %s isn't a directory\n", - dname)); - umask(old_umask); - return False; - } - if ((st.st_uid != uid) || - ((st.st_mode & 0777) != dir_perms)) { - DEBUG(0, ("invalid permissions on directory " - "%s\n", dname)); - umask(old_umask); - return False; - } - } - return True; -} - - -/******************************************************************* - Close the low 3 fd's and open dev/null in their place. -********************************************************************/ -static void close_low_fds(BOOL stderr_too) -{ -#ifndef VALGRIND - int fd; - int i; - - close(0); - close(1); - - if (stderr_too) - close(2); - - /* try and use up these file descriptors, so silly - library routines writing to stdout etc won't cause havoc */ - for (i=0;i<3;i++) { - if (i == 2 && !stderr_too) - continue; - - fd = open("/dev/null",O_RDWR,0); - if (fd < 0) - fd = open("/dev/null",O_WRONLY,0); - if (fd < 0) { - DEBUG(0,("Can't open /dev/null\n")); - return; - } - if (fd != i) { - DEBUG(0,("Didn't get file descriptor %d\n",i)); - return; - } - } -#endif -} - -/**************************************************************************** - Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available, - else - if SYSV use O_NDELAY - if BSD use FNDELAY -****************************************************************************/ - -int set_blocking(int fd, BOOL set) -{ - int val; -#ifdef O_NONBLOCK -#define FLAG_TO_SET O_NONBLOCK -#else -#ifdef SYSV -#define FLAG_TO_SET O_NDELAY -#else /* BSD */ -#define FLAG_TO_SET FNDELAY -#endif -#endif - - if((val = fcntl(fd, F_GETFL, 0)) == -1) - return -1; - if(set) /* Turn blocking on - ie. clear nonblock flag */ - val &= ~FLAG_TO_SET; - else - val |= FLAG_TO_SET; - return fcntl( fd, F_SETFL, val); -#undef FLAG_TO_SET -} - - -/******************************************************************* - Sleep for a specified number of milliseconds. -********************************************************************/ - -void msleep(uint_t t) -{ - struct timeval tval; - - tval.tv_sec = t/1000; - tval.tv_usec = 1000*(t%1000); - /* this should be the real select - do NOT replace - with sys_select() */ - select(0,NULL,NULL,NULL,&tval); -} - -/**************************************************************************** - Become a daemon, discarding the controlling terminal. -****************************************************************************/ - -void become_daemon(BOOL Fork) -{ - if (Fork) { - if (fork()) { - _exit(0); - } - } - - /* detach from the terminal */ -#ifdef HAVE_SETSID - setsid(); -#elif defined(TIOCNOTTY) - { - int i = open("/dev/tty", O_RDWR, 0); - if (i != -1) { - ioctl(i, (int) TIOCNOTTY, (char *)0); - close(i); - } - } -#endif /* HAVE_SETSID */ - - /* Close fd's 0,1,2. Needed if started by rsh */ - close_low_fds(False); /* Don't close stderr, let the debug system - attach it to the logfile */ -} - - -/**************************************************************************** - Free memory, checks for NULL. - Use directly SAFE_FREE() - Exists only because we need to pass a function pointer somewhere --SSS -****************************************************************************/ - -void safe_free(void *p) -{ - SAFE_FREE(p); -} - - -/* - see if a string matches either our primary or one of our secondary - netbios aliases. do a case insensitive match -*/ -BOOL is_myname(const char *name) -{ - const char **aliases; - int i; - - if (strcasecmp(name, lp_netbios_name()) == 0) { - return True; - } - - aliases = lp_netbios_aliases(); - for (i=0; aliases && aliases[i]; i++) { - if (strcasecmp(name, aliases[i]) == 0) { - return True; - } - } - - return False; -} - - -/**************************************************************************** - Get my own name, return in malloc'ed storage. -****************************************************************************/ - -char* get_myname(void) -{ - char *hostname; - const int host_name_max = 255; - char *p; - - hostname = malloc(host_name_max+1); - *hostname = 0; - - /* get my host name */ - if (gethostname(hostname, host_name_max+1) == -1) { - DEBUG(0,("gethostname failed\n")); - return NULL; - } - - /* Ensure null termination. */ - hostname[host_name_max] = '\0'; - - /* split off any parts after an initial . */ - p = strchr_m(hostname,'.'); - - if (p) - *p = 0; - - return hostname; -} - -/**************************************************************************** - Return true if a string could be a pure IP address. -****************************************************************************/ - -BOOL is_ipaddress(const char *str) -{ - BOOL pure_address = True; - int i; - - for (i=0; pure_address && str[i]; i++) - if (!(isdigit((int)str[i]) || str[i] == '.')) - pure_address = False; - - /* Check that a pure number is not misinterpreted as an IP */ - pure_address = pure_address && (strchr_m(str, '.') != NULL); - - return pure_address; -} - -/**************************************************************************** - Interpret an internet address or name into an IP address in 4 byte form. -****************************************************************************/ -uint32_t interpret_addr(const char *str) -{ - struct hostent *hp; - uint32_t res; - - if (str == NULL || *str == 0 || - strcmp(str,"0.0.0.0") == 0) { - return 0; - } - if (strcmp(str,"255.255.255.255") == 0) { - return 0xFFFFFFFF; - } - /* recognise 'localhost' as a special name. This fixes problems with - some hosts that don't have localhost in /etc/hosts */ - if (strcasecmp(str,"localhost") == 0) { - str = "127.0.0.1"; - } - - /* if it's in the form of an IP address then get the lib to interpret it */ - if (is_ipaddress(str)) { - res = inet_addr(str); - } else { - /* otherwise assume it's a network name of some sort and use - sys_gethostbyname */ - if ((hp = sys_gethostbyname(str)) == 0) { - DEBUG(3,("sys_gethostbyname: Unknown host. %s\n",str)); - return 0; - } - - if(hp->h_addr == NULL) { - DEBUG(3,("sys_gethostbyname: host address is invalid for host %s\n",str)); - return 0; - } - memcpy((char *)&res,(char *)hp->h_addr, 4); - } - - if (res == (uint32_t)-1) - return(0); - - return(res); -} - -/******************************************************************* - A convenient addition to interpret_addr(). -******************************************************************/ -struct ipv4_addr interpret_addr2(const char *str) -{ - struct ipv4_addr ret; - uint32_t a = interpret_addr(str); - ret.addr = a; - return ret; -} - -/******************************************************************* - Check if an IP is the 0.0.0.0. -******************************************************************/ - -BOOL is_zero_ip(struct ipv4_addr ip) -{ - return ip.addr == 0; -} - -/******************************************************************* - Are two IPs on the same subnet? -********************************************************************/ - -BOOL same_net(struct ipv4_addr ip1,struct ipv4_addr ip2,struct ipv4_addr mask) -{ - uint32_t net1,net2,nmask; - - nmask = ntohl(mask.addr); - net1 = ntohl(ip1.addr); - net2 = ntohl(ip2.addr); - - return((net1 & nmask) == (net2 & nmask)); -} - - -/**************************************************************************** - Check if a process exists. Does this work on all unixes? -****************************************************************************/ - -BOOL process_exists(pid_t pid) -{ - /* 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); -} - -/**************************************************************************** - Simple routine to do POSIX file locking. Cruft in NFS and 64->32 bit mapping - is dealt with in posix.c -****************************************************************************/ - -BOOL fcntl_lock(int fd, int op, off_t offset, off_t count, int type) -{ - struct flock lock; - int ret; - - DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type)); - - lock.l_type = type; - lock.l_whence = SEEK_SET; - lock.l_start = offset; - lock.l_len = count; - lock.l_pid = 0; - - ret = fcntl(fd,op,&lock); - - if (ret == -1 && errno != 0) - DEBUG(3,("fcntl_lock: fcntl lock gave errno %d (%s)\n",errno,strerror(errno))); - - /* a lock query */ - if (op == F_GETLK) { - if ((ret != -1) && - (lock.l_type != F_UNLCK) && - (lock.l_pid != 0) && - (lock.l_pid != getpid())) { - DEBUG(3,("fcntl_lock: fd %d is locked by pid %d\n",fd,(int)lock.l_pid)); - return(True); - } - - /* it must be not locked or locked by me */ - return(False); - } - - /* a lock set or unset */ - if (ret == -1) { - DEBUG(3,("fcntl_lock: lock failed at offset %.0f count %.0f op %d type %d (%s)\n", - (double)offset,(double)count,op,type,strerror(errno))); - return(False); - } - - /* everything went OK */ - DEBUG(8,("fcntl_lock: Lock call successful\n")); - - return(True); -} - - -static void print_asc(int level, const uint8_t *buf,int len) -{ - int i; - for (i=0;i8) DEBUGADD(level,(" ")); - while (n--) DEBUGADD(level,(" ")); - n = MIN(8,i%16); - print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,( " " )); - n = (i%16) - n; - if (n>0) print_asc(level,&buf[i-n],n); - DEBUGADD(level,("\n")); - } -} - -/***************************************************************** - malloc that aborts with smb_panic on fail or zero size. - *****************************************************************/ - -void *smb_xmalloc(size_t size) -{ - void *p; - if (size == 0) - smb_panic("smb_xmalloc: called with zero size.\n"); - if ((p = malloc(size)) == NULL) - smb_panic("smb_xmalloc: malloc fail.\n"); - return p; -} - -/** - Memdup with smb_panic on fail. -**/ - -void *smb_xmemdup(const void *p, size_t size) -{ - void *p2; - p2 = smb_xmalloc(size); - memcpy(p2, p, size); - return p2; -} - -/** - strdup that aborts on malloc fail. -**/ - -char *smb_xstrdup(const char *s) -{ - char *s1 = strdup(s); - if (!s1) - smb_panic("smb_xstrdup: malloc fail\n"); - return s1; -} - - -/***************************************************************** - Like strdup but for memory. -*****************************************************************/ - -void *memdup(const void *p, size_t size) -{ - void *p2; - if (size == 0) - return NULL; - p2 = malloc(size); - if (!p2) - return NULL; - memcpy(p2, p, size); - return p2; -} - -/***************************************************************** - A useful function for returning a path in the Samba lock directory. -*****************************************************************/ -char *lock_path(TALLOC_CTX* mem_ctx, const char *name) -{ - char *fname, *dname; - if (name == NULL) { - return NULL; - } - if (name[0] == 0 || name[0] == '/' || strstr(name, ":/")) { - return talloc_strdup(mem_ctx, name); - } - - dname = talloc_strdup(mem_ctx, lp_lockdir()); - trim_string(dname,"","/"); - - if (!directory_exist(dname)) { - mkdir(dname,0755); - } - - fname = talloc_asprintf(mem_ctx, "%s/%s", dname, name); - - talloc_free(dname); - - return fname; -} - - -/***************************************************************** - A useful function for returning a path in the Samba piddir directory. -*****************************************************************/ -static char *pid_path(TALLOC_CTX* mem_ctx, const char *name) -{ - char *fname, *dname; - - dname = talloc_strdup(mem_ctx, lp_piddir()); - trim_string(dname,"","/"); - - if (!directory_exist(dname)) { - mkdir(dname,0755); - } - - fname = talloc_asprintf(mem_ctx, "%s/%s", dname, name); - - talloc_free(dname); - - return fname; -} - - -/** - * @brief Returns an absolute path to a file in the Samba lib directory. - * - * @param name File to find, relative to LIBDIR. - * - * @retval Pointer to a talloc'ed string containing the full path. - **/ - -char *lib_path(TALLOC_CTX* mem_ctx, const char *name) -{ - char *fname; - fname = talloc_asprintf(mem_ctx, "%s/%s", dyn_LIBDIR, name); - return fname; -} - -/** - * @brief Returns an absolute path to a file in the Samba private directory. - * - * @param name File to find, relative to PRIVATEDIR. - * if name is not relative, then use it as-is - * - * @retval Pointer to a talloc'ed string containing the full path. - **/ -char *private_path(TALLOC_CTX* mem_ctx, const char *name) -{ - char *fname; - if (name == NULL) { - return NULL; - } - if (name[0] == 0 || name[0] == '/' || strstr(name, ":/")) { - return talloc_strdup(mem_ctx, name); - } - fname = talloc_asprintf(mem_ctx, "%s/%s", lp_private_dir(), name); - return fname; -} - -/* - return a path in the smbd.tmp directory, where all temporary file - for smbd go. If NULL is passed for name then return the directory - path itself -*/ -char *smbd_tmp_path(TALLOC_CTX *mem_ctx, const char *name) -{ - char *fname, *dname; - - dname = pid_path(mem_ctx, "smbd.tmp"); - if (!directory_exist(dname)) { - mkdir(dname,0755); - } - - if (name == NULL) { - return dname; - } - - fname = talloc_asprintf(mem_ctx, "%s/%s", dname, name); - talloc_free(dname); - - return fname; -} - -static char *modules_path(TALLOC_CTX* mem_ctx, const char *name) -{ - return talloc_asprintf(mem_ctx, "%s/%s", dyn_MODULESDIR, name); -} - -init_module_fn *load_samba_modules(TALLOC_CTX *mem_ctx, const char *subsystem) -{ - char *path = modules_path(mem_ctx, subsystem); - init_module_fn *ret; - - ret = load_modules(mem_ctx, path); - - talloc_free(path); - - return ret; -} - -void dump_data_pw(const char *msg, const uint8_t * data, size_t len) -{ -#ifdef DEBUG_PASSWORD - DEBUG(11, ("%s", msg)); - if (data != NULL && len > 0) - { - dump_data(11, data, len); - } -#endif -} - - -/* see if a range of memory is all zero. A NULL pointer is considered - to be all zero */ -BOOL all_zero(const uint8_t *ptr, uint_t size) -{ - int i; - if (!ptr) return True; - for (i=0;i= MAX_MALLOC_SIZE/el_size) { - return NULL; - } - if (!ptr) { - return malloc(el_size * count); - } - return realloc(ptr, el_size * count); -} - diff --git a/source4/lib/util/README b/source4/lib/util/README new file mode 100644 index 00000000000..e52e04ed924 --- /dev/null +++ b/source4/lib/util/README @@ -0,0 +1,296 @@ +This directory contains convenience functions that are used heavily +throughout Samba. None of these functions are SMB or Samba-specific. +It's a bit to Samba what GLib is to the GNOME folks. + +(This file should be migrated to doxygen sometime.. ) + +Also TODO: Remove dependency on loadparm + +XFILE wrapper functions +======================= +The XFILE implementation contains a clone of the standard UNIX stdio +functions + +Debug functions +=============== +DEBUG() + +Crash handlers +============== +void smb_panic(const char *why); + +Signal handling +======================== +void BlockSignals(BOOL block,int signum); +void (*CatchSignal(int signum,void (*handler)(int )))(int); +void CatchChild(void); +void CatchChildLeaveStatus(void); + +Wrappers +======== +struct hostent *sys_gethostbyname(const char *name); +const char *sys_inet_ntoa(struct ipv4_addr in); +struct ipv4_addr sys_inet_makeaddr(int net, int host); +void sys_select_signal(void); +int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval); +int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval); + +Time datastructures +=================== +time_t get_time_t_max(void); +void GetTimeOfDay(struct timeval *tval); +time_t nt_time_to_unix(NTTIME nt); +void unix_to_nt_time(NTTIME *nt, time_t t); +BOOL null_time(time_t t); +BOOL null_nttime(NTTIME t); +void push_dos_date(uint8_t *buf, int offset, time_t unixdate, int zone_offset); +void push_dos_date2(uint8_t *buf,int offset,time_t unixdate, int zone_offset); +void push_dos_date3(uint8_t *buf,int offset,time_t unixdate, int zone_offset); +time_t pull_dos_date(const uint8_t *date_ptr, int zone_offset); +time_t pull_dos_date2(const uint8_t *date_ptr, int zone_offset); +time_t pull_dos_date3(const uint8_t *date_ptr, int zone_offset); +char *http_timestring(TALLOC_CTX *mem_ctx, time_t t); +char *timestring(TALLOC_CTX *mem_ctx, time_t t); +const char *nt_time_string(TALLOC_CTX *mem_ctx, NTTIME nt); +void push_nttime(uint8_t *base, uint16_t offset, NTTIME t); +NTTIME pull_nttime(uint8_t *base, uint16_t offset); +NTTIME nttime_from_string(const char *s); +int64_t usec_time_diff(struct timeval *tv1, struct timeval *tv2); +struct timeval timeval_zero(void); +BOOL timeval_is_zero(const struct timeval *tv); +struct timeval timeval_current(void); +struct timeval timeval_set(uint32_t secs, uint32_t usecs); +struct timeval timeval_add(const struct timeval *tv, + uint32_t secs, uint32_t usecs); +struct timeval timeval_sum(const struct timeval *tv1, + const struct timeval *tv2); +struct timeval timeval_current_ofs(uint32_t secs, uint32_t usecs); +int timeval_compare(const struct timeval *tv1, const struct timeval *tv2); +BOOL timeval_expired(const struct timeval *tv); +double timeval_elapsed2(const struct timeval *tv1, const struct timeval *tv2); +double timeval_elapsed(const struct timeval *tv); +struct timeval timeval_min(const struct timeval *tv1, + const struct timeval *tv2); +struct timeval timeval_max(const struct timeval *tv1, + const struct timeval *tv2); +struct timeval timeval_until(const struct timeval *tv1, + const struct timeval *tv2); +NTTIME timeval_to_nttime(const struct timeval *tv); +int get_time_zone(time_t t); + +Random number generation +======================== +void set_rand_reseed_callback(void (*fn)(int *)); +void set_need_random_reseed(void); +void generate_random_buffer(uint8_t *out, int len); +uint32_t generate_random(void); +BOOL check_password_quality(const char *s); +char *generate_random_str_list(TALLOC_CTX *mem_ctx, size_t len, const char *list); +char *generate_random_str(TALLOC_CTX *mem_ctx, size_t len); + +String manipulation +=================== +BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize); +int strcasecmp_m(const char *s1, const char *s2); +BOOL strequal(const char *s1, const char *s2); +BOOL strcsequal(const char *s1,const char *s2); +int strwicmp(const char *psz1, const char *psz2); +void string_replace(char *s, char oldc, char newc); +BOOL trim_string(char *s,const char *front,const char *back); +size_t count_chars(const char *s, char c); +char *safe_strcpy(char *dest,const char *src, size_t maxlength); +char *safe_strcat(char *dest, const char *src, size_t maxlength); +char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength); +char *StrnCpy(char *dest,const char *src,size_t n); +size_t strhex_to_str(char *p, size_t len, const char *strhex); +DATA_BLOB strhex_to_data_blob(const char *strhex) ; +void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer); +BOOL in_list(const char *s, const char *list, BOOL casesensitive); +void string_free(char **s); +BOOL string_set(char **dest, const char *src); +void string_sub(char *s,const char *pattern, const char *insert, size_t len); +void all_string_sub(char *s,const char *pattern,const char *insert, size_t len); +char *strchr_m(const char *s, char c); +char *strrchr_m(const char *s, char c); +BOOL strhaslower(const char *string); +BOOL strhasupper(const char *string); +char *strlower_talloc(TALLOC_CTX *ctx, const char *src); +char *strupper_talloc(TALLOC_CTX *ctx, const char *src); +void strlower_m(char *s); +void strupper_m(char *s); +size_t strlen_m(const char *s); +size_t strlen_m_term(const char *s); +void rfc1738_unescape(char *buf); +DATA_BLOB base64_decode_data_blob(TALLOC_CTX *mem_ctx, const char *s); +void base64_decode_inplace(char *s); +char *base64_encode_data_blob(TALLOC_CTX *mem_ctx, DATA_BLOB data); +size_t valgrind_strlen(const char *s); +const char *str_format_nbt_domain(TALLOC_CTX *mem_ctx, const char *s); +BOOL add_string_to_array(TALLOC_CTX *mem_ctx, + const char *str, const char ***strings, int *num); +int strcmp_safe(const char *s1, const char *s2); +size_t ascii_len_n(const char *src, size_t n); +char *attrib_string(TALLOC_CTX *mem_ctx, uint32_t attrib); +BOOL set_boolean(const char *boolean_string, BOOL *boolean); +BOOL conv_str_bool(const char * str, BOOL * val); +BOOL conv_str_size(const char * str, uint64_t * val); +BOOL conv_str_u64(const char * str, uint64_t * val); + +String list manipulation +======================== +const char **str_list_make(TALLOC_CTX *mem_ctx, const char *string, const char *sep); +const char **str_list_make_shell(TALLOC_CTX *mem_ctx, const char *string, const char *sep); +char *str_list_join(TALLOC_CTX *mem_ctx, const char **list, char seperator); +char *str_list_join_shell(TALLOC_CTX *mem_ctx, const char **list, char sep); +size_t str_list_length(const char **list); +const char **str_list_copy(TALLOC_CTX *mem_ctx, const char **list); +BOOL str_list_equal(const char **list1, const char **list2); +const char **str_list_add(const char **list, const char *s); +void str_list_remove(const char **list, const char *s); +BOOL str_list_check(const char **list, const char *s); +BOOL str_list_check_ci(const char **list, const char *s); + +Unicode string manipulation +=========================== +codepoint_t toupper_w(codepoint_t val); +codepoint_t tolower_w(codepoint_t val); +size_t utf16_len(const void *buf); +size_t utf16_len_n(const void *src, size_t n); +size_t ucs2_align(const void *base_ptr, const void *p, int flags); +int codepoint_cmpi(codepoint_t c1, codepoint_t c2); + +File manipulation +================= +char *fgets_slash(char *s2,int maxlen,XFILE *f); +char *afdgets(int fd, TALLOC_CTX *mem_ctx, size_t hint); +char *fd_load(int fd, size_t *size, TALLOC_CTX *mem_ctx); +char *file_load(const char *fname, size_t *size, TALLOC_CTX *mem_ctx); +void *map_file(const char *fname, size_t size); +char **file_lines_load(const char *fname, int *numlines, TALLOC_CTX *mem_ctx); +char **fd_lines_load(int fd, int *numlines, TALLOC_CTX *mem_ctx); +void file_lines_slashcont(char **lines); +BOOL file_save(const char *fname, const void *packet, size_t length); +BOOL file_exists(const char *path); +int vfdprintf(int fd, const char *format, va_list ap) _PRINTF_ATTRIBUTE(2,0); +int fdprintf(int fd, const char *format, ...) _PRINTF_ATTRIBUTE(2,3); + +Data Blob +========= +DATA_BLOB data_blob_named(const void *p, size_t length, const char *name); +DATA_BLOB data_blob_talloc_named(TALLOC_CTX *mem_ctx, const void *p, size_t length, const char *name); +DATA_BLOB data_blob_talloc_reference(TALLOC_CTX *mem_ctx, DATA_BLOB *blob); +DATA_BLOB data_blob_talloc_zero(TALLOC_CTX *mem_ctx, size_t length); +void data_blob_free(DATA_BLOB *d); +void data_blob_clear(DATA_BLOB *d); +void data_blob_clear_free(DATA_BLOB *d); +BOOL data_blob_equal(const DATA_BLOB *d1, const DATA_BLOB *d2); +char *data_blob_hex_string(TALLOC_CTX *mem_ctx, DATA_BLOB *blob); +DATA_BLOB data_blob_string_const(const char *str); +DATA_BLOB data_blob_const(const void *p, size_t length); +NTSTATUS data_blob_realloc(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, size_t length); +NTSTATUS data_blob_append(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, + const void *p, size_t length); + +Random Utility functions +======================== +const char *tmpdir(void); +BOOL file_exist(const char *fname); +time_t file_modtime(const char *fname); +BOOL directory_exist(const char *dname); +BOOL directory_create_or_exist(const char *dname, uid_t uid, + mode_t dir_perms); +int set_blocking(int fd, BOOL set); +void msleep(uint_t t); +void become_daemon(BOOL Fork); +void safe_free(void *p); +BOOL is_myname(const char *name); +char* get_myname(void); +BOOL is_ipaddress(const char *str); +uint32_t interpret_addr(const char *str); +struct ipv4_addr interpret_addr2(const char *str); +BOOL is_zero_ip(struct ipv4_addr ip); +BOOL same_net(struct ipv4_addr ip1,struct ipv4_addr ip2,struct ipv4_addr mask); +BOOL process_exists(pid_t pid); +BOOL fcntl_lock(int fd, int op, off_t offset, off_t count, int type); +void dump_data(int level, const uint8_t *buf,int len); +void *smb_xmalloc(size_t size); +void *smb_xmemdup(const void *p, size_t size); +char *smb_xstrdup(const char *s); +void *memdup(const void *p, size_t size); +char *lock_path(TALLOC_CTX* mem_ctx, const char *name); +char *lib_path(TALLOC_CTX* mem_ctx, const char *name); +char *private_path(TALLOC_CTX* mem_ctx, const char *name); +char *smbd_tmp_path(TALLOC_CTX *mem_ctx, const char *name); +init_module_fn *load_samba_modules(TALLOC_CTX *mem_ctx, const char *subsystem); +void dump_data_pw(const char *msg, const uint8_t * data, size_t len); +BOOL all_zero(const uint8_t *ptr, uint_t size); +void *realloc_array(void *ptr, size_t el_size, unsigned count); + +/* The following definitions come from lib/util/util_sock.c */ + +void set_socket_options(int fd, const char *options); + +Variable substitution +===================== +void sub_set_context(struct substitute_context *subptr); +void sub_set_remote_proto(const char *str); +void sub_set_remote_arch(const char *str); +void sub_set_user_name(const char *name); +void standard_sub_basic(char *str,size_t len); +char *talloc_sub_basic(TALLOC_CTX *mem_ctx, const char *smb_name, const char *str); +char *alloc_sub_basic(const char *smb_name, const char *str); +char *talloc_sub_specified(TALLOC_CTX *mem_ctx, + const char *input_string, + const char *username, + const char *domain, + uid_t uid, + gid_t gid); +char *alloc_sub_specified(const char *input_string, + const char *username, + const char *domain, + uid_t uid, + gid_t gid); +char *talloc_sub_advanced(TALLOC_CTX *mem_ctx, + int snum, + const char *user, + const char *connectpath, + gid_t gid, + const char *smb_name, + char *str); +char *alloc_sub_advanced(int snum, const char *user, + const char *connectpath, gid_t gid, + const char *smb_name, char *str); +void standard_sub_tcon(struct smbsrv_tcon *tcon, char *str, size_t len); +char *talloc_sub_tcon(TALLOC_CTX *mem_ctx, struct smbsrv_tcon *tcon, char *str); +char *alloc_sub_tcon(struct smbsrv_tcon *tcon, char *str); +void standard_sub_snum(int snum, char *str, size_t len); + +/* The following definitions come from lib/util/fsusage.c */ + +int sys_fsusage(const char *path, uint64_t *dfree, uint64_t *dsize); + +Microsoft-style filename matching +================================= +int ms_fnmatch(const char *pattern, const char *string, enum protocol_types protocol); +int gen_fnmatch(const char *pattern, const char *string); + +Mutexes +======= +BOOL register_mutex_handlers(const char *name, struct mutex_ops *ops); + +Idtree +====== +very efficient functions to manage mapping a id (such as a fnum) to +a pointer. This is used for fnum and search id allocation. + +struct idr_context *idr_init(TALLOC_CTX *mem_ctx); +int idr_get_new(struct idr_context *idp, void *ptr, int limit); +int idr_get_new_above(struct idr_context *idp, void *ptr, int starting_id, int limit); +int idr_get_new_random(struct idr_context *idp, void *ptr, int limit); +void *idr_find(struct idr_context *idp, int id); +int idr_remove(struct idr_context *idp, int id); + +Module loading +============== +init_module_fn *load_modules(TALLOC_CTX *mem_ctx, const char *path); +BOOL run_init_functions(NTSTATUS (**fns) (void)); diff --git a/source4/lib/util/byteorder.h b/source4/lib/util/byteorder.h new file mode 100644 index 00000000000..941dee9e88f --- /dev/null +++ b/source4/lib/util/byteorder.h @@ -0,0 +1,224 @@ +/* + Unix SMB/CIFS implementation. + SMB Byte handling + Copyright (C) Andrew Tridgell 1992-1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 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. +*/ + +#ifndef _BYTEORDER_H +#define _BYTEORDER_H + +/* + This file implements macros for machine independent short and + int manipulation + +Here is a description of this file that I emailed to the samba list once: + +> I am confused about the way that byteorder.h works in Samba. I have +> looked at it, and I would have thought that you might make a distinction +> between LE and BE machines, but you only seem to distinguish between 386 +> and all other architectures. +> +> Can you give me a clue? + +sure. + +The distinction between 386 and other architectures is only there as +an optimisation. You can take it out completely and it will make no +difference. The routines (macros) in byteorder.h are totally byteorder +independent. The 386 optimsation just takes advantage of the fact that +the x86 processors don't care about alignment, so we don't have to +align ints on int boundaries etc. If there are other processors out +there that aren't alignment sensitive then you could also define +CAREFUL_ALIGNMENT=0 on those processors as well. + +Ok, now to the macros themselves. I'll take a simple example, say we +want to extract a 2 byte integer from a SMB packet and put it into a +type called uint16_t that is in the local machines byte order, and you +want to do it with only the assumption that uint16_t is _at_least_ 16 +bits long (this last condition is very important for architectures +that don't have any int types that are 2 bytes long) + +You do this: + +#define CVAL(buf,pos) (((uint8_t *)(buf))[pos]) +#define PVAL(buf,pos) ((uint_t)CVAL(buf,pos)) +#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8) + +then to extract a uint16_t value at offset 25 in a buffer you do this: + +char *buffer = foo_bar(); +uint16_t xx = SVAL(buffer,25); + +We are using the byteoder independence of the ANSI C bitshifts to do +the work. A good optimising compiler should turn this into efficient +code, especially if it happens to have the right byteorder :-) + +I know these macros can be made a bit tidier by removing some of the +casts, but you need to look at byteorder.h as a whole to see the +reasoning behind them. byteorder.h defines the following macros: + +SVAL(buf,pos) - extract a 2 byte SMB value +IVAL(buf,pos) - extract a 4 byte SMB value +SVALS(buf,pos) signed version of SVAL() +IVALS(buf,pos) signed version of IVAL() + +SSVAL(buf,pos,val) - put a 2 byte SMB value into a buffer +SIVAL(buf,pos,val) - put a 4 byte SMB value into a buffer +SSVALS(buf,pos,val) - signed version of SSVAL() +SIVALS(buf,pos,val) - signed version of SIVAL() + +RSVAL(buf,pos) - like SVAL() but for NMB byte ordering +RSVALS(buf,pos) - like SVALS() but for NMB byte ordering +RIVAL(buf,pos) - like IVAL() but for NMB byte ordering +RIVALS(buf,pos) - like IVALS() but for NMB byte ordering +RSSVAL(buf,pos,val) - like SSVAL() but for NMB ordering +RSIVAL(buf,pos,val) - like SIVAL() but for NMB ordering +RSIVALS(buf,pos,val) - like SIVALS() but for NMB ordering + +it also defines lots of intermediate macros, just ignore those :-) + +*/ + + +/* + on powerpc we can use the magic instructions to load/store + in little endian +*/ +#if (defined(__powerpc__) && defined(__GNUC__)) +static __inline__ uint16_t ld_le16(const uint16_t *addr) +{ + uint16_t val; + __asm__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr)); + return val; +} + +static __inline__ void st_le16(uint16_t *addr, const uint16_t val) +{ + __asm__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); +} + +static __inline__ uint32_t ld_le32(const uint32_t *addr) +{ + uint32_t val; + __asm__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr)); + return val; +} + +static __inline__ void st_le32(uint32_t *addr, const uint32_t val) +{ + __asm__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); +} +#define HAVE_ASM_BYTEORDER 1 +#endif + + + +#undef CAREFUL_ALIGNMENT + +/* we know that the 386 can handle misalignment and has the "right" + byteorder */ +#if defined(__i386__) +#define CAREFUL_ALIGNMENT 0 +#endif + +#ifndef CAREFUL_ALIGNMENT +#define CAREFUL_ALIGNMENT 1 +#endif + +#define CVAL(buf,pos) ((uint_t)(((const uint8_t *)(buf))[pos])) +#define CVAL_NC(buf,pos) (((uint8_t *)(buf))[pos]) /* Non-const version of CVAL */ +#define PVAL(buf,pos) (CVAL(buf,pos)) +#define SCVAL(buf,pos,val) (CVAL_NC(buf,pos) = (val)) + +#if HAVE_ASM_BYTEORDER + +#define _PTRPOS(buf,pos) (((const uint8_t *)buf)+(pos)) +#define SVAL(buf,pos) ld_le16((const uint16_t *)_PTRPOS(buf,pos)) +#define IVAL(buf,pos) ld_le32((const uint32_t *)_PTRPOS(buf,pos)) +#define SSVAL(buf,pos,val) st_le16((uint16_t *)_PTRPOS(buf,pos), val) +#define SIVAL(buf,pos,val) st_le32((uint32_t *)_PTRPOS(buf,pos), val) +#define SVALS(buf,pos) ((int16_t)SVAL(buf,pos)) +#define IVALS(buf,pos) ((int32_t)IVAL(buf,pos)) +#define SSVALS(buf,pos,val) SSVAL((buf),(pos),((int16_t)(val))) +#define SIVALS(buf,pos,val) SIVAL((buf),(pos),((int32_t)(val))) + +#elif CAREFUL_ALIGNMENT + +#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8) +#define IVAL(buf,pos) (SVAL(buf,pos)|SVAL(buf,(pos)+2)<<16) +#define SSVALX(buf,pos,val) (CVAL_NC(buf,pos)=(uint8_t)((val)&0xFF),CVAL_NC(buf,pos+1)=(uint8_t)((val)>>8)) +#define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16)) +#define SVALS(buf,pos) ((int16_t)SVAL(buf,pos)) +#define IVALS(buf,pos) ((int32_t)IVAL(buf,pos)) +#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((uint16_t)(val))) +#define SIVAL(buf,pos,val) SIVALX((buf),(pos),((uint32_t)(val))) +#define SSVALS(buf,pos,val) SSVALX((buf),(pos),((int16_t)(val))) +#define SIVALS(buf,pos,val) SIVALX((buf),(pos),((int32_t)(val))) + +#else /* CAREFUL_ALIGNMENT */ + +/* this handles things for architectures like the 386 that can handle + alignment errors */ +/* + WARNING: This section is dependent on the length of int16_t and int32_t + being correct +*/ + +/* get single value from an SMB buffer */ +#define SVAL(buf,pos) (*(const uint16_t *)((const char *)(buf) + (pos))) +#define SVAL_NC(buf,pos) (*(uint16_t *)((char *)(buf) + (pos))) /* Non const version of above. */ +#define IVAL(buf,pos) (*(const uint32_t *)((const char *)(buf) + (pos))) +#define IVAL_NC(buf,pos) (*(uint32_t *)((char *)(buf) + (pos))) /* Non const version of above. */ +#define SVALS(buf,pos) (*(const int16_t *)((const char *)(buf) + (pos))) +#define SVALS_NC(buf,pos) (*(int16_t *)((char *)(buf) + (pos))) /* Non const version of above. */ +#define IVALS(buf,pos) (*(const int32_t *)((const char *)(buf) + (pos))) +#define IVALS_NC(buf,pos) (*(int32_t *)((char *)(buf) + (pos))) /* Non const version of above. */ + +/* store single value in an SMB buffer */ +#define SSVAL(buf,pos,val) SVAL_NC(buf,pos)=((uint16_t)(val)) +#define SIVAL(buf,pos,val) IVAL_NC(buf,pos)=((uint32_t)(val)) +#define SSVALS(buf,pos,val) SVALS_NC(buf,pos)=((int16_t)(val)) +#define SIVALS(buf,pos,val) IVALS_NC(buf,pos)=((int32_t)(val)) + +#endif /* CAREFUL_ALIGNMENT */ + +/* now the reverse routines - these are used in nmb packets (mostly) */ +#define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF)) +#define IREV(x) ((SREV(x)<<16) | (SREV((x)>>16))) + +#define RSVAL(buf,pos) SREV(SVAL(buf,pos)) +#define RSVALS(buf,pos) SREV(SVALS(buf,pos)) +#define RIVAL(buf,pos) IREV(IVAL(buf,pos)) +#define RIVALS(buf,pos) IREV(IVALS(buf,pos)) +#define RSSVAL(buf,pos,val) SSVAL(buf,pos,SREV(val)) +#define RSSVALS(buf,pos,val) SSVALS(buf,pos,SREV(val)) +#define RSIVAL(buf,pos,val) SIVAL(buf,pos,IREV(val)) +#define RSIVALS(buf,pos,val) SIVALS(buf,pos,IREV(val)) + +/* Alignment macros. */ +#define ALIGN4(p,base) ((p) + ((4 - (PTR_DIFF((p), (base)) & 3)) & 3)) +#define ALIGN2(p,base) ((p) + ((2 - (PTR_DIFF((p), (base)) & 1)) & 1)) + + +/* macros for accessing SMB protocol elements */ +#define VWV(vwv) ((vwv)*2) + +/* 64 bit macros */ +#define SBVAL(p, ofs, v) (SIVAL(p,ofs,(v)&0xFFFFFFFF), SIVAL(p,(ofs)+4,((uint64_t)(v))>>32)) +#define BVAL(p, ofs) (IVAL(p,ofs) | (((uint64_t)IVAL(p,(ofs)+4)) << 32)) + +#endif /* _BYTEORDER_H */ diff --git a/source4/lib/util/capability.c b/source4/lib/util/capability.c new file mode 100644 index 00000000000..0cebd333032 --- /dev/null +++ b/source4/lib/util/capability.c @@ -0,0 +1,112 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Jeremy Allison 1998-2002 + + 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. +*/ + +/* + capabilities fns - will be needed when we enable kernel oplocks +*/ + +#include "includes.h" +#include "system/network.h" +#include "system/wait.h" +#include "system/filesys.h" + + +#if defined(HAVE_IRIX_SPECIFIC_CAPABILITIES) +/************************************************************************** + Try and abstract process capabilities (for systems that have them). +****************************************************************************/ +static BOOL set_process_capability( uint32_t cap_flag, BOOL enable ) +{ + if(cap_flag == KERNEL_OPLOCK_CAPABILITY) { + cap_t cap = cap_get_proc(); + + if (cap == NULL) { + DEBUG(0,("set_process_capability: cap_get_proc failed. Error was %s\n", + strerror(errno))); + return False; + } + + if(enable) + cap->cap_effective |= CAP_NETWORK_MGT; + else + cap->cap_effective &= ~CAP_NETWORK_MGT; + + if (cap_set_proc(cap) == -1) { + DEBUG(0,("set_process_capability: cap_set_proc failed. Error was %s\n", + strerror(errno))); + cap_free(cap); + return False; + } + + cap_free(cap); + + DEBUG(10,("set_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n")); + } + return True; +} + +/************************************************************************** + Try and abstract inherited process capabilities (for systems that have them). +****************************************************************************/ + +static BOOL set_inherited_process_capability( uint32_t cap_flag, BOOL enable ) +{ + if(cap_flag == KERNEL_OPLOCK_CAPABILITY) { + cap_t cap = cap_get_proc(); + + if (cap == NULL) { + DEBUG(0,("set_inherited_process_capability: cap_get_proc failed. Error was %s\n", + strerror(errno))); + return False; + } + + if(enable) + cap->cap_inheritable |= CAP_NETWORK_MGT; + else + cap->cap_inheritable &= ~CAP_NETWORK_MGT; + + if (cap_set_proc(cap) == -1) { + DEBUG(0,("set_inherited_process_capability: cap_set_proc failed. Error was %s\n", + strerror(errno))); + cap_free(cap); + return False; + } + + cap_free(cap); + + DEBUG(10,("set_inherited_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n")); + } + return True; +} +#endif + +/**************************************************************************** + Gain the oplock capability from the kernel if possible. +****************************************************************************/ + +void oplock_set_capability(BOOL this_process, BOOL inherit) +{ +#if HAVE_KERNEL_OPLOCKS_IRIX + set_process_capability(KERNEL_OPLOCK_CAPABILITY,this_process); + set_inherited_process_capability(KERNEL_OPLOCK_CAPABILITY,inherit); +#endif +} + diff --git a/source4/lib/util/config.mk b/source4/lib/util/config.mk new file mode 100644 index 00000000000..79e145775d7 --- /dev/null +++ b/source4/lib/util/config.mk @@ -0,0 +1,34 @@ +[SUBSYSTEM::LIBBASIC] +PRIVATE_PROTO_HEADER = util_proto.h +PUBLIC_HEADERS = util.h +OBJ_FILES = xfile.o \ + debug.o \ + fault.o \ + signal.o \ + system.o \ + time.o \ + genrand.o \ + dprintf.o \ + util_str.o \ + util_strlist.o \ + util_unistr.o \ + util_file.o \ + data_blob.o \ + util.o \ + util_sock.o \ + substitute.o \ + fsusage.o \ + ms_fnmatch.o \ + select.o \ + mutex.o \ + idtree.o \ + module.o +REQUIRED_SUBSYSTEMS = \ + CHARSET LIBREPLACE LIBCRYPTO EXT_LIB_DL LIBTALLOC \ + SOCKET_WRAPPER CONFIG + +[SUBSYSTEM::PIDFILE] +OBJ_FILES = pidfile.o + +[SUBSYSTEM::UNIX_PRIVS] +OBJ_FILES = unix_privs.o diff --git a/source4/lib/util/data_blob.c b/source4/lib/util/data_blob.c new file mode 100644 index 00000000000..c6471fbf540 --- /dev/null +++ b/source4/lib/util/data_blob.c @@ -0,0 +1,209 @@ +/* + Unix SMB/CIFS implementation. + Easy management of byte-length data + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Andrew Bartlett 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 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. +*/ + +#include "includes.h" + +/******************************************************************* + construct a data blob, must be freed with data_blob_free() + you can pass NULL for p and get a blank data blob +*******************************************************************/ +DATA_BLOB data_blob_named(const void *p, size_t length, const char *name) +{ + DATA_BLOB ret; + + if (p == NULL && length == 0) { + ZERO_STRUCT(ret); + return ret; + } + + if (p) { + ret.data = talloc_memdup(NULL, p, length); + } else { + ret.data = talloc_size(NULL, length); + } + if (ret.data == NULL) { + ret.length = 0; + return ret; + } + talloc_set_name_const(ret.data, name); + ret.length = length; + return ret; +} + +/******************************************************************* + construct a data blob, using supplied TALLOC_CTX +*******************************************************************/ +DATA_BLOB data_blob_talloc_named(TALLOC_CTX *mem_ctx, const void *p, size_t length, const char *name) +{ + DATA_BLOB ret = data_blob_named(p, length, name); + + if (ret.data) { + talloc_steal(mem_ctx, ret.data); + } + return ret; +} + + +/******************************************************************* + reference a data blob, to the supplied TALLOC_CTX. + Returns a NULL DATA_BLOB on failure +*******************************************************************/ +DATA_BLOB data_blob_talloc_reference(TALLOC_CTX *mem_ctx, DATA_BLOB *blob) +{ + DATA_BLOB ret = *blob; + + ret.data = talloc_reference(mem_ctx, blob->data); + + if (!ret.data) { + return data_blob(NULL, 0); + } + return ret; +} + +/******************************************************************* + construct a zero data blob, using supplied TALLOC_CTX. + use this sparingly as it initialises data - better to initialise + yourself if you want specific data in the blob +*******************************************************************/ +DATA_BLOB data_blob_talloc_zero(TALLOC_CTX *mem_ctx, size_t length) +{ + DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, length); + data_blob_clear(&blob); + return blob; +} + +/******************************************************************* +free a data blob +*******************************************************************/ +void data_blob_free(DATA_BLOB *d) +{ + if (d) { + talloc_free(d->data); + d->data = NULL; + d->length = 0; + } +} + +/******************************************************************* +clear a DATA_BLOB's contents +*******************************************************************/ +void data_blob_clear(DATA_BLOB *d) +{ + if (d->data) { + memset(d->data, 0, d->length); + } +} + +/******************************************************************* +free a data blob and clear its contents +*******************************************************************/ +void data_blob_clear_free(DATA_BLOB *d) +{ + data_blob_clear(d); + data_blob_free(d); +} + + +/******************************************************************* +check if two data blobs are equal +*******************************************************************/ +BOOL data_blob_equal(const DATA_BLOB *d1, const DATA_BLOB *d2) +{ + if (d1->length != d2->length) { + return False; + } + if (d1->data == d2->data) { + return True; + } + if (d1->data == NULL || d2->data == NULL) { + return False; + } + if (memcmp(d1->data, d2->data, d1->length) == 0) { + return True; + } + return False; +} + +/******************************************************************* +print the data_blob as hex string +*******************************************************************/ +char *data_blob_hex_string(TALLOC_CTX *mem_ctx, DATA_BLOB *blob) +{ + int i; + char *hex_string; + + hex_string = talloc_array(mem_ctx, char, (blob->length*2)+1); + if (!hex_string) { + return NULL; + } + + for (i = 0; i < blob->length; i++) + slprintf(&hex_string[i*2], 3, "%02X", blob->data[i]); + + return hex_string; +} + +/* + useful for constructing data blobs in test suites, while + avoiding const warnings +*/ +DATA_BLOB data_blob_string_const(const char *str) +{ + DATA_BLOB blob; + blob.data = discard_const(str); + blob.length = strlen(str); + return blob; +} + +DATA_BLOB data_blob_const(const void *p, size_t length) +{ + DATA_BLOB blob; + blob.data = discard_const(p); + blob.length = length; + return blob; +} + + +/* + realloc a data_blob +*/ +NTSTATUS data_blob_realloc(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, size_t length) +{ + blob->data = talloc_realloc_size(mem_ctx, blob->data, length); + NT_STATUS_HAVE_NO_MEMORY(blob->data); + blob->length = length; + return NT_STATUS_OK; +} + +/* + append some data to a data blob +*/ +NTSTATUS data_blob_append(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, + const void *p, size_t length) +{ + blob->data = talloc_realloc_size(mem_ctx, blob->data, + blob->length + length); + NT_STATUS_HAVE_NO_MEMORY(blob->data); + memcpy(blob->data + blob->length, p, length); + blob->length += length; + return NT_STATUS_OK; +} + diff --git a/source4/lib/util/debug.c b/source4/lib/util/debug.c new file mode 100644 index 00000000000..9df6e573b09 --- /dev/null +++ b/source4/lib/util/debug.c @@ -0,0 +1,205 @@ +/* + Unix SMB/CIFS implementation. + Samba debug functions + Copyright (C) Andrew Tridgell 2003 + Copyright (C) James J Myers 2003 + + 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. +*/ + +#include "includes.h" +#include "system/filesys.h" +#include "system/time.h" +#include "dynconfig.h" + +/* this global variable determines what messages are printed */ +int DEBUGLEVEL; + + +/* the registered mutex handlers */ +static struct { + const char *name; + struct debug_ops ops; +} debug_handlers; + +/* state variables for the debug system */ +static struct { + int fd; + enum debug_logtype logtype; + const char *prog_name; +} state; + +/* + the backend for debug messages. Note that the DEBUG() macro has already + ensured that the log level has been met before this is called +*/ +void do_debug_header(int level, const char *location, const char *func) +{ + log_timestring(level, location, func); + log_task_id(); +} + +/* + the backend for debug messages. Note that the DEBUG() macro has already + ensured that the log level has been met before this is called +*/ +void do_debug(const char *format, ...) +{ + va_list ap; + char *s = NULL; + + if (state.fd == 0) { + reopen_logs(); + } + + if (state.fd <= 0) return; + + va_start(ap, format); + vasprintf(&s, format, ap); + va_end(ap); + + write(state.fd, s, strlen(s)); + free(s); +} + +/* + reopen the log file (usually called because the log file name might have changed) +*/ +void reopen_logs(void) +{ + const char *logfile = lp_logfile(); + char *fname = NULL; + int old_fd = state.fd; + + switch (state.logtype) { + case DEBUG_STDOUT: + state.fd = 1; + break; + + case DEBUG_STDERR: + state.fd = 2; + break; + + case DEBUG_FILE: + if ((*logfile) == '/') { + fname = strdup(logfile); + } else { + asprintf(&fname, "%s/%s.log", dyn_LOGFILEBASE, state.prog_name); + } + if (fname) { + int newfd = open(fname, O_CREAT|O_APPEND|O_WRONLY, 0600); + if (newfd == -1) { + DEBUG(1, ("Failed to open new logfile: %s\n", fname)); + } else { + state.fd = newfd; + } + free(fname); + } else { + DEBUG(1, ("Failed to find name for file-based logfile!\n")); + } + + break; + } + + if (old_fd > 2) { + close(old_fd); + } +} + +/* + control the name of the logfile and whether logging will be to stdout, stderr + or a file +*/ +void setup_logging(const char *prog_name, enum debug_logtype new_logtype) +{ + if (state.logtype < new_logtype) { + state.logtype = new_logtype; + } + if (prog_name) { + state.prog_name = prog_name; + } + reopen_logs(); +} + +/* + return a string constant containing n tabs + no more than 10 tabs are returned +*/ +const char *do_debug_tab(uint_t n) +{ + const char *tabs[] = {"", "\t", "\t\t", "\t\t\t", "\t\t\t\t", "\t\t\t\t\t", + "\t\t\t\t\t\t", "\t\t\t\t\t\t\t", "\t\t\t\t\t\t\t\t", + "\t\t\t\t\t\t\t\t\t", "\t\t\t\t\t\t\t\t\t\t"}; + return tabs[MIN(n, 10)]; +} + + +/* + log/print suspicious usage - print comments and backtrace +*/ +void log_suspicious_usage(const char *from, const char *info) +{ + if (debug_handlers.ops.log_suspicious_usage) { + debug_handlers.ops.log_suspicious_usage(from, info); + } +} +void print_suspicious_usage(const char* from, const char* info) +{ + if (debug_handlers.ops.print_suspicious_usage) { + debug_handlers.ops.print_suspicious_usage(from, info); + } +} + +void log_timestring(int level, const char *location, const char *func) +{ + char *t = NULL; + char *s = NULL; + + if (state.logtype != DEBUG_FILE) return; + + t = timestring(NULL, time(NULL)); + if (!t) return; + + asprintf(&s, "[%s, %d %s:%s()]\n", t, level, location, func); + talloc_free(t); + if (!s) return; + + write(state.fd, s, strlen(s)); + free(s); +} + +uint32_t get_task_id(void) +{ + if (debug_handlers.ops.get_task_id) { + return debug_handlers.ops.get_task_id(); + } + return getpid(); +} + +void log_task_id(void) +{ + if (debug_handlers.ops.log_task_id) { + debug_handlers.ops.log_task_id(state.fd); + } +} + +/* + register a set of debug handlers. +*/ +void register_debug_handlers(const char *name, struct debug_ops *ops) +{ + debug_handlers.name = name; + debug_handlers.ops = *ops; +} diff --git a/source4/lib/util/debug.h b/source4/lib/util/debug.h new file mode 100644 index 00000000000..8ff937e7b93 --- /dev/null +++ b/source4/lib/util/debug.h @@ -0,0 +1,66 @@ +/* + Unix SMB/CIFS implementation. + Samba debug defines + Copyright (C) Andrew Tridgell 2003 + + 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. +*/ + +/* If we have these macros, we can add additional info to the header. */ + +#ifdef HAVE_FUNCTION_MACRO +#define FUNCTION_MACRO (__FUNCTION__) +#else +#define FUNCTION_MACRO ("") +#endif + +/* the debug operations structure - contains function pointers to + various debug implementations of each operation */ +struct debug_ops { + /* function to log (using DEBUG) suspicious usage of data structure */ + void (*log_suspicious_usage)(const char* from, const char* info); + + /* function to log (using printf) suspicious usage of data structure. + * To be used in circumstances when using DEBUG would cause loop. */ + void (*print_suspicious_usage)(const char* from, const char* info); + + /* function to return process/thread id */ + uint32_t (*get_task_id)(void); + + /* function to log process/thread id */ + void (*log_task_id)(int fd); +}; + +void do_debug_header(int level, const char *location, const char *func); +void do_debug(const char *, ...) PRINTF_ATTRIBUTE(1,2); + +extern int DEBUGLEVEL; + +#define DEBUGLVL(level) ((level) <= DEBUGLEVEL) +#define _DEBUG(level, body, header) do { \ + if (DEBUGLVL(level)) { \ + if (header) { \ + do_debug_header(level, __location__, FUNCTION_MACRO); \ + } \ + do_debug body; \ + } \ +} while (0) +#define DEBUG(level, body) _DEBUG(level, body, True) +#define DEBUGADD(level, body) _DEBUG(level, body, False) +#define DEBUGC(class, level, body) DEBUG(level, body) +#define DEBUGADDC(class, level, body) DEBUGADD(level, body) +#define DEBUGTAB(n) do_debug_tab(n) + +enum debug_logtype {DEBUG_STDOUT = 0, DEBUG_FILE = 1, DEBUG_STDERR = 2}; diff --git a/source4/lib/util/dprintf.c b/source4/lib/util/dprintf.c new file mode 100644 index 00000000000..64227148fd9 --- /dev/null +++ b/source4/lib/util/dprintf.c @@ -0,0 +1,107 @@ +/* + Unix SMB/CIFS implementation. + display print functions + Copyright (C) Andrew Tridgell 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 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. +*/ + + +/* + this module provides functions for printing internal strings in the "display charset" + This charset may be quite different from the chosen unix charset + + Eventually these functions will need to take care of column count constraints + + The d_ prefix on print functions in Samba refers to the display character set + conversion +*/ + +#include "includes.h" + +int d_vfprintf(FILE *f, const char *format, va_list ap) _PRINTF_ATTRIBUTE(2,0) +{ + char *p, *p2; + int ret, maxlen, clen; + va_list ap2; + + /* do any message translations */ + VA_COPY(ap2, ap); + + ret = vasprintf(&p, format, ap2); + + if (ret <= 0) return ret; + + /* now we have the string in unix format, convert it to the display + charset, but beware of it growing */ + maxlen = ret*2; +again: + p2 = malloc(maxlen); + if (!p2) { + SAFE_FREE(p); + return -1; + } + clen = convert_string(CH_UNIX, CH_DISPLAY, p, ret, p2, maxlen); + + if (clen >= maxlen) { + /* it didn't fit - try a larger buffer */ + maxlen *= 2; + SAFE_FREE(p2); + goto again; + } + + /* good, its converted OK */ + SAFE_FREE(p); + ret = fwrite(p2, 1, clen, f); + SAFE_FREE(p2); + + return ret; +} + + +int d_fprintf(FILE *f, const char *format, ...) _PRINTF_ATTRIBUTE(2,3) +{ + int ret; + va_list ap; + + va_start(ap, format); + ret = d_vfprintf(f, format, ap); + va_end(ap); + + return ret; +} + +static FILE *outfile; + +int d_printf(const char *format, ...) _PRINTF_ATTRIBUTE(1,2) +{ + int ret; + va_list ap; + + if (!outfile) outfile = stdout; + + va_start(ap, format); + ret = d_vfprintf(outfile, format, ap); + va_end(ap); + + return ret; +} + +/* interactive programs need a way of tell d_*() to write to stderr instead + of stdout */ +void display_set_stderr(void) +{ + outfile = stderr; +} diff --git a/source4/lib/util/fault.c b/source4/lib/util/fault.c new file mode 100644 index 00000000000..3670575dcc7 --- /dev/null +++ b/source4/lib/util/fault.c @@ -0,0 +1,213 @@ +/* + Unix SMB/CIFS implementation. + Critical Fault handling + Copyright (C) Andrew Tridgell 1992-1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 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. +*/ + +#include "includes.h" +#include "version.h" +#include "system/wait.h" +#include "system/filesys.h" + +/* the registered fault handler */ +static struct { + const char *name; + void (*fault_handler)(int sig); +} fault_handlers; + +static const char *progname; + +#ifdef HAVE_BACKTRACE +#include +#define BACKTRACE_STACK_SIZE 64 +#elif HAVE_LIBEXC_H +#include +#endif + +void call_backtrace(void) +{ +#ifdef HAVE_BACKTRACE +#define BACKTRACE_STACK_SIZE 64 + void *backtrace_stack[BACKTRACE_STACK_SIZE]; + size_t backtrace_size; + char **backtrace_strings; + + /* get the backtrace (stack frames) */ + backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE); + backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size); + + DEBUG(0, ("BACKTRACE: %lu stack frames:\n", + (unsigned long)backtrace_size)); + + if (backtrace_strings) { + int i; + + for (i = 0; i < backtrace_size; i++) + DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i])); + + /* 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); + + for (i = 0; i < BACKTRACE_STACK_SIZE; i++) { + names[i] = namebuf + (i * NAMESIZE); + } + + levels = trace_back_stack(0, addrs, names, + BACKTRACE_STACK_SIZE, NAMESIZE); + + 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 +} + +/******************************************************************* + Something really nasty happened - panic ! +********************************************************************/ +void smb_panic(const char *why) +{ + const char *cmd = lp_panic_action(); + int result; + + if (cmd && *cmd) { + char pidstr[20]; + char cmdstring[200]; + safe_strcpy(cmdstring, cmd, sizeof(cmdstring)); + snprintf(pidstr, sizeof(pidstr), "%u", getpid()); + all_string_sub(cmdstring, "%PID%", pidstr, sizeof(cmdstring)); + if (progname) { + all_string_sub(cmdstring, "%PROG%", progname, sizeof(cmdstring)); + } + DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmdstring)); + result = system(cmdstring); + + if (result == -1) + DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n", + strerror(errno))); + else + DEBUG(0, ("smb_panic(): action returned status %d\n", + WEXITSTATUS(result))); + } + DEBUG(0,("PANIC: %s\n", why)); + + call_backtrace(); + +#ifdef SIGABRT + CatchSignal(SIGABRT,SIGNAL_CAST SIG_DFL); +#endif + abort(); +} + +/******************************************************************* +report a fault +********************************************************************/ +static void fault_report(int sig) +{ + static int counter; + + if (counter) _exit(1); + + DEBUG(0,("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n")); + DEBUG(0,("INTERNAL ERROR: Signal %d in pid %d (%s)",sig,(int)getpid(),SAMBA_VERSION_STRING)); + DEBUG(0,("\nPlease read the file BUGS.txt in the distribution\n")); + DEBUG(0,("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n")); + + smb_panic("internal error"); + + exit(1); +} + +/**************************************************************************** +catch serious errors +****************************************************************************/ +static void sig_fault(int sig) +{ + if (fault_handlers.fault_handler) { + /* we have a fault handler, call it. It may not return. */ + fault_handlers.fault_handler(sig); + } + /* If it returns or doean't exist, use regular reporter */ + fault_report(sig); +} + +/******************************************************************* +setup our fault handlers +********************************************************************/ +void fault_setup(const char *pname) +{ + if (progname == NULL) { + progname = pname; + } +#ifdef SIGSEGV + CatchSignal(SIGSEGV,SIGNAL_CAST sig_fault); +#endif +#ifdef SIGBUS + CatchSignal(SIGBUS,SIGNAL_CAST sig_fault); +#endif +#ifdef SIGABRT + CatchSignal(SIGABRT,SIGNAL_CAST sig_fault); +#endif +#ifdef SIGFPE + CatchSignal(SIGFPE,SIGNAL_CAST sig_fault); +#endif +} + +/* + register a fault handler. + Should only be called once in the execution of smbd. +*/ +BOOL register_fault_handler(const char *name, void (*fault_handler)(int sig)) +{ + if (fault_handlers.name != NULL) { + /* it's already registered! */ + DEBUG(2,("fault handler '%s' already registered - failed '%s'\n", + fault_handlers.name, name)); + return False; + } + + fault_handlers.name = name; + fault_handlers.fault_handler = fault_handler; + + DEBUG(2,("fault handler '%s' registered\n", name)); + return True; +} diff --git a/source4/lib/util/fsusage.c b/source4/lib/util/fsusage.c new file mode 100644 index 00000000000..f8176725447 --- /dev/null +++ b/source4/lib/util/fsusage.c @@ -0,0 +1,149 @@ +/* + Unix SMB/CIFS implementation. + functions to calculate the free disk space + Copyright (C) Andrew Tridgell 1998-2000 + + 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. +*/ + +#include "includes.h" +#include "system/filesys.h" + + +/* Return the number of TOSIZE-byte blocks used by + BLOCKS FROMSIZE-byte blocks, rounding away from zero. +*/ +static uint64_t adjust_blocks(uint64_t blocks, uint64_t fromsize, uint64_t tosize) +{ + if (fromsize == tosize) /* e.g., from 512 to 512 */ + return blocks; + else if (fromsize > tosize) /* e.g., from 2048 to 512 */ + return blocks * (fromsize / tosize); + else /* e.g., from 256 to 512 */ + return (blocks + 1) / (tosize / fromsize); +} + +/* this does all of the system specific guff to get the free disk space. + It is derived from code in the GNU fileutils package, but has been + considerably mangled for use here + + results are returned in *dfree and *dsize, in 512 byte units +*/ +int sys_fsusage(const char *path, uint64_t *dfree, uint64_t *dsize) +{ +#ifdef STAT_STATFS3_OSF1 +#define CONVERT_BLOCKS(B) adjust_blocks ((uint64_t)(B), (uint64_t)fsd.f_fsize, (uint64_t)512) + struct statfs fsd; + + if (statfs (path, &fsd, sizeof (struct statfs)) != 0) + return -1; +#endif /* STAT_STATFS3_OSF1 */ + +#ifdef STAT_STATFS2_FS_DATA /* Ultrix */ +#define CONVERT_BLOCKS(B) adjust_blocks ((uint64_t)(B), (uint64_t)1024, (uint64_t)512) + struct fs_data fsd; + + if (statfs (path, &fsd) != 1) + return -1; + + (*dsize) = CONVERT_BLOCKS (fsd.fd_req.btot); + (*dfree) = CONVERT_BLOCKS (fsd.fd_req.bfreen); +#endif /* STAT_STATFS2_FS_DATA */ + +#ifdef STAT_STATFS2_BSIZE /* 4.3BSD, SunOS 4, HP-UX, AIX */ +#define CONVERT_BLOCKS(B) adjust_blocks ((uint64_t)(B), (uint64_t)fsd.f_bsize, (uint64_t)512) + struct statfs fsd; + + if (statfs (path, &fsd) < 0) + return -1; + +#ifdef STATFS_TRUNCATES_BLOCK_COUNTS + /* In SunOS 4.1.2, 4.1.3, and 4.1.3_U1, the block counts in the + struct statfs are truncated to 2GB. These conditions detect that + truncation, presumably without botching the 4.1.1 case, in which + the values are not truncated. The correct counts are stored in + undocumented spare fields. */ + if (fsd.f_blocks == 0x1fffff && fsd.f_spare[0] > 0) { + fsd.f_blocks = fsd.f_spare[0]; + fsd.f_bfree = fsd.f_spare[1]; + fsd.f_bavail = fsd.f_spare[2]; + } +#endif /* STATFS_TRUNCATES_BLOCK_COUNTS */ +#endif /* STAT_STATFS2_BSIZE */ + + +#ifdef STAT_STATFS2_FSIZE /* 4.4BSD */ +#define CONVERT_BLOCKS(B) adjust_blocks ((uint64_t)(B), (uint64_t)fsd.f_fsize, (uint64_t)512) + + struct statfs fsd; + + if (statfs (path, &fsd) < 0) + return -1; +#endif /* STAT_STATFS2_FSIZE */ + +#ifdef STAT_STATFS4 /* SVR3, Dynix, Irix, AIX */ +# if _AIX || defined(_CRAY) +# define CONVERT_BLOCKS(B) adjust_blocks ((uint64_t)(B), (uint64_t)fsd.f_bsize, (uint64_t)512) +# ifdef _CRAY +# define f_bavail f_bfree +# endif +# else +# define CONVERT_BLOCKS(B) ((uint64_t)B) +# ifndef _SEQUENT_ /* _SEQUENT_ is DYNIX/ptx */ +# ifndef DOLPHIN /* DOLPHIN 3.8.alfa/7.18 has f_bavail */ +# define f_bavail f_bfree +# endif +# endif +# endif + + struct statfs fsd; + + if (statfs (path, &fsd, sizeof fsd, 0) < 0) + return -1; + /* Empirically, the block counts on most SVR3 and SVR3-derived + systems seem to always be in terms of 512-byte blocks, + no matter what value f_bsize has. */ + +#endif /* STAT_STATFS4 */ + +#if defined(STAT_STATVFS) || defined(STAT_STATVFS64) /* SVR4 */ +# define CONVERT_BLOCKS(B) \ + adjust_blocks ((uint64_t)(B), fsd.f_frsize ? (uint64_t)fsd.f_frsize : (uint64_t)fsd.f_bsize, (uint64_t)512) + +#ifdef STAT_STATVFS64 + struct statvfs64 fsd; + if (statvfs64(path, &fsd) < 0) return -1; +#else + struct statvfs fsd; + if (statvfs(path, &fsd) < 0) return -1; +#endif + + /* f_frsize isn't guaranteed to be supported. */ + +#endif /* STAT_STATVFS */ + +#ifndef CONVERT_BLOCKS + /* we don't have any dfree code! */ + return -1; +#else +#if !defined(STAT_STATFS2_FS_DATA) + /* !Ultrix */ + (*dsize) = CONVERT_BLOCKS (fsd.f_blocks); + (*dfree) = CONVERT_BLOCKS (fsd.f_bavail); +#endif /* not STAT_STATFS2_FS_DATA */ +#endif + + return 0; +} diff --git a/source4/lib/util/genrand.c b/source4/lib/util/genrand.c new file mode 100644 index 00000000000..1149314d0b4 --- /dev/null +++ b/source4/lib/util/genrand.c @@ -0,0 +1,314 @@ +/* + Unix SMB/CIFS implementation. + + Functions to create reasonable random numbers for crypto use. + + Copyright (C) Jeremy Allison 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 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. +*/ + +#include "includes.h" +#include "system/iconv.h" +#include "system/filesys.h" +#include "lib/crypto/crypto.h" + +static unsigned char hash[258]; +static uint32_t counter; + +static BOOL done_reseed = False; +static void (*reseed_callback)(int *newseed); + +/**************************************************************** + Copy any user given reseed data. +*****************************************************************/ + +void set_rand_reseed_callback(void (*fn)(int *)) +{ + reseed_callback = fn; + set_need_random_reseed(); +} + +void set_need_random_reseed(void) +{ + done_reseed = False; +} + +static void get_rand_reseed_data(int *reseed_data) +{ + if (reseed_callback) { + reseed_callback(reseed_data); + } else { + *reseed_data = 0; + } +} + +/**************************************************************** + Setup the seed. +*****************************************************************/ + +static void seed_random_stream(unsigned char *seedval, size_t seedlen) +{ + unsigned char j = 0; + size_t ind; + + for (ind = 0; ind < 256; ind++) + hash[ind] = (unsigned char)ind; + + for( ind = 0; ind < 256; ind++) { + unsigned char tc; + + j += (hash[ind] + seedval[ind%seedlen]); + + tc = hash[ind]; + hash[ind] = hash[j]; + hash[j] = tc; + } + + hash[256] = 0; + hash[257] = 0; +} + +/**************************************************************** + Get datasize bytes worth of random data. +*****************************************************************/ + +static void get_random_stream(unsigned char *data, size_t datasize) +{ + unsigned char index_i = hash[256]; + unsigned char index_j = hash[257]; + size_t ind; + + for( ind = 0; ind < datasize; ind++) { + unsigned char tc; + unsigned char t; + + index_i++; + index_j += hash[index_i]; + + tc = hash[index_i]; + hash[index_i] = hash[index_j]; + hash[index_j] = tc; + + t = hash[index_i] + hash[index_j]; + data[ind] = hash[t]; + } + + hash[256] = index_i; + hash[257] = index_j; +} + +/**************************************************************** + Get a 16 byte hash from the contents of a file. + + Note that the hash is initialised, because the extra entropy is not + worth the valgrind pain. +*****************************************************************/ + +static void do_filehash(const char *fname, unsigned char *the_hash) +{ + unsigned char buf[1011]; /* deliberate weird size */ + unsigned char tmp_md4[16]; + int fd, n; + + ZERO_STRUCT(tmp_md4); + + fd = open(fname,O_RDONLY,0); + if (fd == -1) + return; + + while ((n = read(fd, (char *)buf, sizeof(buf))) > 0) { + mdfour(tmp_md4, buf, n); + for (n=0;n<16;n++) + the_hash[n] ^= tmp_md4[n]; + } + close(fd); +} + +/************************************************************** + Try and get a good random number seed. Try a number of + different factors. Firstly, try /dev/urandom - use if exists. + + We use /dev/urandom as a read of /dev/random can block if + the entropy pool dries up. This leads clients to timeout + or be very slow on connect. + + If we can't use /dev/urandom then seed the stream random generator + above... +**************************************************************/ + +static int do_reseed(BOOL use_fd, int fd) +{ + unsigned char seed_inbuf[40]; + uint32_t v1, v2; struct timeval tval; pid_t mypid; + int reseed_data = 0; + + if (use_fd) { + if (fd != -1) + return fd; + + fd = open( "/dev/urandom", O_RDONLY,0); + if(fd >= 0) + return fd; + } + + /* Add in some secret file contents */ + + do_filehash("/etc/shadow", &seed_inbuf[0]); + + /* + * Add the counter, time of day, and pid. + */ + + GetTimeOfDay(&tval); + mypid = getpid(); + v1 = (counter++) + mypid + tval.tv_sec; + v2 = (counter++) * mypid + tval.tv_usec; + + SIVAL(seed_inbuf, 32, v1 ^ IVAL(seed_inbuf, 32)); + SIVAL(seed_inbuf, 36, v2 ^ IVAL(seed_inbuf, 36)); + + /* + * Add any user-given reseed data. + */ + + get_rand_reseed_data(&reseed_data); + if (reseed_data) { + size_t i; + for (i = 0; i < sizeof(seed_inbuf); i++) + seed_inbuf[i] ^= ((char *)(&reseed_data))[i % sizeof(reseed_data)]; + } + + seed_random_stream(seed_inbuf, sizeof(seed_inbuf)); + + return -1; +} + +/* + Interface to the (hopefully) good crypto random number generator. +*/ +void generate_random_buffer(uint8_t *out, int len) +{ + static int urand_fd = -1; + unsigned char md4_buf[64]; + unsigned char tmp_buf[16]; + unsigned char *p; + + if(!done_reseed) { + urand_fd = do_reseed(True, urand_fd); + done_reseed = True; + } + + if (urand_fd != -1 && len > 0) { + + if (read(urand_fd, out, len) == len) + return; /* len bytes of random data read from urandom. */ + + /* Read of urand error, drop back to non urand method. */ + close(urand_fd); + urand_fd = -1; + do_reseed(False, -1); + done_reseed = True; + } + + /* + * Generate random numbers in chunks of 64 bytes, + * then md4 them & copy to the output buffer. + * This way the raw state of the stream is never externally + * seen. + */ + + p = out; + while(len > 0) { + int copy_len = len > 16 ? 16 : len; + + get_random_stream(md4_buf, sizeof(md4_buf)); + mdfour(tmp_buf, md4_buf, sizeof(md4_buf)); + memcpy(p, tmp_buf, copy_len); + p += copy_len; + len -= copy_len; + } +} + +/* + generate a single random uint32_t +*/ +uint32_t generate_random(void) +{ + uint8_t v[4]; + generate_random_buffer(v, 4); + return IVAL(v, 0); +} + + +/* + very basic password quality checker +*/ +BOOL check_password_quality(const char *s) +{ + int has_digit=0, has_capital=0, has_lower=0; + while (*s) { + if (isdigit((unsigned char)*s)) { + has_digit++; + } else if (isupper((unsigned char)*s)) { + has_capital++; + } else if (islower((unsigned char)*s)) { + has_lower++; + } + s++; + } + + return has_digit && has_lower && has_capital; +} + +/******************************************************************* + Use the random number generator to generate a random string. +********************************************************************/ + +char *generate_random_str_list(TALLOC_CTX *mem_ctx, size_t len, const char *list) +{ + size_t i; + size_t list_len = strlen(list); + + char *retstr = talloc_array(mem_ctx, char, len + 1); + if (!retstr) return NULL; + + generate_random_buffer((uint8_t *)retstr, len); + for (i = 0; i < len; i++) { + retstr[i] = list[retstr[i] % list_len]; + } + retstr[i] = '\0'; + + return retstr; +} + +char *generate_random_str(TALLOC_CTX *mem_ctx, size_t len) +{ + char *retstr; + const char *c_list = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_-#.,"; + +again: + retstr = generate_random_str_list(mem_ctx, len, c_list); + if (!retstr) return NULL; + + /* we need to make sure the random string passes basic quality tests + or it might be rejected by windows as a password */ + if (len >= 7 && !check_password_quality(retstr)) { + talloc_free(retstr); + goto again; + } + + return retstr; +} diff --git a/source4/lib/util/idtree.c b/source4/lib/util/idtree.c new file mode 100644 index 00000000000..a67a80940a0 --- /dev/null +++ b/source4/lib/util/idtree.c @@ -0,0 +1,384 @@ +/* + Unix SMB/CIFS implementation. + + very efficient functions to manage mapping a id (such as a fnum) to + a pointer. This is used for fnum and search id allocation. + + Copyright (C) Andrew Tridgell 2004 + + This code is derived from lib/idr.c in the 2.6 Linux kernel, which was + written by Jim Houston jim.houston@ccur.com, and is + Copyright (C) 2002 by Concurrent Computer Corporation + + 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. +*/ + +/* + see the section marked "public interface" below for documentation +*/ + +#include "includes.h" + +#define IDR_BITS 5 +#define IDR_FULL 0xfffffffful +#define TOP_LEVEL_FULL (IDR_FULL >> 30) +#define IDR_SIZE (1 << IDR_BITS) +#define IDR_MASK ((1 << IDR_BITS)-1) +#define MAX_ID_SHIFT (sizeof(int)*8 - 1) +#define MAX_ID_BIT (1U << MAX_ID_SHIFT) +#define MAX_ID_MASK (MAX_ID_BIT - 1) +#define MAX_LEVEL (MAX_ID_SHIFT + IDR_BITS - 1) / IDR_BITS +#define IDR_FREE_MAX MAX_LEVEL + MAX_LEVEL + +#define set_bit(bit, v) (v) |= (1<<(bit)) +#define clear_bit(bit, v) (v) &= ~(1<<(bit)) +#define test_bit(bit, v) ((v) & (1<<(bit))) + +struct idr_layer { + uint32_t bitmap; + struct idr_layer *ary[IDR_SIZE]; + int count; +}; + +struct idr_context { + struct idr_layer *top; + struct idr_layer *id_free; + int layers; + int id_free_cnt; +}; + +static struct idr_layer *alloc_layer(struct idr_context *idp) +{ + struct idr_layer *p; + + if (!(p = idp->id_free)) + return NULL; + idp->id_free = p->ary[0]; + idp->id_free_cnt--; + p->ary[0] = NULL; + return p; +} + +static int find_next_bit(uint32_t bm, int maxid, int n) +{ + while (nary[0] = idp->id_free; + idp->id_free = p; + idp->id_free_cnt++; +} + +static int idr_pre_get(struct idr_context *idp) +{ + while (idp->id_free_cnt < IDR_FREE_MAX) { + struct idr_layer *new = talloc_zero(idp, struct idr_layer); + if(new == NULL) + return (0); + free_layer(idp, new); + } + return 1; +} + +static int sub_alloc(struct idr_context *idp, void *ptr, int *starting_id) +{ + int n, m, sh; + struct idr_layer *p, *new; + struct idr_layer *pa[MAX_LEVEL]; + int l, id; + uint32_t bm; + + id = *starting_id; + p = idp->top; + l = idp->layers; + pa[l--] = NULL; + while (1) { + /* + * We run around this while until we reach the leaf node... + */ + n = (id >> (IDR_BITS*l)) & IDR_MASK; + bm = ~p->bitmap; + m = find_next_bit(bm, IDR_SIZE, n); + if (m == IDR_SIZE) { + /* no space available go back to previous layer. */ + l++; + id = (id | ((1 << (IDR_BITS*l))-1)) + 1; + if (!(p = pa[l])) { + *starting_id = id; + return -2; + } + continue; + } + if (m != n) { + sh = IDR_BITS*l; + id = ((id >> sh) ^ n ^ m) << sh; + } + if ((id >= MAX_ID_BIT) || (id < 0)) + return -1; + if (l == 0) + break; + /* + * Create the layer below if it is missing. + */ + if (!p->ary[m]) { + if (!(new = alloc_layer(idp))) + return -1; + p->ary[m] = new; + p->count++; + } + pa[l--] = p; + p = p->ary[m]; + } + /* + * We have reached the leaf node, plant the + * users pointer and return the raw id. + */ + p->ary[m] = (struct idr_layer *)ptr; + set_bit(m, p->bitmap); + p->count++; + /* + * If this layer is full mark the bit in the layer above + * to show that this part of the radix tree is full. + * This may complete the layer above and require walking + * up the radix tree. + */ + n = id; + while (p->bitmap == IDR_FULL) { + if (!(p = pa[++l])) + break; + n = n >> IDR_BITS; + set_bit((n & IDR_MASK), p->bitmap); + } + return(id); +} + +static int idr_get_new_above_int(struct idr_context *idp, void *ptr, int starting_id) +{ + struct idr_layer *p, *new; + int layers, v, id; + + idr_pre_get(idp); + + id = starting_id; +build_up: + p = idp->top; + layers = idp->layers; + if (!p) { + if (!(p = alloc_layer(idp))) + return -1; + layers = 1; + } + /* + * Add a new layer to the top of the tree if the requested + * id is larger than the currently allocated space. + */ + while ((layers < MAX_LEVEL) && (id >= (1 << (layers*IDR_BITS)))) { + layers++; + if (!p->count) + continue; + if (!(new = alloc_layer(idp))) { + /* + * The allocation failed. If we built part of + * the structure tear it down. + */ + for (new = p; p && p != idp->top; new = p) { + p = p->ary[0]; + new->ary[0] = NULL; + new->bitmap = new->count = 0; + free_layer(idp, new); + } + return -1; + } + new->ary[0] = p; + new->count = 1; + if (p->bitmap == IDR_FULL) + set_bit(0, new->bitmap); + p = new; + } + idp->top = p; + idp->layers = layers; + v = sub_alloc(idp, ptr, &id); + if (v == -2) + goto build_up; + return(v); +} + +static int sub_remove(struct idr_context *idp, int shift, int id) +{ + struct idr_layer *p = idp->top; + struct idr_layer **pa[MAX_LEVEL]; + struct idr_layer ***paa = &pa[0]; + int n; + + *paa = NULL; + *++paa = &idp->top; + + while ((shift > 0) && p) { + n = (id >> shift) & IDR_MASK; + clear_bit(n, p->bitmap); + *++paa = &p->ary[n]; + p = p->ary[n]; + shift -= IDR_BITS; + } + n = id & IDR_MASK; + if (p != NULL && test_bit(n, p->bitmap)) { + clear_bit(n, p->bitmap); + p->ary[n] = NULL; + while(*paa && ! --((**paa)->count)){ + free_layer(idp, **paa); + **paa-- = NULL; + } + if ( ! *paa ) + idp->layers = 0; + return 0; + } + return -1; +} + +static void *_idr_find(struct idr_context *idp, int id) +{ + int n; + struct idr_layer *p; + + n = idp->layers * IDR_BITS; + p = idp->top; + /* + * This tests to see if bits outside the current tree are + * present. If so, tain't one of ours! + */ + if ((id & ~(~0 << MAX_ID_SHIFT)) >> (n + IDR_BITS)) + return NULL; + + /* Mask off upper bits we don't use for the search. */ + id &= MAX_ID_MASK; + + while (n > 0 && p) { + n -= IDR_BITS; + p = p->ary[(id >> n) & IDR_MASK]; + } + return((void *)p); +} + +static int _idr_remove(struct idr_context *idp, int id) +{ + struct idr_layer *p; + + /* Mask off upper bits we don't use for the search. */ + id &= MAX_ID_MASK; + + if (sub_remove(idp, (idp->layers - 1) * IDR_BITS, id) == -1) { + return -1; + } + + if ( idp->top && idp->top->count == 1 && + (idp->layers > 1) && + idp->top->ary[0]) { + /* We can drop a layer */ + p = idp->top->ary[0]; + idp->top->bitmap = idp->top->count = 0; + free_layer(idp, idp->top); + idp->top = p; + --idp->layers; + } + while (idp->id_free_cnt >= IDR_FREE_MAX) { + p = alloc_layer(idp); + talloc_free(p); + } + return 0; +} + +/************************************************************************ + this is the public interface +**************************************************************************/ + +/* + initialise a idr tree. The context return value must be passed to + all subsequent idr calls. To destroy the idr tree use talloc_free() + on this context + */ +struct idr_context *idr_init(TALLOC_CTX *mem_ctx) +{ + return talloc_zero(mem_ctx, struct idr_context); +} + +/* + allocate the next available id, and assign 'ptr' into its slot. + you can retrieve later this pointer using idr_find() +*/ +int idr_get_new(struct idr_context *idp, void *ptr, int limit) +{ + int ret = idr_get_new_above_int(idp, ptr, 0); + if (ret > limit) { + idr_remove(idp, ret); + return -1; + } + return ret; +} + +/* + allocate a new id, giving the first available value greater than or + equal to the given starting id +*/ +int idr_get_new_above(struct idr_context *idp, void *ptr, int starting_id, int limit) +{ + int ret = idr_get_new_above_int(idp, ptr, starting_id); + if (ret > limit) { + idr_remove(idp, ret); + return -1; + } + return ret; +} + +/* + allocate a new id randomly in the given range +*/ +int idr_get_new_random(struct idr_context *idp, void *ptr, int limit) +{ + int id; + + /* first try a random starting point in the whole range, and if that fails, + then start randomly in the bottom half of the range. This can only + fail if the range is over half full */ + id = idr_get_new_above(idp, ptr, 1+(generate_random() % limit), limit); + if (id == -1) { + id = idr_get_new_above(idp, ptr, 1+(generate_random()%(limit/2)), limit); + } + + return id; +} + +/* + find a pointer value previously set with idr_get_new given an id +*/ +void *idr_find(struct idr_context *idp, int id) +{ + return _idr_find(idp, id); +} + +/* + remove an id from the idr tree +*/ +int idr_remove(struct idr_context *idp, int id) +{ + int ret; + ret = _idr_remove((struct idr_context *)idp, id); + if (ret != 0) { + DEBUG(0,("WARNING: attempt to remove unset id %d in idtree\n", id)); + } + return ret; +} diff --git a/source4/lib/util/module.c b/source4/lib/util/module.c new file mode 100644 index 00000000000..672d8df7cef --- /dev/null +++ b/source4/lib/util/module.c @@ -0,0 +1,97 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Jelmer Vernooij 2005 + + 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. +*/ + +#include "includes.h" +#include "system/dir.h" + +static void *load_module(TALLOC_CTX *mem_ctx, const char *dir, const char *name) +{ + char *path; + void *handle; + void *init_fn; + + path = talloc_asprintf(mem_ctx, "%s/%s", dir, name); + + handle = dlopen(path, RTLD_NOW); + if (handle == NULL) { + DEBUG(0, ("Unable to open %s: %s\n", path, dlerror())); + talloc_free(path); + return NULL; + } + + init_fn = dlsym(handle, "init_module"); + + if (init_fn == NULL) { + DEBUG(0, ("Unable to find init_module() in %s: %s\n", path, dlerror())); + DEBUG(1, ("Loading module '%s' failed\n", path)); + dlclose(handle); + talloc_free(path); + return NULL; + } + + talloc_free(path); + + return init_fn; +} + +init_module_fn *load_modules(TALLOC_CTX *mem_ctx, const char *path) +{ + DIR *dir; + struct dirent *entry; + int success = 0; + init_module_fn *ret = talloc_array(mem_ctx, init_module_fn, 2); + + ret[0] = NULL; + + dir = opendir(path); + if (dir == NULL) { + talloc_free(ret); + return NULL; + } + + while((entry = readdir(dir))) { + if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) + continue; + + ret[success] = load_module(mem_ctx, path, entry->d_name); + if (ret[success]) { + ret = talloc_realloc(mem_ctx, ret, init_module_fn, success+2); + success++; + ret[success] = NULL; + } + } + + closedir(dir); + + return ret; +} + +BOOL run_init_functions(NTSTATUS (**fns) (void)) +{ + int i; + BOOL ret; + + if (fns == NULL) + return True; + + for (i = 0; fns[i]; i++) { ret &= NT_STATUS_IS_OK(fns[i]()); } + + return ret; +} diff --git a/source4/lib/util/ms_fnmatch.c b/source4/lib/util/ms_fnmatch.c new file mode 100644 index 00000000000..699341bede5 --- /dev/null +++ b/source4/lib/util/ms_fnmatch.c @@ -0,0 +1,219 @@ +/* + Unix SMB/CIFS implementation. + filename matching routine + Copyright (C) Andrew Tridgell 1992-2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 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. +*/ + +/* + This module was originally based on fnmatch.c copyright by the Free + Software Foundation. It bears little (if any) resemblence to that + code now +*/ + + +#include "includes.h" + +static int null_match(const char *p) +{ + for (;*p;p++) { + if (*p != '*' && + *p != '<' && + *p != '"' && + *p != '>') return -1; + } + return 0; +} + +/* + the max_n structure is purely for efficiency, it doesn't contribute + to the matching algorithm except by ensuring that the algorithm does + not grow exponentially +*/ +struct max_n { + const char *predot; + const char *postdot; +}; + + +/* + p and n are the pattern and string being matched. The max_n array is + an optimisation only. The ldot pointer is NULL if the string does + not contain a '.', otherwise it points at the last dot in 'n'. +*/ +static int ms_fnmatch_core(const char *p, const char *n, + struct max_n *max_n, const char *ldot) +{ + codepoint_t c, c2; + int i; + size_t size, size_n; + + while ((c = next_codepoint(p, &size))) { + p += size; + + switch (c) { + case '*': + /* a '*' matches zero or more characters of any type */ + if (max_n->predot && max_n->predot <= n) { + return null_match(p); + } + for (i=0; n[i]; i += size_n) { + next_codepoint(n+i, &size_n); + if (ms_fnmatch_core(p, n+i, max_n+1, ldot) == 0) { + return 0; + } + } + if (!max_n->predot || max_n->predot > n) max_n->predot = n; + return null_match(p); + + case '<': + /* a '<' matches zero or more characters of + any type, but stops matching at the last + '.' in the string. */ + if (max_n->predot && max_n->predot <= n) { + return null_match(p); + } + if (max_n->postdot && max_n->postdot <= n && n <= ldot) { + return -1; + } + for (i=0; n[i]; i += size_n) { + next_codepoint(n+i, &size_n); + if (ms_fnmatch_core(p, n+i, max_n+1, ldot) == 0) return 0; + if (n+i == ldot) { + if (ms_fnmatch_core(p, n+i+size_n, max_n+1, ldot) == 0) return 0; + if (!max_n->postdot || max_n->postdot > n) max_n->postdot = n; + return -1; + } + } + if (!max_n->predot || max_n->predot > n) max_n->predot = n; + return null_match(p); + + case '?': + /* a '?' matches any single character */ + if (! *n) { + return -1; + } + next_codepoint(n, &size_n); + n += size_n; + break; + + case '>': + /* a '?' matches any single character, but + treats '.' specially */ + if (n[0] == '.') { + if (! n[1] && null_match(p) == 0) { + return 0; + } + break; + } + if (! *n) return null_match(p); + next_codepoint(n, &size_n); + n += size_n; + break; + + case '"': + /* a bit like a soft '.' */ + if (*n == 0 && null_match(p) == 0) { + return 0; + } + if (*n != '.') return -1; + next_codepoint(n, &size_n); + n += size_n; + break; + + default: + c2 = next_codepoint(n, &size_n); + if (c != c2 && codepoint_cmpi(c, c2) != 0) { + return -1; + } + n += size_n; + break; + } + } + + if (! *n) { + return 0; + } + + return -1; +} + +int ms_fnmatch(const char *pattern, const char *string, enum protocol_types protocol) +{ + int ret, count, i; + struct max_n *max_n = NULL; + + if (strcmp(string, "..") == 0) { + string = "."; + } + + if (strpbrk(pattern, "<>*?\"") == NULL) { + /* this is not just an optmisation - it is essential + for LANMAN1 correctness */ + return strcasecmp_m(pattern, string); + } + + if (protocol <= PROTOCOL_LANMAN2) { + char *p = talloc_strdup(NULL, pattern); + if (p == NULL) { + return -1; + } + /* + for older negotiated protocols it is possible to + translate the pattern to produce a "new style" + pattern that exactly matches w2k behaviour + */ + for (i=0;p[i];i++) { + if (p[i] == '?') { + p[i] = '>'; + } else if (p[i] == '.' && + (p[i+1] == '?' || + p[i+1] == '*' || + p[i+1] == 0)) { + p[i] = '"'; + } else if (p[i] == '*' && + p[i+1] == '.') { + p[i] = '<'; + } + } + ret = ms_fnmatch(p, string, PROTOCOL_NT1); + talloc_free(p); + return ret; + } + + for (count=i=0;pattern[i];i++) { + if (pattern[i] == '*' || pattern[i] == '<') count++; + } + + max_n = talloc_array(NULL, struct max_n, count); + if (!max_n) { + return -1; + } + memset(max_n, 0, sizeof(struct max_n) * count); + + ret = ms_fnmatch_core(pattern, string, max_n, strrchr(string, '.')); + + talloc_free(max_n); + + return ret; +} + + +/* a generic fnmatch function - uses for non-CIFS pattern matching */ +int gen_fnmatch(const char *pattern, const char *string) +{ + return ms_fnmatch(pattern, string, PROTOCOL_NT1); +} diff --git a/source4/lib/util/mutex.c b/source4/lib/util/mutex.c new file mode 100644 index 00000000000..480ba92cc09 --- /dev/null +++ b/source4/lib/util/mutex.c @@ -0,0 +1,52 @@ +/* + Unix SMB/CIFS implementation. + Samba mutex/lock functions + Copyright (C) Andrew Tridgell 2003 + Copyright (C) James J Myers 2003 + + 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. +*/ +#include "includes.h" +#include "mutex.h" + +/* the registered mutex handlers */ +static struct { + const char *name; + struct mutex_ops ops; +} mutex_handlers; + +/* read/write lock routines */ + + +/* + register a set of mutex/rwlock handlers. + Should only be called once in the execution of smbd. +*/ +BOOL register_mutex_handlers(const char *name, struct mutex_ops *ops) +{ + if (mutex_handlers.name != NULL) { + /* it's already registered! */ + DEBUG(2,("mutex handler '%s' already registered - failed '%s'\n", + mutex_handlers.name, name)); + return False; + } + + mutex_handlers.name = name; + mutex_handlers.ops = *ops; + + DEBUG(2,("mutex handler '%s' registered\n", name)); + return True; +} + diff --git a/source4/lib/util/mutex.h b/source4/lib/util/mutex.h new file mode 100644 index 00000000000..018c134bcb8 --- /dev/null +++ b/source4/lib/util/mutex.h @@ -0,0 +1,71 @@ +#ifndef _MUTEX_H_ +#define _MUTEX_H_ +/* + Unix SMB/CIFS implementation. + Samba mutex functions + Copyright (C) Andrew Tridgell 2003 + Copyright (C) James J Myers 2003 + + 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. +*/ + +struct mutex_ops; + +/* To add a new read/write lock, add it to enum rwlock_id + */ +enum rwlock_id { RWLOCK_SMBD, /* global smbd lock */ + + RWLOCK_MAX /* this MUST be kept last */ +}; + +#define MUTEX_LOCK_BY_ID(mutex_index) smb_mutex_lock_by_id(mutex_index, #mutex_index) +#define MUTEX_UNLOCK_BY_ID(mutex_index) smb_mutex_unlock_by_id(mutex_index, #mutex_index) +#define MUTEX_INIT(mutex, name) smb_mutex_init(mutex, #name) +#define MUTEX_DESTROY(mutex, name) smb_mutex_destroy(mutex, #name) +#define MUTEX_LOCK(mutex, name) smb_mutex_lock(mutex, #name) +#define MUTEX_UNLOCK(mutex, name) smb_mutex_unlock(mutex, #name) + +#define RWLOCK_INIT(rwlock, name) smb_rwlock_init(rwlock, #name) +#define RWLOCK_DESTROY(rwlock, name) smb_rwlock_destroy(rwlock, #name) +#define RWLOCK_LOCK_WRITE(rwlock, name) smb_rwlock_lock_write(rwlock, #name) +#define RWLOCK_LOCK_READ(rwlock, name) smb_rwlock_lock_read(rwlock, #name) +#define RWLOCK_UNLOCK(rwlock, name) smb_rwlock_unlock(rwlock, #name) + + + +/* this null typedef ensures we get the types right and avoids the + pitfalls of void* */ +typedef struct smb_mutex { + void *mutex; +} smb_mutex_t; +typedef struct { + void *rwlock; +} smb_rwlock_t; + +/* the mutex model operations structure - contains function pointers to + the model-specific implementations of each operation */ +struct mutex_ops { + int (*mutex_init)(smb_mutex_t *mutex, const char *name); + int (*mutex_lock)(smb_mutex_t *mutex, const char *name); + int (*mutex_unlock)(smb_mutex_t *mutex, const char *name); + int (*mutex_destroy)(smb_mutex_t *mutex, const char *name); + int (*rwlock_init)(smb_rwlock_t *rwlock, const char *name); + int (*rwlock_lock_write)(smb_rwlock_t *rwlock, const char *name); + int (*rwlock_lock_read)(smb_rwlock_t *rwlock, const char *name); + int (*rwlock_unlock)(smb_rwlock_t *rwlock, const char *name); + int (*rwlock_destroy)(smb_rwlock_t *rwlock, const char *name); +}; + +#endif /* endif _MUTEX_H_ */ diff --git a/source4/lib/util/pidfile.c b/source4/lib/util/pidfile.c new file mode 100644 index 00000000000..9a7c197f700 --- /dev/null +++ b/source4/lib/util/pidfile.c @@ -0,0 +1,116 @@ +/* this code is broken - there is a race condition with the unlink (tridge) */ + +/* + Unix SMB/CIFS implementation. + pidfile handling + Copyright (C) Andrew Tridgell 1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 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. +*/ + +#include "includes.h" +#include "system/filesys.h" + +#ifndef O_NONBLOCK +#define O_NONBLOCK +#endif + +/* return the pid in a pidfile. return 0 if the process (or pidfile) + does not exist */ +pid_t pidfile_pid(const char *name) +{ + int fd; + char pidstr[20]; + uint_t ret; + char *pidFile; + + asprintf(&pidFile, "%s/%s.pid", lp_piddir(), name); + + fd = open(pidFile, O_NONBLOCK | O_RDONLY, 0644); + + if (fd == -1) { + SAFE_FREE(pidFile); + return 0; + } + + ZERO_STRUCT(pidstr); + + if (read(fd, pidstr, sizeof(pidstr)-1) <= 0) { + goto noproc; + } + + ret = atoi(pidstr); + + if (!process_exists((pid_t)ret)) { + goto noproc; + } + + if (fcntl_lock(fd,F_SETLK,0,1,F_RDLCK)) { + /* we could get the lock - it can't be a Samba process */ + goto noproc; + } + + close(fd); + SAFE_FREE(pidFile); + return (pid_t)ret; + + noproc: + close(fd); + unlink(pidFile); + SAFE_FREE(pidFile); + return 0; +} + +/* create a pid file in the pid directory. open it and leave it locked */ +void pidfile_create(const char *name) +{ + int fd; + char buf[20]; + char *pidFile; + pid_t pid; + + asprintf(&pidFile, "%s/%s.pid", lp_piddir(), name); + + pid = pidfile_pid(name); + if (pid != 0) { + DEBUG(0,("ERROR: %s is already running. File %s exists and process id %d is running.\n", + name, pidFile, (int)pid)); + exit(1); + } + + fd = open(pidFile, O_NONBLOCK | O_CREAT | O_WRONLY | O_EXCL, 0644); + if (fd == -1) { + DEBUG(0,("ERROR: can't open %s: Error was %s\n", pidFile, + strerror(errno))); + exit(1); + } + + if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False) { + DEBUG(0,("ERROR: %s : fcntl lock of file %s failed. Error was %s\n", + name, pidFile, strerror(errno))); + exit(1); + } + + memset(buf, 0, sizeof(buf)); + slprintf(buf, sizeof(buf) - 1, "%u\n", (uint_t) getpid()); + if (write(fd, buf, strlen(buf)) != (ssize_t)strlen(buf)) { + DEBUG(0,("ERROR: can't write to file %s: %s\n", + pidFile, strerror(errno))); + exit(1); + } + + /* Leave pid file open & locked for the duration... */ + SAFE_FREE(pidFile); +} diff --git a/source4/lib/util/safe_string.h b/source4/lib/util/safe_string.h new file mode 100644 index 00000000000..43e094467cc --- /dev/null +++ b/source4/lib/util/safe_string.h @@ -0,0 +1,55 @@ +/* + Unix SMB/CIFS implementation. + Safe string handling routines. + Copyright (C) Andrew Tridgell 1994-1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 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. +*/ + +#ifndef _SAFE_STRING_H +#define _SAFE_STRING_H + +#ifndef _SPLINT_ /* http://www.splint.org */ +/* Some macros to ensure people don't use buffer overflow vulnerable string + functions. */ + +#ifdef bcopy +#undef bcopy +#endif /* bcopy */ +#define bcopy(src,dest,size) __ERROR__XX__NEVER_USE_BCOPY___; + +#ifdef strcpy +#undef strcpy +#endif /* strcpy */ +#define strcpy(dest,src) __ERROR__XX__NEVER_USE_STRCPY___; + +#ifdef strcat +#undef strcat +#endif /* strcat */ +#define strcat(dest,src) __ERROR__XX__NEVER_USE_STRCAT___; + +#ifdef sprintf +#undef sprintf +#endif /* sprintf */ +#define sprintf __ERROR__XX__NEVER_USE_SPRINTF__; + +#endif /* !_SPLINT_ */ + +/* replace some string functions with multi-byte + versions */ +#define strlower(s) strlower_m(s) +#define strupper(s) strupper_m(s) + +#endif diff --git a/source4/lib/util/select.c b/source4/lib/util/select.c new file mode 100644 index 00000000000..a1b2e04065b --- /dev/null +++ b/source4/lib/util/select.c @@ -0,0 +1,169 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + Samba select/poll implementation + Copyright (C) Andrew Tridgell 1992-1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 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. +*/ + +#include "includes.h" +#include "system/filesys.h" + +/* This is here because it allows us to avoid a nasty race in signal handling. + We need to guarantee that when we get a signal we get out of a select immediately + but doing that involves a race condition. We can avoid the race by getting the + signal handler to write to a pipe that is in the select/poll list + + This means all Samba signal handlers should call sys_select_signal(). +*/ + +static pid_t initialised; +static int select_pipe[2]; +static VOLATILE unsigned pipe_written, pipe_read; + +/******************************************************************* + Call this from all Samba signal handlers if you want to avoid a + nasty signal race condition. +********************************************************************/ + +void sys_select_signal(void) +{ + char c = 1; + if (!initialised) return; + + if (pipe_written > pipe_read+256) return; + + if (write(select_pipe[1], &c, 1) == 1) pipe_written++; +} + +/******************************************************************* + Like select() but avoids the signal race using a pipe + it also guarantees that fds on return only ever contains bits set + for file descriptors that were readable. +********************************************************************/ + +int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval) +{ + int ret, saved_errno; + fd_set *readfds2, readfds_buf; + + if (initialised != getpid()) { + pipe(select_pipe); + + /* + * These next two lines seem to fix a bug with the Linux + * 2.0.x kernel (and probably other UNIXes as well) where + * the one byte read below can block even though the + * select returned that there is data in the pipe and + * the pipe_written variable was incremented. Thanks to + * HP for finding this one. JRA. + */ + + if(set_blocking(select_pipe[0],0)==-1) + smb_panic("select_pipe[0]: O_NONBLOCK failed.\n"); + if(set_blocking(select_pipe[1],0)==-1) + smb_panic("select_pipe[1]: O_NONBLOCK failed.\n"); + + initialised = getpid(); + } + + maxfd = MAX(select_pipe[0]+1, maxfd); + + /* If readfds is NULL we need to provide our own set. */ + if (readfds) { + readfds2 = readfds; + } else { + readfds2 = &readfds_buf; + FD_ZERO(readfds2); + } + FD_SET(select_pipe[0], readfds2); + + errno = 0; + ret = select(maxfd,readfds2,writefds,errorfds,tval); + + if (ret <= 0) { + FD_ZERO(readfds2); + if (writefds) + FD_ZERO(writefds); + if (errorfds) + FD_ZERO(errorfds); + } else if (FD_ISSET(select_pipe[0], readfds2)) { + char c; + saved_errno = errno; + if (read(select_pipe[0], &c, 1) == 1) { + pipe_read++; + /* Mark Weaver pointed out a critical + fix to ensure we don't lose signals. We must always + return -1 when the select pipe is set, otherwise if another + fd is also ready (so ret == 2) then we used to eat the + byte in the pipe and lose the signal. JRA. + */ + ret = -1; + errno = EINTR; + } else { + FD_CLR(select_pipe[0], readfds2); + ret--; + errno = saved_errno; + } + } + + return ret; +} + +/******************************************************************* + Similar to sys_select() but catch EINTR and continue. + This is what sys_select() used to do in Samba. +********************************************************************/ + +int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval) +{ + int ret; + fd_set *readfds2, readfds_buf, *writefds2, writefds_buf, *errorfds2, errorfds_buf; + struct timeval tval2, *ptval; + + readfds2 = (readfds ? &readfds_buf : NULL); + writefds2 = (writefds ? &writefds_buf : NULL); + errorfds2 = (errorfds ? &errorfds_buf : NULL); + ptval = (tval ? &tval2 : NULL); + + do { + if (readfds) + readfds_buf = *readfds; + if (writefds) + writefds_buf = *writefds; + if (errorfds) + errorfds_buf = *errorfds; + if (tval) + tval2 = *tval; + + /* We must use select and not sys_select here. If we use + sys_select we'd lose the fact a signal occurred when sys_select + read a byte from the pipe. Fix from Mark Weaver + + */ + + ret = select(maxfd, readfds2, writefds2, errorfds2, ptval); + } while (ret == -1 && errno == EINTR); + + if (readfds) + *readfds = readfds_buf; + if (writefds) + *writefds = writefds_buf; + if (errorfds) + *errorfds = errorfds_buf; + + return ret; +} diff --git a/source4/lib/util/signal.c b/source4/lib/util/signal.c new file mode 100644 index 00000000000..6c0bb4007a1 --- /dev/null +++ b/source4/lib/util/signal.c @@ -0,0 +1,140 @@ +/* + Unix SMB/CIFS implementation. + signal handling functions + + Copyright (C) Andrew Tridgell 1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 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. +*/ + +#include "includes.h" +#include "system/wait.h" + +/**************************************************************************** + Catch child exits and reap the child zombie status. +****************************************************************************/ + +static void sig_cld(int signum) +{ + while (waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0) + ; + + /* + * Turns out it's *really* important not to + * restore the signal handler here if we have real POSIX + * signal handling. If we do, then we get the signal re-delivered + * immediately - hey presto - instant loop ! JRA. + */ + +#if !defined(HAVE_SIGACTION) + CatchSignal(SIGCLD, sig_cld); +#endif +} + +/**************************************************************************** +catch child exits - leave status; +****************************************************************************/ + +static void sig_cld_leave_status(int signum) +{ + /* + * Turns out it's *really* important not to + * restore the signal handler here if we have real POSIX + * signal handling. If we do, then we get the signal re-delivered + * immediately - hey presto - instant loop ! JRA. + */ + +#if !defined(HAVE_SIGACTION) + CatchSignal(SIGCLD, sig_cld_leave_status); +#endif +} + +/******************************************************************* + Block sigs. +********************************************************************/ + +void BlockSignals(BOOL block,int signum) +{ +#ifdef HAVE_SIGPROCMASK + sigset_t set; + sigemptyset(&set); + sigaddset(&set,signum); + sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL); +#elif defined(HAVE_SIGBLOCK) + if (block) { + sigblock(sigmask(signum)); + } else { + sigsetmask(siggetmask() & ~sigmask(signum)); + } +#else + /* yikes! This platform can't block signals? */ + static int done; + if (!done) { + DEBUG(0,("WARNING: No signal blocking available\n")); + done=1; + } +#endif +} + +/******************************************************************* + Catch a signal. This should implement the following semantics: + + 1) The handler remains installed after being called. + 2) The signal should be blocked during handler execution. +********************************************************************/ + +void (*CatchSignal(int signum,void (*handler)(int )))(int) +{ +#ifdef HAVE_SIGACTION + struct sigaction act; + struct sigaction oldact; + + ZERO_STRUCT(act); + + act.sa_handler = handler; +#ifdef SA_RESTART + /* + * We *want* SIGALRM to interrupt a system call. + */ + if(signum != SIGALRM) + act.sa_flags = SA_RESTART; +#endif + sigemptyset(&act.sa_mask); + sigaddset(&act.sa_mask,signum); + sigaction(signum,&act,&oldact); + return oldact.sa_handler; +#else /* !HAVE_SIGACTION */ + /* FIXME: need to handle sigvec and systems with broken signal() */ + return signal(signum, handler); +#endif +} + +/******************************************************************* + Ignore SIGCLD via whatever means is necessary for this OS. +********************************************************************/ + +void CatchChild(void) +{ + CatchSignal(SIGCLD, sig_cld); +} + +/******************************************************************* + Catch SIGCLD but leave the child around so it's status can be reaped. +********************************************************************/ + +void CatchChildLeaveStatus(void) +{ + CatchSignal(SIGCLD, sig_cld_leave_status); +} diff --git a/source4/lib/util/substitute.c b/source4/lib/util/substitute.c new file mode 100644 index 00000000000..34a2ad9f82b --- /dev/null +++ b/source4/lib/util/substitute.c @@ -0,0 +1,165 @@ +/* + Unix SMB/CIFS implementation. + string substitution functions + Copyright (C) Andrew Tridgell 1992-2000 + + 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. +*/ + + +#include "includes.h" +#include "smb_server/smb_server.h" + +/* oh bugger - I really didn't want to have a top-level context + anywhere, but until we change all lp_*() calls to take a context + argument this is needed */ +static struct substitute_context *sub; + +void sub_set_context(struct substitute_context *subptr) +{ + sub = subptr; +} + +/* + setup a string in the negotiate structure, using alpha_strcpy with SAFE_NETBIOS_CHARS +*/ +static void setup_string(char **dest, const char *str) +{ +#define SAFE_NETBIOS_CHARS ". -_" + char *s; + + s = strdup(str); + if (!s) { + return; + } + + alpha_strcpy(s, str, SAFE_NETBIOS_CHARS, strlen(s)+1); + + trim_string(s," "," "); + strlower(s); + + SAFE_FREE(*dest); + (*dest) = s; +} + +void sub_set_remote_proto(const char *str) +{ + if (!sub) return; + setup_string(&sub->remote_proto, str); +} + +void sub_set_remote_arch(const char *str) +{ + if (!sub) return; + setup_string(&sub->remote_arch, str); +} + +/* + setup the string used by %U substitution +*/ +void sub_set_user_name(const char *name) +{ + if (!sub) return; + setup_string(&sub->user_name, name); +} + +/**************************************************************************** +FOO +****************************************************************************/ +void standard_sub_basic(char *str,size_t len) +{ +} + +/**************************************************************************** + Do some standard substitutions in a string. + This function will return an allocated string that have to be freed. +****************************************************************************/ +char *talloc_sub_basic(TALLOC_CTX *mem_ctx, const char *smb_name, const char *str) +{ + return talloc_strdup(mem_ctx, str); +} + +char *alloc_sub_basic(const char *smb_name, const char *str) +{ + return strdup(str); +} + +/**************************************************************************** + Do some specific substitutions in a string. + This function will return an allocated string that have to be freed. +****************************************************************************/ + +char *talloc_sub_specified(TALLOC_CTX *mem_ctx, + const char *input_string, + const char *username, + const char *domain, + uid_t uid, + gid_t gid) +{ + return talloc_strdup(mem_ctx, input_string); +} + +char *alloc_sub_specified(const char *input_string, + const char *username, + const char *domain, + uid_t uid, + gid_t gid) +{ + return strdup(input_string); +} + +char *talloc_sub_advanced(TALLOC_CTX *mem_ctx, + int snum, + const char *user, + const char *connectpath, + gid_t gid, + const char *smb_name, + char *str) +{ + return talloc_strdup(mem_ctx, str); +} + +char *alloc_sub_advanced(int snum, const char *user, + const char *connectpath, gid_t gid, + const char *smb_name, char *str) +{ + return strdup(str); +} + +/**************************************************************************** + Do some standard substitutions in a string. +****************************************************************************/ + +void standard_sub_tcon(struct smbsrv_tcon *tcon, char *str, size_t len) +{ +} + +char *talloc_sub_tcon(TALLOC_CTX *mem_ctx, struct smbsrv_tcon *tcon, char *str) +{ + return talloc_strdup(mem_ctx, str); +} + +char *alloc_sub_tcon(struct smbsrv_tcon *tcon, char *str) +{ + return strdup(str); +} + +/**************************************************************************** + Like standard_sub but by snum. +****************************************************************************/ + +void standard_sub_snum(int snum, char *str, size_t len) +{ +} diff --git a/source4/lib/util/system.c b/source4/lib/util/system.c new file mode 100644 index 00000000000..655b4a1054f --- /dev/null +++ b/source4/lib/util/system.c @@ -0,0 +1,98 @@ +/* + Unix SMB/CIFS implementation. + Samba system utilities + Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Jeremy Allison 1998-2002 + + 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. +*/ + +#include "includes.h" +#include "system/network.h" +#include "system/filesys.h" + +/* + The idea is that this file will eventually have wrappers around all + important system calls in samba. The aims are: + + - to enable easier porting by putting OS dependent stuff in here + + - to allow for hooks into other "pseudo-filesystems" + + - to allow easier integration of things like the japanese extensions + + - to support the philosophy of Samba to expose the features of + the OS within the SMB model. In general whatever file/printer/variable + expansions/etc make sense to the OS should be acceptable to Samba. +*/ + +/************************************************************************** +A wrapper for gethostbyname() that tries avoids looking up hostnames +in the root domain, which can cause dial-on-demand links to come up for no +apparent reason. +****************************************************************************/ + +struct hostent *sys_gethostbyname(const char *name) +{ +#ifdef REDUCE_ROOT_DNS_LOOKUPS + char query[256], hostname[256]; + char *domain; + + /* Does this name have any dots in it? If so, make no change */ + + if (strchr_m(name, '.')) + return(gethostbyname(name)); + + /* Get my hostname, which should have domain name + attached. If not, just do the gethostname on the + original string. + */ + + gethostname(hostname, sizeof(hostname) - 1); + hostname[sizeof(hostname) - 1] = 0; + if ((domain = strchr_m(hostname, '.')) == NULL) + return(gethostbyname(name)); + + /* Attach domain name to query and do modified query. + If names too large, just do gethostname on the + original string. + */ + + if((strlen(name) + strlen(domain)) >= sizeof(query)) + return(gethostbyname(name)); + + slprintf(query, sizeof(query)-1, "%s%s", name, domain); + return(gethostbyname(query)); +#else /* REDUCE_ROOT_DNS_LOOKUPS */ + return(gethostbyname(name)); +#endif /* REDUCE_ROOT_DNS_LOOKUPS */ +} + +const char *sys_inet_ntoa(struct ipv4_addr in) +{ + struct in_addr in2; + in2.s_addr = in.addr; + return inet_ntoa(in2); +} + +struct ipv4_addr sys_inet_makeaddr(int net, int host) +{ + struct in_addr in; + struct ipv4_addr in2; + in = inet_makeaddr(net, host); + in2.addr = in.s_addr; + return in2; +} + diff --git a/source4/lib/util/time.c b/source4/lib/util/time.c new file mode 100644 index 00000000000..7721a2c456c --- /dev/null +++ b/source4/lib/util/time.c @@ -0,0 +1,596 @@ +/* + Unix SMB/CIFS implementation. + time handling functions + + Copyright (C) Andrew Tridgell 1992-2004 + Copyright (C) Stefan (metze) Metzmacher 2002 + + 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. +*/ + +#include "includes.h" +#include "system/time.h" + +#ifndef TIME_T_MIN +/* we use 0 here, because (time_t)-1 means error */ +#define TIME_T_MIN 0 +#endif + +/* + * we use the INT32_MAX here as on 64 bit systems, + * gmtime() fails with INT64_MAX + */ + +#ifndef TIME_T_MAX +#define TIME_T_MAX MIN(INT32_MAX,_TYPE_MAXIMUM(time_t)) +#endif + +/******************************************************************* + External access to time_t_min and time_t_max. +********************************************************************/ +time_t get_time_t_max(void) +{ + return TIME_T_MAX; +} + +/******************************************************************* +a gettimeofday wrapper +********************************************************************/ +void GetTimeOfDay(struct timeval *tval) +{ +#ifdef HAVE_GETTIMEOFDAY_TZ + gettimeofday(tval,NULL); +#else + gettimeofday(tval); +#endif +} + + +#define TIME_FIXUP_CONSTANT 11644473600LL + +/**************************************************************************** +interpret an 8 byte "filetime" structure to a time_t +It's originally in "100ns units since jan 1st 1601" +****************************************************************************/ +time_t nt_time_to_unix(NTTIME nt) +{ + if (nt == 0) { + return 0; + } + if (nt == -1LL) { + return (time_t)-1; + } + nt += 1000*1000*10/2; + nt /= 1000*1000*10; + nt -= TIME_FIXUP_CONSTANT; + + if (TIME_T_MIN > nt || nt > TIME_T_MAX) { + return 0; + } + + return (time_t)nt; +} + + +/**************************************************************************** +put a 8 byte filetime from a time_t +This takes GMT as input +****************************************************************************/ +void unix_to_nt_time(NTTIME *nt, time_t t) +{ + uint64_t t2; + + if (t == (time_t)-1) { + *nt = (NTTIME)-1LL; + return; + } + if (t == 0) { + *nt = 0; + return; + } + + t2 = t; + t2 += TIME_FIXUP_CONSTANT; + t2 *= 1000*1000*10; + + *nt = t2; +} + + +/**************************************************************************** +check if it's a null unix time +****************************************************************************/ +BOOL null_time(time_t t) +{ + return t == 0 || + t == (time_t)0xFFFFFFFF || + t == (time_t)-1; +} + + +/**************************************************************************** +check if it's a null NTTIME +****************************************************************************/ +BOOL null_nttime(NTTIME t) +{ + return t == 0 || t == (NTTIME)-1; +} + +/******************************************************************* + create a 16 bit dos packed date +********************************************************************/ +static uint16_t make_dos_date1(struct tm *t) +{ + uint16_t ret=0; + ret = (((uint_t)(t->tm_mon+1)) >> 3) | ((t->tm_year-80) << 1); + ret = ((ret&0xFF)<<8) | (t->tm_mday | (((t->tm_mon+1) & 0x7) << 5)); + return ret; +} + +/******************************************************************* + create a 16 bit dos packed time +********************************************************************/ +static uint16_t make_dos_time1(struct tm *t) +{ + uint16_t ret=0; + ret = ((((uint_t)t->tm_min >> 3)&0x7) | (((uint_t)t->tm_hour) << 3)); + ret = ((ret&0xFF)<<8) | ((t->tm_sec/2) | ((t->tm_min & 0x7) << 5)); + return ret; +} + +/******************************************************************* + create a 32 bit dos packed date/time from some parameters + This takes a GMT time and returns a packed localtime structure +********************************************************************/ +static uint32_t make_dos_date(time_t unixdate, int zone_offset) +{ + struct tm *t; + uint32_t ret=0; + + if (unixdate == 0) { + return 0; + } + + unixdate -= zone_offset; + + t = gmtime(&unixdate); + if (!t) { + return 0xFFFFFFFF; + } + + ret = make_dos_date1(t); + ret = ((ret&0xFFFF)<<16) | make_dos_time1(t); + + return ret; +} + +/******************************************************************* +put a dos date into a buffer (time/date format) +This takes GMT time and puts local time in the buffer +********************************************************************/ +void push_dos_date(uint8_t *buf, int offset, time_t unixdate, int zone_offset) +{ + uint32_t x = make_dos_date(unixdate, zone_offset); + SIVAL(buf,offset,x); +} + +/******************************************************************* +put a dos date into a buffer (date/time format) +This takes GMT time and puts local time in the buffer +********************************************************************/ +void push_dos_date2(uint8_t *buf,int offset,time_t unixdate, int zone_offset) +{ + uint32_t x; + x = make_dos_date(unixdate, zone_offset); + x = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16); + SIVAL(buf,offset,x); +} + +/******************************************************************* +put a dos 32 bit "unix like" date into a buffer. This routine takes +GMT and converts it to LOCAL time before putting it (most SMBs assume +localtime for this sort of date) +********************************************************************/ +void push_dos_date3(uint8_t *buf,int offset,time_t unixdate, int zone_offset) +{ + if (!null_time(unixdate)) { + unixdate -= zone_offset; + } + SIVAL(buf,offset,unixdate); +} + +/******************************************************************* + interpret a 32 bit dos packed date/time to some parameters +********************************************************************/ +static void interpret_dos_date(uint32_t date,int *year,int *month,int *day,int *hour,int *minute,int *second) +{ + uint32_t p0,p1,p2,p3; + + p0=date&0xFF; p1=((date&0xFF00)>>8)&0xFF; + p2=((date&0xFF0000)>>16)&0xFF; p3=((date&0xFF000000)>>24)&0xFF; + + *second = 2*(p0 & 0x1F); + *minute = ((p0>>5)&0xFF) + ((p1&0x7)<<3); + *hour = (p1>>3)&0xFF; + *day = (p2&0x1F); + *month = ((p2>>5)&0xFF) + ((p3&0x1)<<3) - 1; + *year = ((p3>>1)&0xFF) + 80; +} + +/******************************************************************* + create a unix date (int GMT) from a dos date (which is actually in + localtime) +********************************************************************/ +time_t pull_dos_date(const uint8_t *date_ptr, int zone_offset) +{ + uint32_t dos_date=0; + struct tm t; + time_t ret; + + dos_date = IVAL(date_ptr,0); + + if (dos_date == 0) return (time_t)0; + + interpret_dos_date(dos_date,&t.tm_year,&t.tm_mon, + &t.tm_mday,&t.tm_hour,&t.tm_min,&t.tm_sec); + t.tm_isdst = -1; + + ret = timegm(&t); + + ret += zone_offset; + + return ret; +} + +/******************************************************************* +like make_unix_date() but the words are reversed +********************************************************************/ +time_t pull_dos_date2(const uint8_t *date_ptr, int zone_offset) +{ + uint32_t x,x2; + + x = IVAL(date_ptr,0); + x2 = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16); + SIVAL(&x,0,x2); + + return pull_dos_date((void *)&x, zone_offset); +} + +/******************************************************************* + create a unix GMT date from a dos date in 32 bit "unix like" format + these generally arrive as localtimes, with corresponding DST + ******************************************************************/ +time_t pull_dos_date3(const uint8_t *date_ptr, int zone_offset) +{ + time_t t = (time_t)IVAL(date_ptr,0); + if (!null_time(t)) { + t += zone_offset; + } + return t; +} + + +/*************************************************************************** +return a HTTP/1.0 time string + ***************************************************************************/ +char *http_timestring(TALLOC_CTX *mem_ctx, time_t t) +{ + char *buf; + char tempTime[60]; + struct tm *tm = localtime(&t); + + if (!tm) { + return talloc_asprintf(mem_ctx,"%ld seconds since the Epoch",(long)t); + } + +#ifndef HAVE_STRFTIME + buf = talloc_strdup(mem_ctx, asctime(tm)); + if (buf[strlen(buf)-1] == '\n') { + buf[strlen(buf)-1] = 0; + } +#else + strftime(tempTime, sizeof(tempTime)-1, "%a, %d %b %Y %H:%M:%S %Z", tm); + buf = talloc_strdup(mem_ctx, tempTime); +#endif /* !HAVE_STRFTIME */ + + return buf; +} + +/**************************************************************************** + Return the date and time as a string +****************************************************************************/ +char *timestring(TALLOC_CTX *mem_ctx, time_t t) +{ + char *TimeBuf; + char tempTime[80]; + struct tm *tm; + + tm = localtime(&t); + if (!tm) { + return talloc_asprintf(mem_ctx, + "%ld seconds since the Epoch", + (long)t); + } + +#ifdef HAVE_STRFTIME + /* some versions of gcc complain about using %c. This is a bug + in the gcc warning, not a bug in this code. See a recent + strftime() manual page for details. + */ + strftime(tempTime,sizeof(tempTime)-1,"%c %Z",tm); + TimeBuf = talloc_strdup(mem_ctx, tempTime); +#else + TimeBuf = talloc_strdup(mem_ctx, asctime(tm)); +#endif + + return TimeBuf; +} + +/* + return a talloced string representing a NTTIME for human consumption +*/ +const char *nt_time_string(TALLOC_CTX *mem_ctx, NTTIME nt) +{ + time_t t; + if (nt == 0) { + return "NTTIME(0)"; + } + t = nt_time_to_unix(nt); + return timestring(mem_ctx, t); +} + + +/* + put a NTTIME into a packet +*/ +void push_nttime(uint8_t *base, uint16_t offset, NTTIME t) +{ + SBVAL(base, offset, t); +} + +/* + pull a NTTIME from a packet +*/ +NTTIME pull_nttime(uint8_t *base, uint16_t offset) +{ + NTTIME ret = BVAL(base, offset); + return ret; +} + +/* + parse a nttime as a large integer in a string and return a NTTIME +*/ +NTTIME nttime_from_string(const char *s) +{ + return strtoull(s, NULL, 0); +} + +/* + return (tv1 - tv2) in microseconds +*/ +int64_t usec_time_diff(struct timeval *tv1, struct timeval *tv2) +{ + int64_t sec_diff = tv1->tv_sec - tv2->tv_sec; + return (sec_diff * 1000000) + (int64_t)(tv1->tv_usec - tv2->tv_usec); +} + + +/* + return a zero timeval +*/ +struct timeval timeval_zero(void) +{ + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 0; + return tv; +} + +/* + return True if a timeval is zero +*/ +BOOL timeval_is_zero(const struct timeval *tv) +{ + return tv->tv_sec == 0 && tv->tv_usec == 0; +} + +/* + return a timeval for the current time +*/ +struct timeval timeval_current(void) +{ + struct timeval tv; + GetTimeOfDay(&tv); + return tv; +} + +/* + return a timeval struct with the given elements +*/ +struct timeval timeval_set(uint32_t secs, uint32_t usecs) +{ + struct timeval tv; + tv.tv_sec = secs; + tv.tv_usec = usecs; + return tv; +} + + +/* + return a timeval ofs microseconds after tv +*/ +struct timeval timeval_add(const struct timeval *tv, + uint32_t secs, uint32_t usecs) +{ + struct timeval tv2 = *tv; + const uint_t million = 1000000; + tv2.tv_sec += secs; + tv2.tv_usec += usecs; + tv2.tv_sec += tv2.tv_usec / million; + tv2.tv_usec = tv2.tv_usec % million; + return tv2; +} + +/* + return the sum of two timeval structures +*/ +struct timeval timeval_sum(const struct timeval *tv1, + const struct timeval *tv2) +{ + return timeval_add(tv1, tv2->tv_sec, tv2->tv_usec); +} + +/* + return a timeval secs/usecs into the future +*/ +struct timeval timeval_current_ofs(uint32_t secs, uint32_t usecs) +{ + struct timeval tv = timeval_current(); + return timeval_add(&tv, secs, usecs); +} + +/* + compare two timeval structures. + Return -1 if tv1 < tv2 + Return 0 if tv1 == tv2 + Return 1 if tv1 > tv2 +*/ +int timeval_compare(const struct timeval *tv1, const struct timeval *tv2) +{ + if (tv1->tv_sec > tv2->tv_sec) return 1; + if (tv1->tv_sec < tv2->tv_sec) return -1; + if (tv1->tv_usec > tv2->tv_usec) return 1; + if (tv1->tv_usec < tv2->tv_usec) return -1; + return 0; +} + +/* + return True if a timer is in the past +*/ +BOOL timeval_expired(const struct timeval *tv) +{ + struct timeval tv2 = timeval_current(); + if (tv2.tv_sec > tv->tv_sec) return True; + if (tv2.tv_sec < tv->tv_sec) return False; + return (tv2.tv_usec >= tv->tv_usec); +} + +/* + return the number of seconds elapsed between two times +*/ +double timeval_elapsed2(const struct timeval *tv1, const struct timeval *tv2) +{ + return (tv2->tv_sec - tv1->tv_sec) + + (tv2->tv_usec - tv1->tv_usec)*1.0e-6; +} + +/* + return the number of seconds elapsed since a given time +*/ +double timeval_elapsed(const struct timeval *tv) +{ + struct timeval tv2 = timeval_current(); + return timeval_elapsed2(tv, &tv2); +} + +/* + return the lesser of two timevals +*/ +struct timeval timeval_min(const struct timeval *tv1, + const struct timeval *tv2) +{ + if (tv1->tv_sec < tv2->tv_sec) return *tv1; + if (tv1->tv_sec > tv2->tv_sec) return *tv2; + if (tv1->tv_usec < tv2->tv_usec) return *tv1; + return *tv2; +} + +/* + return the greater of two timevals +*/ +struct timeval timeval_max(const struct timeval *tv1, + const struct timeval *tv2) +{ + if (tv1->tv_sec > tv2->tv_sec) return *tv1; + if (tv1->tv_sec < tv2->tv_sec) return *tv2; + if (tv1->tv_usec > tv2->tv_usec) return *tv1; + return *tv2; +} + +/* + return the difference between two timevals as a timeval + if tv1 comes after tv2, then return a zero timeval + (this is *tv2 - *tv1) +*/ +struct timeval timeval_until(const struct timeval *tv1, + const struct timeval *tv2) +{ + struct timeval t; + if (timeval_compare(tv1, tv2) >= 0) { + return timeval_zero(); + } + t.tv_sec = tv2->tv_sec - tv1->tv_sec; + if (tv1->tv_usec > tv2->tv_usec) { + t.tv_sec--; + t.tv_usec = 1000000 - (tv1->tv_usec - tv2->tv_usec); + } else { + t.tv_usec = tv2->tv_usec - tv1->tv_usec; + } + return t; +} + + +/* + convert a timeval to a NTTIME +*/ +NTTIME timeval_to_nttime(const struct timeval *tv) +{ + return 10*(tv->tv_usec + + ((TIME_FIXUP_CONSTANT + (uint64_t)tv->tv_sec) * 1000000)); +} + +/******************************************************************* +yield the difference between *A and *B, in seconds, ignoring leap seconds +********************************************************************/ +static int tm_diff(struct tm *a, struct tm *b) +{ + int ay = a->tm_year + (1900 - 1); + int by = b->tm_year + (1900 - 1); + int intervening_leap_days = + (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400); + int years = ay - by; + int days = 365*years + intervening_leap_days + (a->tm_yday - b->tm_yday); + int hours = 24*days + (a->tm_hour - b->tm_hour); + int minutes = 60*hours + (a->tm_min - b->tm_min); + int seconds = 60*minutes + (a->tm_sec - b->tm_sec); + + return seconds; +} + +/******************************************************************* + return the UTC offset in seconds west of UTC, or 0 if it cannot be determined + ******************************************************************/ +int get_time_zone(time_t t) +{ + struct tm *tm = gmtime(&t); + struct tm tm_utc; + if (!tm) + return 0; + tm_utc = *tm; + tm = localtime(&t); + if (!tm) + return 0; + return tm_diff(&tm_utc,tm); +} diff --git a/source4/lib/util/unix_privs.c b/source4/lib/util/unix_privs.c new file mode 100644 index 00000000000..3c0f3197767 --- /dev/null +++ b/source4/lib/util/unix_privs.c @@ -0,0 +1,68 @@ +/* + Unix SMB/CIFS implementation. + + gain/lose root privileges + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 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. +*/ + +#include "includes.h" +#include "system/filesys.h" + +/* + there are times when smbd needs to temporarily gain root privileges + to do some operation. To do this you call root_privileges(), which + returns a talloc handle. To restore your previous privileges + talloc_free() this pointer. + + Note that this call is considered successful even if it does not + manage to gain root privileges, but it will call smb_abort() if it + fails to restore the privileges afterwards. The logic is that + failing to gain root access can be caught by whatever operation + needs to be run as root failing, but failing to lose the root + privileges is dangerous. + + This also means that this code is safe to be called from completely + unprivileged processes. +*/ + +struct saved_state { + uid_t uid; +}; + +static int privileges_destructor(void *ptr) +{ + struct saved_state *s = ptr; + if (geteuid() != s->uid && + seteuid(s->uid) != 0) { + smb_panic("Failed to restore privileges"); + } + return 0; +} + +void *root_privileges(void) +{ + struct saved_state *s; + s = talloc(NULL, struct saved_state); + if (!s) return NULL; + s->uid = geteuid(); + if (s->uid != 0) { + seteuid(0); + } + talloc_set_destructor(s, privileges_destructor); + return s; +} diff --git a/source4/lib/util/util.c b/source4/lib/util/util.c new file mode 100644 index 00000000000..17dde332e1a --- /dev/null +++ b/source4/lib/util/util.c @@ -0,0 +1,737 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Jeremy Allison 2001-2002 + Copyright (C) Simo Sorce 2001 + Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003. + Copyright (C) James J Myers 2003 + + 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. +*/ + +#include "includes.h" +#include "dynconfig.h" +#include "system/network.h" +#include "system/iconv.h" +#include "system/filesys.h" + +/*************************************************************************** + Find a suitable temporary directory. The result should be copied immediately + as it may be overwritten by a subsequent call. +****************************************************************************/ +const char *tmpdir(void) +{ + char *p; + if ((p = getenv("TMPDIR"))) + return p; + return "/tmp"; +} + + +/******************************************************************* + Check if a file exists - call vfs_file_exist for samba files. +********************************************************************/ +BOOL file_exist(const char *fname) +{ + struct stat st; + + if (stat(fname, &st) != 0) { + return False; + } + + return ((S_ISREG(st.st_mode)) || (S_ISFIFO(st.st_mode))); +} + +/******************************************************************* + Check a files mod time. +********************************************************************/ + +time_t file_modtime(const char *fname) +{ + struct stat st; + + if (stat(fname,&st) != 0) + return(0); + + return(st.st_mtime); +} + +/******************************************************************* + Check if a directory exists. +********************************************************************/ + +BOOL directory_exist(const char *dname) +{ + struct stat st; + BOOL ret; + + if (stat(dname,&st) != 0) { + return False; + } + + ret = S_ISDIR(st.st_mode); + if(!ret) + errno = ENOTDIR; + return ret; +} + +BOOL directory_create_or_exist(const char *dname, uid_t uid, + mode_t dir_perms) +{ + mode_t old_umask; + struct stat st; + + old_umask = umask(0); + if (lstat(dname, &st) == -1) { + if (errno == ENOENT) { + /* Create directory */ + if (mkdir(dname, dir_perms) == -1) { + DEBUG(0, ("error creating directory " + "%s: %s\n", dname, + strerror(errno))); + umask(old_umask); + return False; + } + } else { + DEBUG(0, ("lstat failed on directory %s: %s\n", + dname, strerror(errno))); + umask(old_umask); + return False; + } + } else { + /* Check ownership and permission on existing directory */ + if (!S_ISDIR(st.st_mode)) { + DEBUG(0, ("directory %s isn't a directory\n", + dname)); + umask(old_umask); + return False; + } + if ((st.st_uid != uid) || + ((st.st_mode & 0777) != dir_perms)) { + DEBUG(0, ("invalid permissions on directory " + "%s\n", dname)); + umask(old_umask); + return False; + } + } + return True; +} + + +/******************************************************************* + Close the low 3 fd's and open dev/null in their place. +********************************************************************/ +static void close_low_fds(BOOL stderr_too) +{ +#ifndef VALGRIND + int fd; + int i; + + close(0); + close(1); + + if (stderr_too) + close(2); + + /* try and use up these file descriptors, so silly + library routines writing to stdout etc won't cause havoc */ + for (i=0;i<3;i++) { + if (i == 2 && !stderr_too) + continue; + + fd = open("/dev/null",O_RDWR,0); + if (fd < 0) + fd = open("/dev/null",O_WRONLY,0); + if (fd < 0) { + DEBUG(0,("Can't open /dev/null\n")); + return; + } + if (fd != i) { + DEBUG(0,("Didn't get file descriptor %d\n",i)); + return; + } + } +#endif +} + +/**************************************************************************** + Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available, + else + if SYSV use O_NDELAY + if BSD use FNDELAY +****************************************************************************/ + +int set_blocking(int fd, BOOL set) +{ + int val; +#ifdef O_NONBLOCK +#define FLAG_TO_SET O_NONBLOCK +#else +#ifdef SYSV +#define FLAG_TO_SET O_NDELAY +#else /* BSD */ +#define FLAG_TO_SET FNDELAY +#endif +#endif + + if((val = fcntl(fd, F_GETFL, 0)) == -1) + return -1; + if(set) /* Turn blocking on - ie. clear nonblock flag */ + val &= ~FLAG_TO_SET; + else + val |= FLAG_TO_SET; + return fcntl( fd, F_SETFL, val); +#undef FLAG_TO_SET +} + + +/******************************************************************* + Sleep for a specified number of milliseconds. +********************************************************************/ + +void msleep(uint_t t) +{ + struct timeval tval; + + tval.tv_sec = t/1000; + tval.tv_usec = 1000*(t%1000); + /* this should be the real select - do NOT replace + with sys_select() */ + select(0,NULL,NULL,NULL,&tval); +} + +/**************************************************************************** + Become a daemon, discarding the controlling terminal. +****************************************************************************/ + +void become_daemon(BOOL Fork) +{ + if (Fork) { + if (fork()) { + _exit(0); + } + } + + /* detach from the terminal */ +#ifdef HAVE_SETSID + setsid(); +#elif defined(TIOCNOTTY) + { + int i = open("/dev/tty", O_RDWR, 0); + if (i != -1) { + ioctl(i, (int) TIOCNOTTY, (char *)0); + close(i); + } + } +#endif /* HAVE_SETSID */ + + /* Close fd's 0,1,2. Needed if started by rsh */ + close_low_fds(False); /* Don't close stderr, let the debug system + attach it to the logfile */ +} + + +/**************************************************************************** + Free memory, checks for NULL. + Use directly SAFE_FREE() + Exists only because we need to pass a function pointer somewhere --SSS +****************************************************************************/ + +void safe_free(void *p) +{ + SAFE_FREE(p); +} + + +/* + see if a string matches either our primary or one of our secondary + netbios aliases. do a case insensitive match +*/ +BOOL is_myname(const char *name) +{ + const char **aliases; + int i; + + if (strcasecmp(name, lp_netbios_name()) == 0) { + return True; + } + + aliases = lp_netbios_aliases(); + for (i=0; aliases && aliases[i]; i++) { + if (strcasecmp(name, aliases[i]) == 0) { + return True; + } + } + + return False; +} + + +/**************************************************************************** + Get my own name, return in malloc'ed storage. +****************************************************************************/ + +char* get_myname(void) +{ + char *hostname; + const int host_name_max = 255; + char *p; + + hostname = malloc(host_name_max+1); + *hostname = 0; + + /* get my host name */ + if (gethostname(hostname, host_name_max+1) == -1) { + DEBUG(0,("gethostname failed\n")); + return NULL; + } + + /* Ensure null termination. */ + hostname[host_name_max] = '\0'; + + /* split off any parts after an initial . */ + p = strchr_m(hostname,'.'); + + if (p) + *p = 0; + + return hostname; +} + +/**************************************************************************** + Return true if a string could be a pure IP address. +****************************************************************************/ + +BOOL is_ipaddress(const char *str) +{ + BOOL pure_address = True; + int i; + + for (i=0; pure_address && str[i]; i++) + if (!(isdigit((int)str[i]) || str[i] == '.')) + pure_address = False; + + /* Check that a pure number is not misinterpreted as an IP */ + pure_address = pure_address && (strchr_m(str, '.') != NULL); + + return pure_address; +} + +/**************************************************************************** + Interpret an internet address or name into an IP address in 4 byte form. +****************************************************************************/ +uint32_t interpret_addr(const char *str) +{ + struct hostent *hp; + uint32_t res; + + if (str == NULL || *str == 0 || + strcmp(str,"0.0.0.0") == 0) { + return 0; + } + if (strcmp(str,"255.255.255.255") == 0) { + return 0xFFFFFFFF; + } + /* recognise 'localhost' as a special name. This fixes problems with + some hosts that don't have localhost in /etc/hosts */ + if (strcasecmp(str,"localhost") == 0) { + str = "127.0.0.1"; + } + + /* if it's in the form of an IP address then get the lib to interpret it */ + if (is_ipaddress(str)) { + res = inet_addr(str); + } else { + /* otherwise assume it's a network name of some sort and use + sys_gethostbyname */ + if ((hp = sys_gethostbyname(str)) == 0) { + DEBUG(3,("sys_gethostbyname: Unknown host. %s\n",str)); + return 0; + } + + if(hp->h_addr == NULL) { + DEBUG(3,("sys_gethostbyname: host address is invalid for host %s\n",str)); + return 0; + } + memcpy((char *)&res,(char *)hp->h_addr, 4); + } + + if (res == (uint32_t)-1) + return(0); + + return(res); +} + +/******************************************************************* + A convenient addition to interpret_addr(). +******************************************************************/ +struct ipv4_addr interpret_addr2(const char *str) +{ + struct ipv4_addr ret; + uint32_t a = interpret_addr(str); + ret.addr = a; + return ret; +} + +/******************************************************************* + Check if an IP is the 0.0.0.0. +******************************************************************/ + +BOOL is_zero_ip(struct ipv4_addr ip) +{ + return ip.addr == 0; +} + +/******************************************************************* + Are two IPs on the same subnet? +********************************************************************/ + +BOOL same_net(struct ipv4_addr ip1,struct ipv4_addr ip2,struct ipv4_addr mask) +{ + uint32_t net1,net2,nmask; + + nmask = ntohl(mask.addr); + net1 = ntohl(ip1.addr); + net2 = ntohl(ip2.addr); + + return((net1 & nmask) == (net2 & nmask)); +} + + +/**************************************************************************** + Check if a process exists. Does this work on all unixes? +****************************************************************************/ + +BOOL process_exists(pid_t pid) +{ + /* 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); +} + +/**************************************************************************** + Simple routine to do POSIX file locking. Cruft in NFS and 64->32 bit mapping + is dealt with in posix.c +****************************************************************************/ + +BOOL fcntl_lock(int fd, int op, off_t offset, off_t count, int type) +{ + struct flock lock; + int ret; + + DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type)); + + lock.l_type = type; + lock.l_whence = SEEK_SET; + lock.l_start = offset; + lock.l_len = count; + lock.l_pid = 0; + + ret = fcntl(fd,op,&lock); + + if (ret == -1 && errno != 0) + DEBUG(3,("fcntl_lock: fcntl lock gave errno %d (%s)\n",errno,strerror(errno))); + + /* a lock query */ + if (op == F_GETLK) { + if ((ret != -1) && + (lock.l_type != F_UNLCK) && + (lock.l_pid != 0) && + (lock.l_pid != getpid())) { + DEBUG(3,("fcntl_lock: fd %d is locked by pid %d\n",fd,(int)lock.l_pid)); + return(True); + } + + /* it must be not locked or locked by me */ + return(False); + } + + /* a lock set or unset */ + if (ret == -1) { + DEBUG(3,("fcntl_lock: lock failed at offset %.0f count %.0f op %d type %d (%s)\n", + (double)offset,(double)count,op,type,strerror(errno))); + return(False); + } + + /* everything went OK */ + DEBUG(8,("fcntl_lock: Lock call successful\n")); + + return(True); +} + + +static void print_asc(int level, const uint8_t *buf,int len) +{ + int i; + for (i=0;i8) DEBUGADD(level,(" ")); + while (n--) DEBUGADD(level,(" ")); + n = MIN(8,i%16); + print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,( " " )); + n = (i%16) - n; + if (n>0) print_asc(level,&buf[i-n],n); + DEBUGADD(level,("\n")); + } +} + +/***************************************************************** + malloc that aborts with smb_panic on fail or zero size. + *****************************************************************/ + +void *smb_xmalloc(size_t size) +{ + void *p; + if (size == 0) + smb_panic("smb_xmalloc: called with zero size.\n"); + if ((p = malloc(size)) == NULL) + smb_panic("smb_xmalloc: malloc fail.\n"); + return p; +} + +/** + Memdup with smb_panic on fail. +**/ + +void *smb_xmemdup(const void *p, size_t size) +{ + void *p2; + p2 = smb_xmalloc(size); + memcpy(p2, p, size); + return p2; +} + +/** + strdup that aborts on malloc fail. +**/ + +char *smb_xstrdup(const char *s) +{ + char *s1 = strdup(s); + if (!s1) + smb_panic("smb_xstrdup: malloc fail\n"); + return s1; +} + + +/***************************************************************** + Like strdup but for memory. +*****************************************************************/ + +void *memdup(const void *p, size_t size) +{ + void *p2; + if (size == 0) + return NULL; + p2 = malloc(size); + if (!p2) + return NULL; + memcpy(p2, p, size); + return p2; +} + +/***************************************************************** + A useful function for returning a path in the Samba lock directory. +*****************************************************************/ +char *lock_path(TALLOC_CTX* mem_ctx, const char *name) +{ + char *fname, *dname; + if (name == NULL) { + return NULL; + } + if (name[0] == 0 || name[0] == '/' || strstr(name, ":/")) { + return talloc_strdup(mem_ctx, name); + } + + dname = talloc_strdup(mem_ctx, lp_lockdir()); + trim_string(dname,"","/"); + + if (!directory_exist(dname)) { + mkdir(dname,0755); + } + + fname = talloc_asprintf(mem_ctx, "%s/%s", dname, name); + + talloc_free(dname); + + return fname; +} + + +/***************************************************************** + A useful function for returning a path in the Samba piddir directory. +*****************************************************************/ +static char *pid_path(TALLOC_CTX* mem_ctx, const char *name) +{ + char *fname, *dname; + + dname = talloc_strdup(mem_ctx, lp_piddir()); + trim_string(dname,"","/"); + + if (!directory_exist(dname)) { + mkdir(dname,0755); + } + + fname = talloc_asprintf(mem_ctx, "%s/%s", dname, name); + + talloc_free(dname); + + return fname; +} + + +/** + * @brief Returns an absolute path to a file in the Samba lib directory. + * + * @param name File to find, relative to LIBDIR. + * + * @retval Pointer to a talloc'ed string containing the full path. + **/ + +char *lib_path(TALLOC_CTX* mem_ctx, const char *name) +{ + char *fname; + fname = talloc_asprintf(mem_ctx, "%s/%s", dyn_LIBDIR, name); + return fname; +} + +/** + * @brief Returns an absolute path to a file in the Samba private directory. + * + * @param name File to find, relative to PRIVATEDIR. + * if name is not relative, then use it as-is + * + * @retval Pointer to a talloc'ed string containing the full path. + **/ +char *private_path(TALLOC_CTX* mem_ctx, const char *name) +{ + char *fname; + if (name == NULL) { + return NULL; + } + if (name[0] == 0 || name[0] == '/' || strstr(name, ":/")) { + return talloc_strdup(mem_ctx, name); + } + fname = talloc_asprintf(mem_ctx, "%s/%s", lp_private_dir(), name); + return fname; +} + +/* + return a path in the smbd.tmp directory, where all temporary file + for smbd go. If NULL is passed for name then return the directory + path itself +*/ +char *smbd_tmp_path(TALLOC_CTX *mem_ctx, const char *name) +{ + char *fname, *dname; + + dname = pid_path(mem_ctx, "smbd.tmp"); + if (!directory_exist(dname)) { + mkdir(dname,0755); + } + + if (name == NULL) { + return dname; + } + + fname = talloc_asprintf(mem_ctx, "%s/%s", dname, name); + talloc_free(dname); + + return fname; +} + +static char *modules_path(TALLOC_CTX* mem_ctx, const char *name) +{ + return talloc_asprintf(mem_ctx, "%s/%s", dyn_MODULESDIR, name); +} + +init_module_fn *load_samba_modules(TALLOC_CTX *mem_ctx, const char *subsystem) +{ + char *path = modules_path(mem_ctx, subsystem); + init_module_fn *ret; + + ret = load_modules(mem_ctx, path); + + talloc_free(path); + + return ret; +} + +void dump_data_pw(const char *msg, const uint8_t * data, size_t len) +{ +#ifdef DEBUG_PASSWORD + DEBUG(11, ("%s", msg)); + if (data != NULL && len > 0) + { + dump_data(11, data, len); + } +#endif +} + + +/* see if a range of memory is all zero. A NULL pointer is considered + to be all zero */ +BOOL all_zero(const uint8_t *ptr, uint_t size) +{ + int i; + if (!ptr) return True; + for (i=0;i= MAX_MALLOC_SIZE/el_size) { + return NULL; + } + if (!ptr) { + return malloc(el_size * count); + } + return realloc(ptr, el_size * count); +} + diff --git a/source4/lib/util/util.h b/source4/lib/util/util.h new file mode 100644 index 00000000000..55d775e25c6 --- /dev/null +++ b/source4/lib/util/util.h @@ -0,0 +1,81 @@ +/* + Unix SMB/CIFS implementation. + Utility functions for Samba + Copyright (C) Andrew Tridgell 1992-1999 + Copyright (C) John H Terpstra 1996-1999 + Copyright (C) Luke Kenneth Casson Leighton 1996-1999 + Copyright (C) Paul Ashton 1998 - 1999 + + 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. +*/ + +#ifndef _SAMBA_UTIL_H_ +#define _SAMBA_UTIL_H_ + +struct substitute_context; + +#include "util/xfile.h" +#include "util/debug.h" +#include "util/mutex.h" +#include "util/byteorder.h" +#include "util/util_proto.h" + +/* zero a structure */ +#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x)) + +/* zero a structure given a pointer to the structure */ +#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0) + +/* zero a structure given a pointer to the structure - no zero check */ +#define ZERO_STRUCTPN(x) memset((char *)(x), 0, sizeof(*(x))) + +/* pointer difference macro */ +#define PTR_DIFF(p1,p2) ((ptrdiff_t)(((const char *)(p1)) - (const char *)(p2))) + +/* work out how many elements there are in a static array */ +#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) + +/* assert macros */ +#define SMB_ASSERT(b) do { if (!(b)) { \ + DEBUG(0,("PANIC: assert failed at %s(%d)\n", __FILE__, __LINE__)); \ + smb_panic("assert failed"); }} while (0) + +#ifndef MIN +#define MIN(a,b) ((a)<(b)?(a):(b)) +#endif + +#ifndef MAX +#define MAX(a,b) ((a)>(b)?(a):(b)) +#endif + +#ifndef ABS +#define ABS(a) ((a)>0?(a):(-(a))) +#endif + +#ifndef SAFE_FREE /* Oh no this is also defined in tdb.h */ +/** + * Free memory if the pointer and zero the pointer. + * + * @note You are explicitly allowed to pass NULL pointers -- they will + * always be ignored. + **/ +#define SAFE_FREE(x) do { if ((x) != NULL) {free(discard_const_p(void *, (x))); (x)=NULL;} } while(0) +#endif + +#define malloc_p(type) (type *)malloc(sizeof(type)) +#define malloc_array_p(type, count) (type *)realloc_array(NULL, sizeof(type), count) +#define realloc_p(p, type, count) (type *)realloc_array(p, sizeof(type), count) + +#endif /* _SAMBA_UTIL_H_ */ diff --git a/source4/lib/util/util_file.c b/source4/lib/util/util_file.c new file mode 100644 index 00000000000..246b03b4aa4 --- /dev/null +++ b/source4/lib/util/util_file.c @@ -0,0 +1,385 @@ +/* + * Unix SMB/CIFS implementation. + * SMB parameters and setup + * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995. + * + * Added afdgets() Jelmer Vernooij 2005 + * + * 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. + */ + +#include "includes.h" +#include "system/shmem.h" +#include "system/filesys.h" + +/**************************************************************************** +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; + + maxlen *= 2; + t = realloc_p(s, char, maxlen); + if (!t) { + DEBUG(0,("fgets_slash: failed to expand buffer!\n")); + SAFE_FREE(s); + return(NULL); + } else s = t; + } + } + return(s); +} + +/* Read one line (data until next newline or eof) and allocate it */ +char *afdgets(int fd, TALLOC_CTX *mem_ctx, size_t hint) +{ + char *data = NULL; + ssize_t alloc_size = 0, offset = 0, ret; + int p; + + if (hint <= 0) hint = 0x100; + + do { + alloc_size += hint; + + data = talloc_realloc(mem_ctx, data, char, alloc_size); + + if (!data) + return NULL; + + ret = read(fd, data + offset, hint); + + if (ret == -1) { + talloc_free(data); + return NULL; + } + + /* Find newline */ + for (p = 0; p < ret; p++) { + if (data[offset + p] == '\n') + break; + } + + if (p < ret) { + data[offset + p] = '\0'; + + /* Go back to position of newline */ + lseek(fd, p - ret + 1, SEEK_CUR); + return data; + } + + offset += ret; + + } while (ret == hint); + + data[offset] = '\0'; + + return data; +} + + +/**************************************************************************** +load a file into memory from a fd. +****************************************************************************/ + +char *fd_load(int fd, size_t *size, TALLOC_CTX *mem_ctx) +{ + struct stat sbuf; + char *p; + + if (fstat(fd, &sbuf) != 0) return NULL; + + p = (char *)talloc_size(mem_ctx, sbuf.st_size+1); + if (!p) return NULL; + + if (read(fd, p, sbuf.st_size) != sbuf.st_size) { + talloc_free(p); + return NULL; + } + p[sbuf.st_size] = 0; + + if (size) *size = sbuf.st_size; + + return p; +} + +/**************************************************************************** +load a file into memory +****************************************************************************/ +char *file_load(const char *fname, size_t *size, TALLOC_CTX *mem_ctx) +{ + int fd; + char *p; + + if (!fname || !*fname) return NULL; + + fd = open(fname,O_RDONLY); + if (fd == -1) return NULL; + + p = fd_load(fd, size, mem_ctx); + + close(fd); + + return p; +} + + +/******************************************************************* +mmap (if possible) or read a file +********************************************************************/ +void *map_file(const char *fname, size_t size) +{ + size_t s2 = 0; + void *p = NULL; +#ifdef HAVE_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; + } +#endif + if (!p) { + p = file_load(fname, &s2, talloc_autofree_context()); + if (!p) return NULL; + if (s2 != size) { + DEBUG(1,("incorrect size for %s - got %d expected %d\n", + fname, (int)s2, (int)size)); + talloc_free(p); + return NULL; + } + } + + return p; +} + + +/**************************************************************************** +parse a buffer into lines +****************************************************************************/ +static char **file_lines_parse(char *p, size_t size, int *numlines, TALLOC_CTX *mem_ctx) +{ + int i; + char *s, **ret; + + if (!p) return NULL; + + for (s = p, i=0; s < p+size; s++) { + if (s[0] == '\n') i++; + } + + ret = talloc_array(mem_ctx, char *, i+2); + if (!ret) { + talloc_free(p); + return NULL; + } + + talloc_reference(ret, p); + + memset(ret, 0, sizeof(ret[0])*(i+2)); + if (numlines) *numlines = i; + + ret[0] = p; + for (s = p, i=0; s < p+size; s++) { + if (s[0] == '\n') { + s[0] = 0; + i++; + ret[i] = s+1; + } + 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 talloc_free(). +****************************************************************************/ +char **file_lines_load(const char *fname, int *numlines, TALLOC_CTX *mem_ctx) +{ + char *p; + char **lines; + size_t size; + + p = file_load(fname, &size, mem_ctx); + if (!p) return NULL; + + lines = file_lines_parse(p, size, numlines, mem_ctx); + + talloc_free(p); + + return lines; +} + +/**************************************************************************** +load a fd into memory and return an array of pointers to lines in the file +must be freed with talloc_free(). If convert is true calls unix_to_dos on +the list. +****************************************************************************/ +char **fd_lines_load(int fd, int *numlines, TALLOC_CTX *mem_ctx) +{ + char *p; + char **lines; + size_t size; + + p = fd_load(fd, &size, mem_ctx); + if (!p) return NULL; + + lines = file_lines_parse(p, size, numlines, mem_ctx); + + talloc_free(p); + + return lines; +} + + +/**************************************************************************** +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; + + for (i=0; lines[i];) { + int len = strlen(lines[i]); + if (lines[i][len-1] == '\\') { + 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]; + } + } else { + i++; + } + } +} + +/* + save a lump of data into a file. Mostly used for debugging +*/ +BOOL file_save(const char *fname, const void *packet, size_t length) +{ + int fd; + fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0644); + if (fd == -1) { + return False; + } + if (write(fd, packet, length) != (size_t)length) { + return False; + } + close(fd); + return True; +} + +/* + see if a file exists +*/ +BOOL file_exists(const char *path) +{ + struct stat st; + return (stat(path, &st) == 0); +} + +int vfdprintf(int fd, const char *format, va_list ap) _PRINTF_ATTRIBUTE(2,0) +{ + char *p; + int len, ret; + va_list ap2; + + VA_COPY(ap2, ap); + + len = vasprintf(&p, format, ap2); + if (len <= 0) return len; + ret = write(fd, p, len); + SAFE_FREE(p); + return ret; +} + +int fdprintf(int fd, const char *format, ...) _PRINTF_ATTRIBUTE(2,3) +{ + va_list ap; + int ret; + + va_start(ap, format); + ret = vfdprintf(fd, format, ap); + va_end(ap); + return ret; +} diff --git a/source4/lib/util/util_getent.c b/source4/lib/util/util_getent.c new file mode 100644 index 00000000000..9f58472fb8c --- /dev/null +++ b/source4/lib/util/util_getent.c @@ -0,0 +1,284 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Simo Sorce 2001 + Copyright (C) Jeremy Allison 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 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. +*/ + +#include "includes.h" + + +/**************************************************************** + Returns a single linked list of group entries. + Use grent_free() to free it after use. +****************************************************************/ + +struct sys_grent * getgrent_list(void) +{ + struct sys_grent *glist; + struct sys_grent *gent; + struct group *grp; + + gent = malloc_p(struct sys_grent); + if (gent == NULL) { + DEBUG (0, ("Out of memory in getgrent_list!\n")); + return NULL; + } + memset(gent, '\0', sizeof(struct sys_grent)); + glist = gent; + + setgrent(); + grp = getgrent(); + if (grp == NULL) { + endgrent(); + SAFE_FREE(glist); + return NULL; + } + + while (grp != NULL) { + int i,num; + + if (grp->gr_name) { + if ((gent->gr_name = strdup(grp->gr_name)) == NULL) + goto err; + } + if (grp->gr_passwd) { + if ((gent->gr_passwd = strdup(grp->gr_passwd)) == NULL) + goto err; + } + gent->gr_gid = grp->gr_gid; + + /* number of strings in gr_mem */ + for (num = 0; grp->gr_mem[num]; num++) + ; + + /* alloc space for gr_mem string pointers */ + if ((gent->gr_mem = malloc_array_p(char *, num+1)) == NULL) + goto err; + + memset(gent->gr_mem, '\0', (num+1) * sizeof(char *)); + + for (i=0; i < num; i++) { + if ((gent->gr_mem[i] = strdup(grp->gr_mem[i])) == NULL) + goto err; + } + gent->gr_mem[num] = NULL; + + grp = getgrent(); + if (grp) { + gent->next = malloc_p(struct sys_grent); + if (gent->next == NULL) + goto err; + gent = gent->next; + memset(gent, '\0', sizeof(struct sys_grent)); + } + } + + endgrent(); + return glist; + + err: + + endgrent(); + DEBUG(0, ("Out of memory in getgrent_list!\n")); + grent_free(glist); + return NULL; +} + +/**************************************************************** + Free the single linked list of group entries made by + getgrent_list() +****************************************************************/ + +void grent_free (struct sys_grent *glist) +{ + while (glist) { + struct sys_grent *prev; + + SAFE_FREE(glist->gr_name); + SAFE_FREE(glist->gr_passwd); + if (glist->gr_mem) { + int i; + for (i = 0; glist->gr_mem[i]; i++) + SAFE_FREE(glist->gr_mem[i]); + SAFE_FREE(glist->gr_mem); + } + prev = glist; + glist = glist->next; + SAFE_FREE(prev); + } +} + +/**************************************************************** + Returns a single linked list of passwd entries. + Use pwent_free() to free it after use. +****************************************************************/ + +struct sys_pwent * getpwent_list(void) +{ + struct sys_pwent *plist; + struct sys_pwent *pent; + struct passwd *pwd; + + pent = malloc_p(struct sys_pwent); + if (pent == NULL) { + DEBUG (0, ("Out of memory in getpwent_list!\n")); + return NULL; + } + plist = pent; + + setpwent(); + pwd = getpwent(); + while (pwd != NULL) { + memset(pent, '\0', sizeof(struct sys_pwent)); + if (pwd->pw_name) { + if ((pent->pw_name = strdup(pwd->pw_name)) == NULL) + goto err; + } + if (pwd->pw_passwd) { + if ((pent->pw_passwd = strdup(pwd->pw_passwd)) == NULL) + goto err; + } + pent->pw_uid = pwd->pw_uid; + pent->pw_gid = pwd->pw_gid; + if (pwd->pw_gecos) { + if ((pent->pw_name = strdup(pwd->pw_gecos)) == NULL) + goto err; + } + if (pwd->pw_dir) { + if ((pent->pw_name = strdup(pwd->pw_dir)) == NULL) + goto err; + } + if (pwd->pw_shell) { + if ((pent->pw_name = strdup(pwd->pw_shell)) == NULL) + goto err; + } + + pwd = getpwent(); + if (pwd) { + pent->next = malloc_p(struct sys_pwent); + if (pent->next == NULL) + goto err; + pent = pent->next; + } + } + + endpwent(); + return plist; + + err: + + endpwent(); + DEBUG(0, ("Out of memory in getpwent_list!\n")); + pwent_free(plist); + return NULL; +} + +/**************************************************************** + Free the single linked list of passwd entries made by + getpwent_list() +****************************************************************/ + +void pwent_free (struct sys_pwent *plist) +{ + while (plist) { + struct sys_pwent *prev; + + SAFE_FREE(plist->pw_name); + SAFE_FREE(plist->pw_passwd); + SAFE_FREE(plist->pw_gecos); + SAFE_FREE(plist->pw_dir); + SAFE_FREE(plist->pw_shell); + + prev = plist; + plist = plist->next; + SAFE_FREE(prev); + } +} + +/**************************************************************** + Add the individual group users onto the list. +****************************************************************/ + +static struct sys_userlist *add_members_to_userlist(struct sys_userlist *list_head, const struct group *grp) +{ + size_t num_users, i; + + /* Count the number of users. */ + for (num_users = 0; grp->gr_mem[num_users]; num_users++) + ; + + for (i = 0; i < num_users; i++) { + struct sys_userlist *entry = malloc_p(struct sys_userlist); + if (entry == NULL) { + free_userlist(list_head); + return NULL; + } + entry->unix_name = (char *)strdup(grp->gr_mem[i]); + if (entry->unix_name == NULL) { + SAFE_FREE(entry); + free_userlist(list_head); + return NULL; + } + DLIST_ADD(list_head, entry); + } + return list_head; +} + +/**************************************************************** + Get the list of UNIX users in a group. + We have to enumerate the /etc/group file as some UNIX getgrnam() + calls won't do that for us (notably Tru64 UNIX). +****************************************************************/ + +struct sys_userlist *get_users_in_group(const char *gname) +{ + struct sys_userlist *list_head = NULL; + struct group *gptr; + +#if !defined(BROKEN_GETGRNAM) + if ((gptr = (struct group *)getgrnam(gname)) == NULL) + return NULL; + return add_members_to_userlist(list_head, gptr); +#else + /* BROKEN_GETGRNAM - True64 */ + setgrent(); + while((gptr = getgrent()) != NULL) { + if (strequal(gname, gptr->gr_name)) { + list_head = add_members_to_userlist(list_head, gptr); + if (list_head == NULL) + return NULL; + } + } + endgrent(); + return list_head; +#endif +} + +/**************************************************************** + Free list allocated above. +****************************************************************/ + +void free_userlist(struct sys_userlist *list_head) +{ + while (list_head) { + struct sys_userlist *old_head = list_head; + DLIST_REMOVE(list_head, list_head); + SAFE_FREE(old_head->unix_name); + SAFE_FREE(old_head); + } +} diff --git a/source4/lib/util/util_pw.c b/source4/lib/util/util_pw.c new file mode 100644 index 00000000000..19893e396f9 --- /dev/null +++ b/source4/lib/util/util_pw.c @@ -0,0 +1,89 @@ +/* + Unix SMB/CIFS implementation. + + Safe versions of getpw* calls + + Copyright (C) Andrew Bartlett 2002 + + 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. +*/ + +#include "includes.h" + +static struct passwd *alloc_copy_passwd(const struct passwd *from) +{ + struct passwd *ret = smb_xmalloc_p(struct passwd); + ZERO_STRUCTP(ret); + ret->pw_name = smb_xstrdup(from->pw_name); + ret->pw_passwd = smb_xstrdup(from->pw_passwd); + ret->pw_uid = from->pw_uid; + ret->pw_gid = from->pw_gid; + ret->pw_gecos = smb_xstrdup(from->pw_gecos); + ret->pw_dir = smb_xstrdup(from->pw_dir); + ret->pw_shell = smb_xstrdup(from->pw_shell); + return ret; +} + +void passwd_free (struct passwd **buf) +{ + if (!*buf) { + DEBUG(0, ("attempted double-free of allocated passwd\n")); + return; + } + + SAFE_FREE((*buf)->pw_name); + SAFE_FREE((*buf)->pw_passwd); + SAFE_FREE((*buf)->pw_gecos); + SAFE_FREE((*buf)->pw_dir); + SAFE_FREE((*buf)->pw_shell); + + SAFE_FREE(*buf); +} + +struct passwd *getpwnam_alloc(const char *name) +{ + struct passwd *temp; + + temp = sys_getpwnam(name); + + if (!temp) { +#if 0 + if (errno == ENOMEM) { + /* what now? */ + } +#endif + return NULL; + } + + return alloc_copy_passwd(temp); +} + +struct passwd *getpwuid_alloc(uid_t uid) +{ + struct passwd *temp; + + temp = sys_getpwuid(uid); + + if (!temp) { +#if 0 + if (errno == ENOMEM) { + /* what now? */ + } +#endif + return NULL; + } + + return alloc_copy_passwd(temp); +} diff --git a/source4/lib/util/util_sock.c b/source4/lib/util/util_sock.c new file mode 100644 index 00000000000..8a65a27d020 --- /dev/null +++ b/source4/lib/util/util_sock.c @@ -0,0 +1,128 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Tim Potter 2000-2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 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. +*/ + +#include "includes.h" +#include "system/network.h" + +enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON}; + +static const struct { + const char *name; + int level; + int option; + int value; + int opttype; +} socket_options[] = { + {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL}, + {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL}, + {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL}, +#ifdef TCP_NODELAY + {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL}, +#endif +#ifdef IPTOS_LOWDELAY + {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON}, +#endif +#ifdef IPTOS_THROUGHPUT + {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON}, +#endif +#ifdef SO_REUSEPORT + {"SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, 0, OPT_BOOL}, +#endif +#ifdef SO_SNDBUF + {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT}, +#endif +#ifdef SO_RCVBUF + {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT}, +#endif +#ifdef SO_SNDLOWAT + {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT}, +#endif +#ifdef SO_RCVLOWAT + {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT}, +#endif +#ifdef SO_SNDTIMEO + {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT}, +#endif +#ifdef SO_RCVTIMEO + {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT}, +#endif + {NULL,0,0,0,0}}; + + +/**************************************************************************** + Set user socket options. +****************************************************************************/ +void set_socket_options(int fd, const char *options) +{ + const char **options_list = str_list_make(NULL, options, " \t,"); + int j; + + if (!options_list) + return; + + for (j = 0; options_list[j]; j++) { + const char *tok = options_list[j]; + int ret=0,i; + int value = 1; + char *p; + BOOL got_value = False; + + if ((p = strchr_m(tok,'='))) { + *p = 0; + value = atoi(p+1); + got_value = True; + } + + for (i=0;socket_options[i].name;i++) + if (strequal(socket_options[i].name,tok)) + break; + + if (!socket_options[i].name) { + DEBUG(0,("Unknown socket option %s\n",tok)); + continue; + } + + switch (socket_options[i].opttype) { + case OPT_BOOL: + case OPT_INT: + ret = setsockopt(fd,socket_options[i].level, + socket_options[i].option,(char *)&value,sizeof(int)); + break; + + case OPT_ON: + if (got_value) + DEBUG(0,("syntax error - %s does not take a value\n",tok)); + + { + int on = socket_options[i].value; + ret = setsockopt(fd,socket_options[i].level, + socket_options[i].option,(char *)&on,sizeof(int)); + } + break; + } + + if (ret != 0) + DEBUG(0,("Failed to set socket option %s (Error %s)\n",tok, strerror(errno) )); + } + + talloc_free(options_list); +} + diff --git a/source4/lib/util/util_str.c b/source4/lib/util/util_str.c new file mode 100644 index 00000000000..b46787e3ea2 --- /dev/null +++ b/source4/lib/util/util_str.c @@ -0,0 +1,1209 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + + Copyright (C) Andrew Tridgell 1992-2001 + Copyright (C) Simo Sorce 2001-2002 + Copyright (C) Martin Pool 2003 + Copyright (C) James Peach 2005 + + 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. +*/ + +#include "includes.h" +#include "system/iconv.h" +#include "smb.h" +#include "pstring.h" +#include "lib/ldb/include/ldb.h" + +/** + * @file + * @brief String utilities. + **/ + +/** + * Get the next token from a string, return False if none found. + * Handles double-quotes. + * + * Based on a routine by GJC@VILLAGE.COM. + * Extensively modified by Andrew.Tridgell@anu.edu.au + **/ +BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize) +{ + const char *s; + BOOL quoted; + size_t len=1; + + if (!ptr) + return(False); + + s = *ptr; + + /* default to simple separators */ + if (!sep) + sep = " \t\n\r"; + + /* find the first non sep char */ + while (*s && strchr_m(sep,*s)) + s++; + + /* nothing left? */ + if (! *s) + return(False); + + /* copy over the token */ + for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) { + if (*s == '\"') { + quoted = !quoted; + } else { + len++; + *buff++ = *s; + } + } + + *ptr = (*s) ? s+1 : s; + *buff = 0; + + return(True); +} + +/** + Case insensitive string compararison +**/ +int strcasecmp_m(const char *s1, const char *s2) +{ + codepoint_t c1=0, c2=0; + size_t size1, size2; + + while (*s1 && *s2) { + c1 = next_codepoint(s1, &size1); + c2 = next_codepoint(s2, &size2); + + s1 += size1; + s2 += size2; + + if (c1 == c2) { + continue; + } + + if (c1 == INVALID_CODEPOINT || + c2 == INVALID_CODEPOINT) { + /* what else can we do?? */ + return c1 - c2; + } + + if (toupper_w(c1) != toupper_w(c2)) { + return c1 - c2; + } + } + + return *s1 - *s2; +} + +/** + * Compare 2 strings. + * + * @note The comparison is case-insensitive. + **/ +BOOL strequal(const char *s1, const char *s2) +{ + if (s1 == s2) + return(True); + if (!s1 || !s2) + return(False); + + return strcasecmp_m(s1,s2) == 0; +} + +/** + Compare 2 strings (case sensitive). +**/ +BOOL strcsequal(const char *s1,const char *s2) +{ + if (s1 == s2) + return(True); + if (!s1 || !s2) + return(False); + + return strcmp(s1,s2) == 0; +} + + +/** +Do a case-insensitive, whitespace-ignoring string compare. +**/ +int strwicmp(const char *psz1, const char *psz2) +{ + /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */ + /* appropriate value. */ + if (psz1 == psz2) + return (0); + else if (psz1 == NULL) + return (-1); + else if (psz2 == NULL) + return (1); + + /* sync the strings on first non-whitespace */ + while (1) { + while (isspace((int)*psz1)) + psz1++; + while (isspace((int)*psz2)) + psz2++; + if (toupper((unsigned char)*psz1) != toupper((unsigned char)*psz2) + || *psz1 == '\0' + || *psz2 == '\0') + break; + psz1++; + psz2++; + } + return (*psz1 - *psz2); +} + +/** + String replace. + NOTE: oldc and newc must be 7 bit characters +**/ +void string_replace(char *s, char oldc, char newc) +{ + while (*s) { + size_t size; + codepoint_t c = next_codepoint(s, &size); + if (c == oldc) { + *s = newc; + } + s += size; + } +} + +/** + Trim the specified elements off the front and back of a string. +**/ +BOOL trim_string(char *s,const char *front,const char *back) +{ + BOOL ret = False; + size_t front_len; + size_t back_len; + size_t len; + + /* Ignore null or empty strings. */ + if (!s || (s[0] == '\0')) + return False; + + front_len = front? strlen(front) : 0; + back_len = back? strlen(back) : 0; + + len = strlen(s); + + if (front_len) { + while (len && strncmp(s, front, front_len)==0) { + /* Must use memmove here as src & dest can + * easily overlap. Found by valgrind. JRA. */ + memmove(s, s+front_len, (len-front_len)+1); + len -= front_len; + ret=True; + } + } + + if (back_len) { + while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) { + s[len-back_len]='\0'; + len -= back_len; + ret=True; + } + } + return ret; +} + +/** + Find the number of 'c' chars in a string +**/ +size_t count_chars(const char *s, char c) +{ + size_t count = 0; + + while (*s) { + size_t size; + codepoint_t c2 = next_codepoint(s, &size); + if (c2 == c) count++; + s += size; + } + + return count; +} + +/** + Safe string copy into a known length string. maxlength does not + include the terminating zero. +**/ +char *safe_strcpy(char *dest,const char *src, size_t maxlength) +{ + size_t len; + + if (!dest) { + DEBUG(0,("ERROR: NULL dest in safe_strcpy\n")); + return NULL; + } + +#ifdef DEVELOPER + /* We intentionally write out at the extremity of the destination + * string. If the destination is too short (e.g. pstrcpy into mallocd + * or fstring) then this should cause an error under a memory + * checker. */ + dest[maxlength] = '\0'; + if (PTR_DIFF(&len, dest) > 0) { /* check if destination is on the stack, ok if so */ + log_suspicious_usage("safe_strcpy", src); + } +#endif + + if (!src) { + *dest = 0; + return dest; + } + + len = strlen(src); + + if (len > maxlength) { + DEBUG(0,("ERROR: string overflow by %u (%u - %u) in safe_strcpy [%.50s]\n", + (uint_t)(len-maxlength), (unsigned)len, (unsigned)maxlength, src)); + len = maxlength; + } + + memmove(dest, src, len); + dest[len] = 0; + return dest; +} + +/** + Safe string cat into a string. maxlength does not + include the terminating zero. +**/ +char *safe_strcat(char *dest, const char *src, size_t maxlength) +{ + size_t src_len, dest_len; + + if (!dest) { + DEBUG(0,("ERROR: NULL dest in safe_strcat\n")); + return NULL; + } + + if (!src) + return dest; + +#ifdef DEVELOPER + if (PTR_DIFF(&src_len, dest) > 0) { /* check if destination is on the stack, ok if so */ + log_suspicious_usage("safe_strcat", src); + } +#endif + src_len = strlen(src); + dest_len = strlen(dest); + + if (src_len + dest_len > maxlength) { + DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n", + (int)(src_len + dest_len - maxlength), src)); + if (maxlength > dest_len) { + memcpy(&dest[dest_len], src, maxlength - dest_len); + } + dest[maxlength] = 0; + return NULL; + } + + memcpy(&dest[dest_len], src, src_len); + dest[dest_len + src_len] = 0; + return dest; +} + +/** + Paranoid strcpy into a buffer of given length (includes terminating + zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars + and replaces with '_'. Deliberately does *NOT* check for multibyte + characters. Don't change it ! +**/ + +char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength) +{ + size_t len, i; + + if (maxlength == 0) { + /* can't fit any bytes at all! */ + return NULL; + } + + if (!dest) { + DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n")); + return NULL; + } + + if (!src) { + *dest = 0; + return dest; + } + + len = strlen(src); + if (len >= maxlength) + len = maxlength - 1; + + if (!other_safe_chars) + other_safe_chars = ""; + + for(i = 0; i < len; i++) { + int val = (src[i] & 0xff); + if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val)) + dest[i] = src[i]; + else + dest[i] = '_'; + } + + dest[i] = '\0'; + + return dest; +} + +/** + Like strncpy but always null terminates. Make sure there is room! + The variable n should always be one less than the available size. +**/ + +char *StrnCpy(char *dest,const char *src,size_t n) +{ + char *d = dest; + if (!dest) + return(NULL); + if (!src) { + *dest = 0; + return(dest); + } + while (n-- && (*d++ = *src++)) + ; + *d = 0; + return(dest); +} + + +/** + Routine to get hex characters and turn them into a 16 byte array. + the array can be variable length, and any non-hex-numeric + characters are skipped. "0xnn" or "0Xnn" is specially catered + for. + + valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n" + + +**/ +size_t strhex_to_str(char *p, size_t len, const char *strhex) +{ + size_t i; + size_t num_chars = 0; + uint8_t lonybble, hinybble; + const char *hexchars = "0123456789ABCDEF"; + char *p1 = NULL, *p2 = NULL; + + for (i = 0; i < len && strhex[i] != 0; i++) { + if (strncasecmp(hexchars, "0x", 2) == 0) { + i++; /* skip two chars */ + continue; + } + + if (!(p1 = strchr_m(hexchars, toupper((unsigned char)strhex[i])))) + break; + + i++; /* next hex digit */ + + if (!(p2 = strchr_m(hexchars, toupper((unsigned char)strhex[i])))) + break; + + /* get the two nybbles */ + hinybble = PTR_DIFF(p1, hexchars); + lonybble = PTR_DIFF(p2, hexchars); + + p[num_chars] = (hinybble << 4) | lonybble; + num_chars++; + + p1 = NULL; + p2 = NULL; + } + return num_chars; +} + +DATA_BLOB strhex_to_data_blob(const char *strhex) +{ + DATA_BLOB ret_blob = data_blob(NULL, strlen(strhex)/2+1); + + ret_blob.length = strhex_to_str((char *)ret_blob.data, + strlen(strhex), + strhex); + + return ret_blob; +} + + +/** + * Routine to print a buffer as HEX digits, into an allocated string. + */ +void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer) +{ + int i; + char *hex_buffer; + + *out_hex_buffer = smb_xmalloc((len*2)+1); + hex_buffer = *out_hex_buffer; + + for (i = 0; i < len; i++) + slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]); +} + +/** + Check if a string is part of a list. +**/ +BOOL in_list(const char *s, const char *list, BOOL casesensitive) +{ + pstring tok; + const char *p=list; + + if (!list) + return(False); + + while (next_token(&p,tok,LIST_SEP,sizeof(tok))) { + if (casesensitive) { + if (strcmp(tok,s) == 0) + return(True); + } else { + if (strcasecmp_m(tok,s) == 0) + return(True); + } + } + return(False); +} + +/** + Set a string value, allocing the space for the string +**/ +static BOOL string_init(char **dest,const char *src) +{ + if (!src) src = ""; + + (*dest) = strdup(src); + if ((*dest) == NULL) { + DEBUG(0,("Out of memory in string_init\n")); + return False; + } + return True; +} + +/** + Free a string value. +**/ +void string_free(char **s) +{ + if (s) SAFE_FREE(*s); +} + +/** + Set a string value, deallocating any existing space, and allocing the space + for the string +**/ +BOOL string_set(char **dest, const char *src) +{ + string_free(dest); + return string_init(dest,src); +} + +/** + Substitute a string for a pattern in another string. Make sure there is + enough room! + + This routine looks for pattern in s and replaces it with + insert. It may do multiple replacements. + + Any of " ; ' $ or ` in the insert string are replaced with _ + if len==0 then the string cannot be extended. This is different from the old + use of len==0 which was for no length checks to be done. +**/ + +void string_sub(char *s,const char *pattern, const char *insert, size_t len) +{ + char *p; + ssize_t ls,lp,li, i; + + if (!insert || !pattern || !*pattern || !s) + return; + + ls = (ssize_t)strlen(s); + lp = (ssize_t)strlen(pattern); + li = (ssize_t)strlen(insert); + + if (len == 0) + len = ls + 1; /* len is number of *bytes* */ + + while (lp <= ls && (p = strstr(s,pattern))) { + if (ls + (li-lp) >= len) { + DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", + (int)(ls + (li-lp) - len), + pattern, (int)len)); + break; + } + if (li != lp) { + memmove(p+li,p+lp,strlen(p+lp)+1); + } + for (i=0;i= len) { + DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", + (int)(ls + (li-lp) - len), + pattern, (int)len)); + break; + } + if (li != lp) { + memmove(p+li,p+lp,strlen(p+lp)+1); + } + memcpy(p, insert, li); + s = p + li; + ls += (li-lp); + } +} + + +/** + Strchr and strrchr_m are a bit complex on general multi-byte strings. +**/ +char *strchr_m(const char *s, char c) +{ + /* characters below 0x3F are guaranteed to not appear in + non-initial position in multi-byte charsets */ + if ((c & 0xC0) == 0) { + return strchr(s, c); + } + + while (*s) { + size_t size; + codepoint_t c2 = next_codepoint(s, &size); + if (c2 == c) { + return discard_const(s); + } + s += size; + } + + return NULL; +} + +char *strrchr_m(const char *s, char c) +{ + char *ret = NULL; + + /* characters below 0x3F are guaranteed to not appear in + non-initial position in multi-byte charsets */ + if ((c & 0xC0) == 0) { + return strrchr(s, c); + } + + while (*s) { + size_t size; + codepoint_t c2 = next_codepoint(s, &size); + if (c2 == c) { + ret = discard_const(s); + } + s += size; + } + + return ret; +} + +/* + return True if any (multi-byte) character is lower case +*/ +BOOL strhaslower(const char *string) +{ + while (*string) { + size_t c_size; + codepoint_t s; + codepoint_t t; + + s = next_codepoint(string, &c_size); + string += c_size; + + t = toupper_w(s); + + if (s != t) { + return True; /* that means it has lower case chars */ + } + } + + return False; +} + +/* + return True if any (multi-byte) character is upper case +*/ +BOOL strhasupper(const char *string) +{ + while (*string) { + size_t c_size; + codepoint_t s; + codepoint_t t; + + s = next_codepoint(string, &c_size); + string += c_size; + + t = tolower_w(s); + + if (s != t) { + return True; /* that means it has upper case chars */ + } + } + + return False; +} + +/** + Convert a string to lower case, allocated with talloc +**/ +char *strlower_talloc(TALLOC_CTX *ctx, const char *src) +{ + size_t size=0; + char *dest; + + /* this takes advantage of the fact that upper/lower can't + change the length of a character by more than 1 byte */ + dest = talloc_size(ctx, 2*(strlen(src))+1); + if (dest == NULL) { + return NULL; + } + + while (*src) { + size_t c_size; + codepoint_t c = next_codepoint(src, &c_size); + src += c_size; + + c = tolower_w(c); + + c_size = push_codepoint(dest+size, c); + if (c_size == -1) { + talloc_free(dest); + return NULL; + } + size += c_size; + } + + dest[size] = 0; + + return dest; +} + +/** + Convert a string to UPPER case, allocated with talloc +**/ +char *strupper_talloc(TALLOC_CTX *ctx, const char *src) +{ + size_t size=0; + char *dest; + + if (!src) { + return NULL; + } + + /* this takes advantage of the fact that upper/lower can't + change the length of a character by more than 1 byte */ + dest = talloc_size(ctx, 2*(strlen(src))+1); + if (dest == NULL) { + return NULL; + } + + while (*src) { + size_t c_size; + codepoint_t c = next_codepoint(src, &c_size); + src += c_size; + + c = toupper_w(c); + + c_size = push_codepoint(dest+size, c); + if (c_size == -1) { + talloc_free(dest); + return NULL; + } + size += c_size; + } + + dest[size] = 0; + + return dest; +} + +/** + Convert a string to lower case. +**/ +void strlower_m(char *s) +{ + char *d; + + /* this is quite a common operation, so we want it to be + fast. We optimise for the ascii case, knowing that all our + supported multi-byte character sets are ascii-compatible + (ie. they match for the first 128 chars) */ + while (*s && !(((uint8_t)*s) & 0x80)) { + *s = tolower((uint8_t)*s); + s++; + } + + if (!*s) + return; + + d = s; + + while (*s) { + size_t c_size, c_size2; + codepoint_t c = next_codepoint(s, &c_size); + c_size2 = push_codepoint(d, tolower_w(c)); + if (c_size2 > c_size) { + DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strlower_m\n", + c, tolower_w(c), (int)c_size, (int)c_size2)); + smb_panic("codepoint expansion in strlower_m\n"); + } + s += c_size; + d += c_size2; + } + *d = 0; +} + +/** + Convert a string to UPPER case. +**/ +void strupper_m(char *s) +{ + char *d; + + /* this is quite a common operation, so we want it to be + fast. We optimise for the ascii case, knowing that all our + supported multi-byte character sets are ascii-compatible + (ie. they match for the first 128 chars) */ + while (*s && !(((uint8_t)*s) & 0x80)) { + *s = toupper((uint8_t)*s); + s++; + } + + if (!*s) + return; + + d = s; + + while (*s) { + size_t c_size, c_size2; + codepoint_t c = next_codepoint(s, &c_size); + c_size2 = push_codepoint(d, toupper_w(c)); + if (c_size2 > c_size) { + DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strupper_m\n", + c, toupper_w(c), (int)c_size, (int)c_size2)); + smb_panic("codepoint expansion in strupper_m\n"); + } + s += c_size; + d += c_size2; + } + *d = 0; +} + +/** + Count the number of UCS2 characters in a string. Normally this will + be the same as the number of bytes in a string for single byte strings, + but will be different for multibyte. +**/ +size_t strlen_m(const char *s) +{ + size_t count = 0; + + if (!s) { + return 0; + } + + while (*s && !(((uint8_t)*s) & 0x80)) { + s++; + count++; + } + + if (!*s) { + return count; + } + + while (*s) { + size_t c_size; + codepoint_t c = next_codepoint(s, &c_size); + if (c < 0x10000) { + count += 1; + } else { + count += 2; + } + s += c_size; + } + + return count; +} + +/** + Work out the number of multibyte chars in a string, including the NULL + terminator. +**/ +size_t strlen_m_term(const char *s) +{ + if (!s) { + return 0; + } + + return strlen_m(s) + 1; +} + +/** + Unescape a URL encoded string, in place. +**/ + +void rfc1738_unescape(char *buf) +{ + char *p=buf; + + while ((p=strchr_m(p,'+'))) + *p = ' '; + + p = buf; + + while (p && *p && (p=strchr_m(p,'%'))) { + int c1 = p[1]; + int c2 = p[2]; + + if (c1 >= '0' && c1 <= '9') + c1 = c1 - '0'; + else if (c1 >= 'A' && c1 <= 'F') + c1 = 10 + c1 - 'A'; + else if (c1 >= 'a' && c1 <= 'f') + c1 = 10 + c1 - 'a'; + else {p++; continue;} + + if (c2 >= '0' && c2 <= '9') + c2 = c2 - '0'; + else if (c2 >= 'A' && c2 <= 'F') + c2 = 10 + c2 - 'A'; + else if (c2 >= 'a' && c2 <= 'f') + c2 = 10 + c2 - 'a'; + else {p++; continue;} + + *p = (c1<<4) | c2; + + memmove(p+1, p+3, strlen(p+3)+1); + p++; + } +} + +/** + * Decode a base64 string into a DATA_BLOB - simple and slow algorithm + **/ +DATA_BLOB base64_decode_data_blob(TALLOC_CTX *mem_ctx, const char *s) +{ + DATA_BLOB ret = data_blob_talloc(mem_ctx, s, strlen(s)+1); + ret.length = ldb_base64_decode((char *)ret.data); + return ret; +} + +/** + * Decode a base64 string in-place - wrapper for the above + **/ +void base64_decode_inplace(char *s) +{ + ldb_base64_decode(s); +} + +/** + * Encode a base64 string into a talloc()ed string caller to free. + **/ +char *base64_encode_data_blob(TALLOC_CTX *mem_ctx, DATA_BLOB data) +{ + return ldb_base64_encode(mem_ctx, (const char *)data.data, data.length); +} + +#ifdef VALGRIND +size_t valgrind_strlen(const char *s) +{ + size_t count; + for(count = 0; *s++; count++) + ; + return count; +} +#endif + + +/* + format a string into length-prefixed dotted domain format, as used in NBT + and in some ADS structures +*/ +const char *str_format_nbt_domain(TALLOC_CTX *mem_ctx, const char *s) +{ + char *ret; + int i; + if (!s || !*s) { + return talloc_strdup(mem_ctx, ""); + } + ret = talloc_size(mem_ctx, strlen(s)+2); + if (!ret) { + return ret; + } + + memcpy(ret+1, s, strlen(s)+1); + ret[0] = '.'; + + for (i=0;ret[i];i++) { + if (ret[i] == '.') { + char *p = strchr(ret+i+1, '.'); + if (p) { + ret[i] = p-(ret+i+1); + } else { + ret[i] = strlen(ret+i+1); + } + } + } + + return ret; +} + +BOOL add_string_to_array(TALLOC_CTX *mem_ctx, + const char *str, const char ***strings, int *num) +{ + char *dup_str = talloc_strdup(mem_ctx, str); + + *strings = talloc_realloc(mem_ctx, + *strings, + const char *, ((*num)+1)); + + if ((*strings == NULL) || (dup_str == NULL)) + return False; + + (*strings)[*num] = dup_str; + *num += 1; + + return True; +} + + + +/* + varient of strcmp() that handles NULL ptrs +*/ +int strcmp_safe(const char *s1, const char *s2) +{ + if (s1 == s2) { + return 0; + } + if (s1 == NULL || s2 == NULL) { + return s1?-1:1; + } + return strcmp(s1, s2); +} + + +/******************************************************************* +return the number of bytes occupied by a buffer in ASCII format +the result includes the null termination +limited by 'n' bytes +********************************************************************/ +size_t ascii_len_n(const char *src, size_t n) +{ + size_t len; + + len = strnlen(src, n); + if (len+1 <= n) { + len += 1; + } + + return len; +} + + +/******************************************************************* + Return a string representing a CIFS attribute for a file. +********************************************************************/ +char *attrib_string(TALLOC_CTX *mem_ctx, uint32_t attrib) +{ + int i, len; + const struct { + char c; + uint16_t attr; + } attr_strs[] = { + {'V', FILE_ATTRIBUTE_VOLUME}, + {'D', FILE_ATTRIBUTE_DIRECTORY}, + {'A', FILE_ATTRIBUTE_ARCHIVE}, + {'H', FILE_ATTRIBUTE_HIDDEN}, + {'S', FILE_ATTRIBUTE_SYSTEM}, + {'N', FILE_ATTRIBUTE_NORMAL}, + {'R', FILE_ATTRIBUTE_READONLY}, + {'d', FILE_ATTRIBUTE_DEVICE}, + {'t', FILE_ATTRIBUTE_TEMPORARY}, + {'s', FILE_ATTRIBUTE_SPARSE}, + {'r', FILE_ATTRIBUTE_REPARSE_POINT}, + {'c', FILE_ATTRIBUTE_COMPRESSED}, + {'o', FILE_ATTRIBUTE_OFFLINE}, + {'n', FILE_ATTRIBUTE_NONINDEXED}, + {'e', FILE_ATTRIBUTE_ENCRYPTED} + }; + char *ret; + + ret = talloc_size(mem_ctx, ARRAY_SIZE(attr_strs)+1); + if (!ret) { + return NULL; + } + + for (len=i=0; ibufused) return -1; + + /* on files being read full buffering is the only option */ + if ((f->open_flags & O_ACCMODE) == O_RDONLY) { + mode = X_IOFBF; + } + + /* destroy any earlier buffer */ + SAFE_FREE(f->buf); + f->buf = 0; + f->bufsize = 0; + f->next = NULL; + f->bufused = 0; + f->buftype = mode; + + if (f->buftype == X_IONBF) return 0; + + /* if buffering then we need some size */ + if (size == 0) size = XBUFSIZE; + + f->bufsize = size; + f->bufused = 0; + + return 0; +} + +/* allocate the buffer */ +static int x_allocate_buffer(XFILE *f) +{ + if (f->buf) return 1; + if (f->bufsize == 0) return 0; + f->buf = malloc(f->bufsize); + if (!f->buf) return 0; + f->next = f->buf; + return 1; +} + + +/* this looks more like open() than fopen(), but that is quite deliberate. + I want programmers to *think* about O_EXCL, O_CREAT etc not just + get them magically added +*/ +XFILE *x_fopen(const char *fname, int flags, mode_t mode) +{ + XFILE *ret; + + ret = malloc_p(XFILE); + if (!ret) return NULL; + + memset(ret, 0, sizeof(XFILE)); + + if ((flags & O_ACCMODE) == O_RDWR) { + /* we don't support RDWR in XFILE - use file + descriptors instead */ + errno = EINVAL; + return NULL; + } + + ret->open_flags = flags; + + ret->fd = open(fname, flags, mode); + if (ret->fd == -1) { + SAFE_FREE(ret); + return NULL; + } + + x_setvbuf(ret, NULL, X_IOFBF, XBUFSIZE); + + return ret; +} + +/* simulate fclose() */ +int x_fclose(XFILE *f) +{ + int ret; + + /* make sure we flush any buffered data */ + x_fflush(f); + + ret = close(f->fd); + f->fd = -1; + if (f->buf) { + /* make sure data can't leak into a later malloc */ + memset(f->buf, 0, f->bufsize); + SAFE_FREE(f->buf); + } + /* check the file descriptor given to the function is NOT one of the static + * descriptor of this libreary or we will free unallocated memory + * --sss */ + if (f != x_stdin && f != x_stdout && f != x_stderr) { + SAFE_FREE(f); + } + return ret; +} + +/* simulate fwrite() */ +size_t x_fwrite(const void *p, size_t size, size_t nmemb, XFILE *f) +{ + ssize_t ret; + size_t total=0; + + /* we might be writing unbuffered */ + if (f->buftype == X_IONBF || + (!f->buf && !x_allocate_buffer(f))) { + ret = write(f->fd, p, size*nmemb); + if (ret == -1) return -1; + return ret/size; + } + + + while (total < size*nmemb) { + size_t n = f->bufsize - f->bufused; + n = MIN(n, (size*nmemb)-total); + + if (n == 0) { + /* it's full, flush it */ + x_fflush(f); + continue; + } + + memcpy(f->buf + f->bufused, total+(const char *)p, n); + f->bufused += n; + total += n; + } + + /* when line buffered we need to flush at the last linefeed. This can + flush a bit more than necessary, but that is harmless */ + if (f->buftype == X_IOLBF && f->bufused) { + int i; + for (i=(size*nmemb)-1; i>=0; i--) { + if (*(i+(const char *)p) == '\n') { + x_fflush(f); + break; + } + } + } + + return total/size; +} + +/* thank goodness for asprintf() */ + int x_vfprintf(XFILE *f, const char *format, va_list ap) +{ + char *p; + int len, ret; + va_list ap2; + + VA_COPY(ap2, ap); + + len = vasprintf(&p, format, ap2); + if (len <= 0) return len; + ret = x_fwrite(p, 1, len, f); + SAFE_FREE(p); + return ret; +} + + int x_fprintf(XFILE *f, const char *format, ...) +{ + va_list ap; + int ret; + + va_start(ap, format); + ret = x_vfprintf(f, format, ap); + va_end(ap); + return ret; +} + +/* at least fileno() is simple! */ +int x_fileno(XFILE *f) +{ + return f->fd; +} + +/* simulate fflush() */ +int x_fflush(XFILE *f) +{ + int ret; + + if (f->flags & X_FLAG_ERROR) return -1; + + if ((f->open_flags & O_ACCMODE) != O_WRONLY) { + errno = EINVAL; + return -1; + } + + if (f->bufused == 0) return 0; + + ret = write(f->fd, f->buf, f->bufused); + if (ret == -1) return -1; + + f->bufused -= ret; + if (f->bufused > 0) { + f->flags |= X_FLAG_ERROR; + memmove(f->buf, ret + (char *)f->buf, f->bufused); + return -1; + } + + return 0; +} + +/* simulate setbuffer() */ +void x_setbuffer(XFILE *f, char *buf, size_t size) +{ + x_setvbuf(f, buf, buf?X_IOFBF:X_IONBF, size); +} + +/* simulate setbuf() */ +void x_setbuf(XFILE *f, char *buf) +{ + x_setvbuf(f, buf, buf?X_IOFBF:X_IONBF, XBUFSIZE); +} + +/* simulate setlinebuf() */ +void x_setlinebuf(XFILE *f) +{ + x_setvbuf(f, NULL, X_IOLBF, 0); +} + + +/* simulate feof() */ +int x_feof(XFILE *f) +{ + if (f->flags & X_FLAG_EOF) return 1; + return 0; +} + +/* simulate ferror() */ +int x_ferror(XFILE *f) +{ + if (f->flags & X_FLAG_ERROR) return 1; + return 0; +} + +/* fill the read buffer */ +static void x_fillbuf(XFILE *f) +{ + int n; + + if (f->bufused) return; + + if (!f->buf && !x_allocate_buffer(f)) return; + + n = read(f->fd, f->buf, f->bufsize); + if (n <= 0) return; + f->bufused = n; + f->next = f->buf; +} + +/* simulate fgetc() */ +int x_fgetc(XFILE *f) +{ + int ret; + + if (f->flags & (X_FLAG_EOF | X_FLAG_ERROR)) return EOF; + + if (f->bufused == 0) x_fillbuf(f); + + if (f->bufused == 0) { + f->flags |= X_FLAG_EOF; + return EOF; + } + + ret = *(uint8_t *)(f->next); + f->next++; + f->bufused--; + return ret; +} + +/* simulate fread */ +size_t x_fread(void *p, size_t size, size_t nmemb, XFILE *f) +{ + size_t total = 0; + while (total < size*nmemb) { + int c = x_fgetc(f); + if (c == EOF) break; + (total+(char *)p)[0] = (char)c; + total++; + } + return total/size; +} + +/* simulate fgets() */ +char *x_fgets(char *s, int size, XFILE *stream) +{ + char *s0 = s; + int l = size; + while (l>1) { + int c = x_fgetc(stream); + if (c == EOF) break; + *s++ = (char)c; + l--; + if (c == '\n') break; + } + if (l==size || x_ferror(stream)) { + return 0; + } + *s = 0; + return s0; +} + +/* trivial seek, works only for SEEK_SET and SEEK_END if SEEK_CUR is + * set then an error is returned */ +off_t x_tseek(XFILE *f, off_t offset, int whence) +{ + if (f->flags & X_FLAG_ERROR) + return -1; + + /* only SEEK_SET and SEEK_END are supported */ + /* SEEK_CUR needs internal offset counter */ + if (whence != SEEK_SET && whence != SEEK_END) { + f->flags |= X_FLAG_EINVAL; + errno = EINVAL; + return -1; + } + + /* empty the buffer */ + switch (f->open_flags & O_ACCMODE) { + case O_RDONLY: + f->bufused = 0; + break; + case O_WRONLY: + if (x_fflush(f) != 0) + return -1; + break; + default: + errno = EINVAL; + return -1; + } + + f->flags &= ~X_FLAG_EOF; + return lseek(f->fd, offset, whence); +} diff --git a/source4/lib/util/xfile.h b/source4/lib/util/xfile.h new file mode 100644 index 00000000000..89fa9d1e118 --- /dev/null +++ b/source4/lib/util/xfile.h @@ -0,0 +1,49 @@ +/* + Unix SMB/CIFS implementation. + stdio replacement + Copyright (C) Andrew Tridgell 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 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. +*/ + +#ifndef _XFILE_H_ +#define _XFILE_H_ +/* + see xfile.c for explanations +*/ + +typedef struct { + int fd; + char *buf; + char *next; + int bufsize; + int bufused; + int open_flags; + int buftype; + int flags; +} XFILE; + +extern XFILE *x_stdin, *x_stdout, *x_stderr; + +/* buffering type */ +#define X_IOFBF 0 +#define X_IOLBF 1 +#define X_IONBF 2 + +#define x_getc(f) x_fgetc(f) + +int x_vfprintf(XFILE *f, const char *format, va_list ap) PRINTF_ATTRIBUTE(2, 0); +int x_fprintf(XFILE *f, const char *format, ...) PRINTF_ATTRIBUTE(2, 3); +#endif /* _XFILE_H_ */ diff --git a/source4/lib/util_file.c b/source4/lib/util_file.c deleted file mode 100644 index 246b03b4aa4..00000000000 --- a/source4/lib/util_file.c +++ /dev/null @@ -1,385 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * SMB parameters and setup - * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995. - * - * Added afdgets() Jelmer Vernooij 2005 - * - * 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. - */ - -#include "includes.h" -#include "system/shmem.h" -#include "system/filesys.h" - -/**************************************************************************** -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; - - maxlen *= 2; - t = realloc_p(s, char, maxlen); - if (!t) { - DEBUG(0,("fgets_slash: failed to expand buffer!\n")); - SAFE_FREE(s); - return(NULL); - } else s = t; - } - } - return(s); -} - -/* Read one line (data until next newline or eof) and allocate it */ -char *afdgets(int fd, TALLOC_CTX *mem_ctx, size_t hint) -{ - char *data = NULL; - ssize_t alloc_size = 0, offset = 0, ret; - int p; - - if (hint <= 0) hint = 0x100; - - do { - alloc_size += hint; - - data = talloc_realloc(mem_ctx, data, char, alloc_size); - - if (!data) - return NULL; - - ret = read(fd, data + offset, hint); - - if (ret == -1) { - talloc_free(data); - return NULL; - } - - /* Find newline */ - for (p = 0; p < ret; p++) { - if (data[offset + p] == '\n') - break; - } - - if (p < ret) { - data[offset + p] = '\0'; - - /* Go back to position of newline */ - lseek(fd, p - ret + 1, SEEK_CUR); - return data; - } - - offset += ret; - - } while (ret == hint); - - data[offset] = '\0'; - - return data; -} - - -/**************************************************************************** -load a file into memory from a fd. -****************************************************************************/ - -char *fd_load(int fd, size_t *size, TALLOC_CTX *mem_ctx) -{ - struct stat sbuf; - char *p; - - if (fstat(fd, &sbuf) != 0) return NULL; - - p = (char *)talloc_size(mem_ctx, sbuf.st_size+1); - if (!p) return NULL; - - if (read(fd, p, sbuf.st_size) != sbuf.st_size) { - talloc_free(p); - return NULL; - } - p[sbuf.st_size] = 0; - - if (size) *size = sbuf.st_size; - - return p; -} - -/**************************************************************************** -load a file into memory -****************************************************************************/ -char *file_load(const char *fname, size_t *size, TALLOC_CTX *mem_ctx) -{ - int fd; - char *p; - - if (!fname || !*fname) return NULL; - - fd = open(fname,O_RDONLY); - if (fd == -1) return NULL; - - p = fd_load(fd, size, mem_ctx); - - close(fd); - - return p; -} - - -/******************************************************************* -mmap (if possible) or read a file -********************************************************************/ -void *map_file(const char *fname, size_t size) -{ - size_t s2 = 0; - void *p = NULL; -#ifdef HAVE_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; - } -#endif - if (!p) { - p = file_load(fname, &s2, talloc_autofree_context()); - if (!p) return NULL; - if (s2 != size) { - DEBUG(1,("incorrect size for %s - got %d expected %d\n", - fname, (int)s2, (int)size)); - talloc_free(p); - return NULL; - } - } - - return p; -} - - -/**************************************************************************** -parse a buffer into lines -****************************************************************************/ -static char **file_lines_parse(char *p, size_t size, int *numlines, TALLOC_CTX *mem_ctx) -{ - int i; - char *s, **ret; - - if (!p) return NULL; - - for (s = p, i=0; s < p+size; s++) { - if (s[0] == '\n') i++; - } - - ret = talloc_array(mem_ctx, char *, i+2); - if (!ret) { - talloc_free(p); - return NULL; - } - - talloc_reference(ret, p); - - memset(ret, 0, sizeof(ret[0])*(i+2)); - if (numlines) *numlines = i; - - ret[0] = p; - for (s = p, i=0; s < p+size; s++) { - if (s[0] == '\n') { - s[0] = 0; - i++; - ret[i] = s+1; - } - 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 talloc_free(). -****************************************************************************/ -char **file_lines_load(const char *fname, int *numlines, TALLOC_CTX *mem_ctx) -{ - char *p; - char **lines; - size_t size; - - p = file_load(fname, &size, mem_ctx); - if (!p) return NULL; - - lines = file_lines_parse(p, size, numlines, mem_ctx); - - talloc_free(p); - - return lines; -} - -/**************************************************************************** -load a fd into memory and return an array of pointers to lines in the file -must be freed with talloc_free(). If convert is true calls unix_to_dos on -the list. -****************************************************************************/ -char **fd_lines_load(int fd, int *numlines, TALLOC_CTX *mem_ctx) -{ - char *p; - char **lines; - size_t size; - - p = fd_load(fd, &size, mem_ctx); - if (!p) return NULL; - - lines = file_lines_parse(p, size, numlines, mem_ctx); - - talloc_free(p); - - return lines; -} - - -/**************************************************************************** -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; - - for (i=0; lines[i];) { - int len = strlen(lines[i]); - if (lines[i][len-1] == '\\') { - 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]; - } - } else { - i++; - } - } -} - -/* - save a lump of data into a file. Mostly used for debugging -*/ -BOOL file_save(const char *fname, const void *packet, size_t length) -{ - int fd; - fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0644); - if (fd == -1) { - return False; - } - if (write(fd, packet, length) != (size_t)length) { - return False; - } - close(fd); - return True; -} - -/* - see if a file exists -*/ -BOOL file_exists(const char *path) -{ - struct stat st; - return (stat(path, &st) == 0); -} - -int vfdprintf(int fd, const char *format, va_list ap) _PRINTF_ATTRIBUTE(2,0) -{ - char *p; - int len, ret; - va_list ap2; - - VA_COPY(ap2, ap); - - len = vasprintf(&p, format, ap2); - if (len <= 0) return len; - ret = write(fd, p, len); - SAFE_FREE(p); - return ret; -} - -int fdprintf(int fd, const char *format, ...) _PRINTF_ATTRIBUTE(2,3) -{ - va_list ap; - int ret; - - va_start(ap, format); - ret = vfdprintf(fd, format, ap); - va_end(ap); - return ret; -} diff --git a/source4/lib/util_getent.c b/source4/lib/util_getent.c deleted file mode 100644 index 9f58472fb8c..00000000000 --- a/source4/lib/util_getent.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba utility functions - Copyright (C) Simo Sorce 2001 - Copyright (C) Jeremy Allison 2001 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 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. -*/ - -#include "includes.h" - - -/**************************************************************** - Returns a single linked list of group entries. - Use grent_free() to free it after use. -****************************************************************/ - -struct sys_grent * getgrent_list(void) -{ - struct sys_grent *glist; - struct sys_grent *gent; - struct group *grp; - - gent = malloc_p(struct sys_grent); - if (gent == NULL) { - DEBUG (0, ("Out of memory in getgrent_list!\n")); - return NULL; - } - memset(gent, '\0', sizeof(struct sys_grent)); - glist = gent; - - setgrent(); - grp = getgrent(); - if (grp == NULL) { - endgrent(); - SAFE_FREE(glist); - return NULL; - } - - while (grp != NULL) { - int i,num; - - if (grp->gr_name) { - if ((gent->gr_name = strdup(grp->gr_name)) == NULL) - goto err; - } - if (grp->gr_passwd) { - if ((gent->gr_passwd = strdup(grp->gr_passwd)) == NULL) - goto err; - } - gent->gr_gid = grp->gr_gid; - - /* number of strings in gr_mem */ - for (num = 0; grp->gr_mem[num]; num++) - ; - - /* alloc space for gr_mem string pointers */ - if ((gent->gr_mem = malloc_array_p(char *, num+1)) == NULL) - goto err; - - memset(gent->gr_mem, '\0', (num+1) * sizeof(char *)); - - for (i=0; i < num; i++) { - if ((gent->gr_mem[i] = strdup(grp->gr_mem[i])) == NULL) - goto err; - } - gent->gr_mem[num] = NULL; - - grp = getgrent(); - if (grp) { - gent->next = malloc_p(struct sys_grent); - if (gent->next == NULL) - goto err; - gent = gent->next; - memset(gent, '\0', sizeof(struct sys_grent)); - } - } - - endgrent(); - return glist; - - err: - - endgrent(); - DEBUG(0, ("Out of memory in getgrent_list!\n")); - grent_free(glist); - return NULL; -} - -/**************************************************************** - Free the single linked list of group entries made by - getgrent_list() -****************************************************************/ - -void grent_free (struct sys_grent *glist) -{ - while (glist) { - struct sys_grent *prev; - - SAFE_FREE(glist->gr_name); - SAFE_FREE(glist->gr_passwd); - if (glist->gr_mem) { - int i; - for (i = 0; glist->gr_mem[i]; i++) - SAFE_FREE(glist->gr_mem[i]); - SAFE_FREE(glist->gr_mem); - } - prev = glist; - glist = glist->next; - SAFE_FREE(prev); - } -} - -/**************************************************************** - Returns a single linked list of passwd entries. - Use pwent_free() to free it after use. -****************************************************************/ - -struct sys_pwent * getpwent_list(void) -{ - struct sys_pwent *plist; - struct sys_pwent *pent; - struct passwd *pwd; - - pent = malloc_p(struct sys_pwent); - if (pent == NULL) { - DEBUG (0, ("Out of memory in getpwent_list!\n")); - return NULL; - } - plist = pent; - - setpwent(); - pwd = getpwent(); - while (pwd != NULL) { - memset(pent, '\0', sizeof(struct sys_pwent)); - if (pwd->pw_name) { - if ((pent->pw_name = strdup(pwd->pw_name)) == NULL) - goto err; - } - if (pwd->pw_passwd) { - if ((pent->pw_passwd = strdup(pwd->pw_passwd)) == NULL) - goto err; - } - pent->pw_uid = pwd->pw_uid; - pent->pw_gid = pwd->pw_gid; - if (pwd->pw_gecos) { - if ((pent->pw_name = strdup(pwd->pw_gecos)) == NULL) - goto err; - } - if (pwd->pw_dir) { - if ((pent->pw_name = strdup(pwd->pw_dir)) == NULL) - goto err; - } - if (pwd->pw_shell) { - if ((pent->pw_name = strdup(pwd->pw_shell)) == NULL) - goto err; - } - - pwd = getpwent(); - if (pwd) { - pent->next = malloc_p(struct sys_pwent); - if (pent->next == NULL) - goto err; - pent = pent->next; - } - } - - endpwent(); - return plist; - - err: - - endpwent(); - DEBUG(0, ("Out of memory in getpwent_list!\n")); - pwent_free(plist); - return NULL; -} - -/**************************************************************** - Free the single linked list of passwd entries made by - getpwent_list() -****************************************************************/ - -void pwent_free (struct sys_pwent *plist) -{ - while (plist) { - struct sys_pwent *prev; - - SAFE_FREE(plist->pw_name); - SAFE_FREE(plist->pw_passwd); - SAFE_FREE(plist->pw_gecos); - SAFE_FREE(plist->pw_dir); - SAFE_FREE(plist->pw_shell); - - prev = plist; - plist = plist->next; - SAFE_FREE(prev); - } -} - -/**************************************************************** - Add the individual group users onto the list. -****************************************************************/ - -static struct sys_userlist *add_members_to_userlist(struct sys_userlist *list_head, const struct group *grp) -{ - size_t num_users, i; - - /* Count the number of users. */ - for (num_users = 0; grp->gr_mem[num_users]; num_users++) - ; - - for (i = 0; i < num_users; i++) { - struct sys_userlist *entry = malloc_p(struct sys_userlist); - if (entry == NULL) { - free_userlist(list_head); - return NULL; - } - entry->unix_name = (char *)strdup(grp->gr_mem[i]); - if (entry->unix_name == NULL) { - SAFE_FREE(entry); - free_userlist(list_head); - return NULL; - } - DLIST_ADD(list_head, entry); - } - return list_head; -} - -/**************************************************************** - Get the list of UNIX users in a group. - We have to enumerate the /etc/group file as some UNIX getgrnam() - calls won't do that for us (notably Tru64 UNIX). -****************************************************************/ - -struct sys_userlist *get_users_in_group(const char *gname) -{ - struct sys_userlist *list_head = NULL; - struct group *gptr; - -#if !defined(BROKEN_GETGRNAM) - if ((gptr = (struct group *)getgrnam(gname)) == NULL) - return NULL; - return add_members_to_userlist(list_head, gptr); -#else - /* BROKEN_GETGRNAM - True64 */ - setgrent(); - while((gptr = getgrent()) != NULL) { - if (strequal(gname, gptr->gr_name)) { - list_head = add_members_to_userlist(list_head, gptr); - if (list_head == NULL) - return NULL; - } - } - endgrent(); - return list_head; -#endif -} - -/**************************************************************** - Free list allocated above. -****************************************************************/ - -void free_userlist(struct sys_userlist *list_head) -{ - while (list_head) { - struct sys_userlist *old_head = list_head; - DLIST_REMOVE(list_head, list_head); - SAFE_FREE(old_head->unix_name); - SAFE_FREE(old_head); - } -} diff --git a/source4/lib/util_pw.c b/source4/lib/util_pw.c deleted file mode 100644 index 19893e396f9..00000000000 --- a/source4/lib/util_pw.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Safe versions of getpw* calls - - Copyright (C) Andrew Bartlett 2002 - - 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. -*/ - -#include "includes.h" - -static struct passwd *alloc_copy_passwd(const struct passwd *from) -{ - struct passwd *ret = smb_xmalloc_p(struct passwd); - ZERO_STRUCTP(ret); - ret->pw_name = smb_xstrdup(from->pw_name); - ret->pw_passwd = smb_xstrdup(from->pw_passwd); - ret->pw_uid = from->pw_uid; - ret->pw_gid = from->pw_gid; - ret->pw_gecos = smb_xstrdup(from->pw_gecos); - ret->pw_dir = smb_xstrdup(from->pw_dir); - ret->pw_shell = smb_xstrdup(from->pw_shell); - return ret; -} - -void passwd_free (struct passwd **buf) -{ - if (!*buf) { - DEBUG(0, ("attempted double-free of allocated passwd\n")); - return; - } - - SAFE_FREE((*buf)->pw_name); - SAFE_FREE((*buf)->pw_passwd); - SAFE_FREE((*buf)->pw_gecos); - SAFE_FREE((*buf)->pw_dir); - SAFE_FREE((*buf)->pw_shell); - - SAFE_FREE(*buf); -} - -struct passwd *getpwnam_alloc(const char *name) -{ - struct passwd *temp; - - temp = sys_getpwnam(name); - - if (!temp) { -#if 0 - if (errno == ENOMEM) { - /* what now? */ - } -#endif - return NULL; - } - - return alloc_copy_passwd(temp); -} - -struct passwd *getpwuid_alloc(uid_t uid) -{ - struct passwd *temp; - - temp = sys_getpwuid(uid); - - if (!temp) { -#if 0 - if (errno == ENOMEM) { - /* what now? */ - } -#endif - return NULL; - } - - return alloc_copy_passwd(temp); -} diff --git a/source4/lib/util_sock.c b/source4/lib/util_sock.c deleted file mode 100644 index 8a65a27d020..00000000000 --- a/source4/lib/util_sock.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba utility functions - Copyright (C) Andrew Tridgell 1992-1998 - Copyright (C) Tim Potter 2000-2001 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 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. -*/ - -#include "includes.h" -#include "system/network.h" - -enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON}; - -static const struct { - const char *name; - int level; - int option; - int value; - int opttype; -} socket_options[] = { - {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL}, - {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL}, - {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL}, -#ifdef TCP_NODELAY - {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL}, -#endif -#ifdef IPTOS_LOWDELAY - {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON}, -#endif -#ifdef IPTOS_THROUGHPUT - {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON}, -#endif -#ifdef SO_REUSEPORT - {"SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, 0, OPT_BOOL}, -#endif -#ifdef SO_SNDBUF - {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT}, -#endif -#ifdef SO_RCVBUF - {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT}, -#endif -#ifdef SO_SNDLOWAT - {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT}, -#endif -#ifdef SO_RCVLOWAT - {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT}, -#endif -#ifdef SO_SNDTIMEO - {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT}, -#endif -#ifdef SO_RCVTIMEO - {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT}, -#endif - {NULL,0,0,0,0}}; - - -/**************************************************************************** - Set user socket options. -****************************************************************************/ -void set_socket_options(int fd, const char *options) -{ - const char **options_list = str_list_make(NULL, options, " \t,"); - int j; - - if (!options_list) - return; - - for (j = 0; options_list[j]; j++) { - const char *tok = options_list[j]; - int ret=0,i; - int value = 1; - char *p; - BOOL got_value = False; - - if ((p = strchr_m(tok,'='))) { - *p = 0; - value = atoi(p+1); - got_value = True; - } - - for (i=0;socket_options[i].name;i++) - if (strequal(socket_options[i].name,tok)) - break; - - if (!socket_options[i].name) { - DEBUG(0,("Unknown socket option %s\n",tok)); - continue; - } - - switch (socket_options[i].opttype) { - case OPT_BOOL: - case OPT_INT: - ret = setsockopt(fd,socket_options[i].level, - socket_options[i].option,(char *)&value,sizeof(int)); - break; - - case OPT_ON: - if (got_value) - DEBUG(0,("syntax error - %s does not take a value\n",tok)); - - { - int on = socket_options[i].value; - ret = setsockopt(fd,socket_options[i].level, - socket_options[i].option,(char *)&on,sizeof(int)); - } - break; - } - - if (ret != 0) - DEBUG(0,("Failed to set socket option %s (Error %s)\n",tok, strerror(errno) )); - } - - talloc_free(options_list); -} - diff --git a/source4/lib/util_str.c b/source4/lib/util_str.c deleted file mode 100644 index b46787e3ea2..00000000000 --- a/source4/lib/util_str.c +++ /dev/null @@ -1,1209 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba utility functions - - Copyright (C) Andrew Tridgell 1992-2001 - Copyright (C) Simo Sorce 2001-2002 - Copyright (C) Martin Pool 2003 - Copyright (C) James Peach 2005 - - 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. -*/ - -#include "includes.h" -#include "system/iconv.h" -#include "smb.h" -#include "pstring.h" -#include "lib/ldb/include/ldb.h" - -/** - * @file - * @brief String utilities. - **/ - -/** - * Get the next token from a string, return False if none found. - * Handles double-quotes. - * - * Based on a routine by GJC@VILLAGE.COM. - * Extensively modified by Andrew.Tridgell@anu.edu.au - **/ -BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize) -{ - const char *s; - BOOL quoted; - size_t len=1; - - if (!ptr) - return(False); - - s = *ptr; - - /* default to simple separators */ - if (!sep) - sep = " \t\n\r"; - - /* find the first non sep char */ - while (*s && strchr_m(sep,*s)) - s++; - - /* nothing left? */ - if (! *s) - return(False); - - /* copy over the token */ - for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) { - if (*s == '\"') { - quoted = !quoted; - } else { - len++; - *buff++ = *s; - } - } - - *ptr = (*s) ? s+1 : s; - *buff = 0; - - return(True); -} - -/** - Case insensitive string compararison -**/ -int strcasecmp_m(const char *s1, const char *s2) -{ - codepoint_t c1=0, c2=0; - size_t size1, size2; - - while (*s1 && *s2) { - c1 = next_codepoint(s1, &size1); - c2 = next_codepoint(s2, &size2); - - s1 += size1; - s2 += size2; - - if (c1 == c2) { - continue; - } - - if (c1 == INVALID_CODEPOINT || - c2 == INVALID_CODEPOINT) { - /* what else can we do?? */ - return c1 - c2; - } - - if (toupper_w(c1) != toupper_w(c2)) { - return c1 - c2; - } - } - - return *s1 - *s2; -} - -/** - * Compare 2 strings. - * - * @note The comparison is case-insensitive. - **/ -BOOL strequal(const char *s1, const char *s2) -{ - if (s1 == s2) - return(True); - if (!s1 || !s2) - return(False); - - return strcasecmp_m(s1,s2) == 0; -} - -/** - Compare 2 strings (case sensitive). -**/ -BOOL strcsequal(const char *s1,const char *s2) -{ - if (s1 == s2) - return(True); - if (!s1 || !s2) - return(False); - - return strcmp(s1,s2) == 0; -} - - -/** -Do a case-insensitive, whitespace-ignoring string compare. -**/ -int strwicmp(const char *psz1, const char *psz2) -{ - /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */ - /* appropriate value. */ - if (psz1 == psz2) - return (0); - else if (psz1 == NULL) - return (-1); - else if (psz2 == NULL) - return (1); - - /* sync the strings on first non-whitespace */ - while (1) { - while (isspace((int)*psz1)) - psz1++; - while (isspace((int)*psz2)) - psz2++; - if (toupper((unsigned char)*psz1) != toupper((unsigned char)*psz2) - || *psz1 == '\0' - || *psz2 == '\0') - break; - psz1++; - psz2++; - } - return (*psz1 - *psz2); -} - -/** - String replace. - NOTE: oldc and newc must be 7 bit characters -**/ -void string_replace(char *s, char oldc, char newc) -{ - while (*s) { - size_t size; - codepoint_t c = next_codepoint(s, &size); - if (c == oldc) { - *s = newc; - } - s += size; - } -} - -/** - Trim the specified elements off the front and back of a string. -**/ -BOOL trim_string(char *s,const char *front,const char *back) -{ - BOOL ret = False; - size_t front_len; - size_t back_len; - size_t len; - - /* Ignore null or empty strings. */ - if (!s || (s[0] == '\0')) - return False; - - front_len = front? strlen(front) : 0; - back_len = back? strlen(back) : 0; - - len = strlen(s); - - if (front_len) { - while (len && strncmp(s, front, front_len)==0) { - /* Must use memmove here as src & dest can - * easily overlap. Found by valgrind. JRA. */ - memmove(s, s+front_len, (len-front_len)+1); - len -= front_len; - ret=True; - } - } - - if (back_len) { - while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) { - s[len-back_len]='\0'; - len -= back_len; - ret=True; - } - } - return ret; -} - -/** - Find the number of 'c' chars in a string -**/ -size_t count_chars(const char *s, char c) -{ - size_t count = 0; - - while (*s) { - size_t size; - codepoint_t c2 = next_codepoint(s, &size); - if (c2 == c) count++; - s += size; - } - - return count; -} - -/** - Safe string copy into a known length string. maxlength does not - include the terminating zero. -**/ -char *safe_strcpy(char *dest,const char *src, size_t maxlength) -{ - size_t len; - - if (!dest) { - DEBUG(0,("ERROR: NULL dest in safe_strcpy\n")); - return NULL; - } - -#ifdef DEVELOPER - /* We intentionally write out at the extremity of the destination - * string. If the destination is too short (e.g. pstrcpy into mallocd - * or fstring) then this should cause an error under a memory - * checker. */ - dest[maxlength] = '\0'; - if (PTR_DIFF(&len, dest) > 0) { /* check if destination is on the stack, ok if so */ - log_suspicious_usage("safe_strcpy", src); - } -#endif - - if (!src) { - *dest = 0; - return dest; - } - - len = strlen(src); - - if (len > maxlength) { - DEBUG(0,("ERROR: string overflow by %u (%u - %u) in safe_strcpy [%.50s]\n", - (uint_t)(len-maxlength), (unsigned)len, (unsigned)maxlength, src)); - len = maxlength; - } - - memmove(dest, src, len); - dest[len] = 0; - return dest; -} - -/** - Safe string cat into a string. maxlength does not - include the terminating zero. -**/ -char *safe_strcat(char *dest, const char *src, size_t maxlength) -{ - size_t src_len, dest_len; - - if (!dest) { - DEBUG(0,("ERROR: NULL dest in safe_strcat\n")); - return NULL; - } - - if (!src) - return dest; - -#ifdef DEVELOPER - if (PTR_DIFF(&src_len, dest) > 0) { /* check if destination is on the stack, ok if so */ - log_suspicious_usage("safe_strcat", src); - } -#endif - src_len = strlen(src); - dest_len = strlen(dest); - - if (src_len + dest_len > maxlength) { - DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n", - (int)(src_len + dest_len - maxlength), src)); - if (maxlength > dest_len) { - memcpy(&dest[dest_len], src, maxlength - dest_len); - } - dest[maxlength] = 0; - return NULL; - } - - memcpy(&dest[dest_len], src, src_len); - dest[dest_len + src_len] = 0; - return dest; -} - -/** - Paranoid strcpy into a buffer of given length (includes terminating - zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars - and replaces with '_'. Deliberately does *NOT* check for multibyte - characters. Don't change it ! -**/ - -char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength) -{ - size_t len, i; - - if (maxlength == 0) { - /* can't fit any bytes at all! */ - return NULL; - } - - if (!dest) { - DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n")); - return NULL; - } - - if (!src) { - *dest = 0; - return dest; - } - - len = strlen(src); - if (len >= maxlength) - len = maxlength - 1; - - if (!other_safe_chars) - other_safe_chars = ""; - - for(i = 0; i < len; i++) { - int val = (src[i] & 0xff); - if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val)) - dest[i] = src[i]; - else - dest[i] = '_'; - } - - dest[i] = '\0'; - - return dest; -} - -/** - Like strncpy but always null terminates. Make sure there is room! - The variable n should always be one less than the available size. -**/ - -char *StrnCpy(char *dest,const char *src,size_t n) -{ - char *d = dest; - if (!dest) - return(NULL); - if (!src) { - *dest = 0; - return(dest); - } - while (n-- && (*d++ = *src++)) - ; - *d = 0; - return(dest); -} - - -/** - Routine to get hex characters and turn them into a 16 byte array. - the array can be variable length, and any non-hex-numeric - characters are skipped. "0xnn" or "0Xnn" is specially catered - for. - - valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n" - - -**/ -size_t strhex_to_str(char *p, size_t len, const char *strhex) -{ - size_t i; - size_t num_chars = 0; - uint8_t lonybble, hinybble; - const char *hexchars = "0123456789ABCDEF"; - char *p1 = NULL, *p2 = NULL; - - for (i = 0; i < len && strhex[i] != 0; i++) { - if (strncasecmp(hexchars, "0x", 2) == 0) { - i++; /* skip two chars */ - continue; - } - - if (!(p1 = strchr_m(hexchars, toupper((unsigned char)strhex[i])))) - break; - - i++; /* next hex digit */ - - if (!(p2 = strchr_m(hexchars, toupper((unsigned char)strhex[i])))) - break; - - /* get the two nybbles */ - hinybble = PTR_DIFF(p1, hexchars); - lonybble = PTR_DIFF(p2, hexchars); - - p[num_chars] = (hinybble << 4) | lonybble; - num_chars++; - - p1 = NULL; - p2 = NULL; - } - return num_chars; -} - -DATA_BLOB strhex_to_data_blob(const char *strhex) -{ - DATA_BLOB ret_blob = data_blob(NULL, strlen(strhex)/2+1); - - ret_blob.length = strhex_to_str((char *)ret_blob.data, - strlen(strhex), - strhex); - - return ret_blob; -} - - -/** - * Routine to print a buffer as HEX digits, into an allocated string. - */ -void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer) -{ - int i; - char *hex_buffer; - - *out_hex_buffer = smb_xmalloc((len*2)+1); - hex_buffer = *out_hex_buffer; - - for (i = 0; i < len; i++) - slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]); -} - -/** - Check if a string is part of a list. -**/ -BOOL in_list(const char *s, const char *list, BOOL casesensitive) -{ - pstring tok; - const char *p=list; - - if (!list) - return(False); - - while (next_token(&p,tok,LIST_SEP,sizeof(tok))) { - if (casesensitive) { - if (strcmp(tok,s) == 0) - return(True); - } else { - if (strcasecmp_m(tok,s) == 0) - return(True); - } - } - return(False); -} - -/** - Set a string value, allocing the space for the string -**/ -static BOOL string_init(char **dest,const char *src) -{ - if (!src) src = ""; - - (*dest) = strdup(src); - if ((*dest) == NULL) { - DEBUG(0,("Out of memory in string_init\n")); - return False; - } - return True; -} - -/** - Free a string value. -**/ -void string_free(char **s) -{ - if (s) SAFE_FREE(*s); -} - -/** - Set a string value, deallocating any existing space, and allocing the space - for the string -**/ -BOOL string_set(char **dest, const char *src) -{ - string_free(dest); - return string_init(dest,src); -} - -/** - Substitute a string for a pattern in another string. Make sure there is - enough room! - - This routine looks for pattern in s and replaces it with - insert. It may do multiple replacements. - - Any of " ; ' $ or ` in the insert string are replaced with _ - if len==0 then the string cannot be extended. This is different from the old - use of len==0 which was for no length checks to be done. -**/ - -void string_sub(char *s,const char *pattern, const char *insert, size_t len) -{ - char *p; - ssize_t ls,lp,li, i; - - if (!insert || !pattern || !*pattern || !s) - return; - - ls = (ssize_t)strlen(s); - lp = (ssize_t)strlen(pattern); - li = (ssize_t)strlen(insert); - - if (len == 0) - len = ls + 1; /* len is number of *bytes* */ - - while (lp <= ls && (p = strstr(s,pattern))) { - if (ls + (li-lp) >= len) { - DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", - (int)(ls + (li-lp) - len), - pattern, (int)len)); - break; - } - if (li != lp) { - memmove(p+li,p+lp,strlen(p+lp)+1); - } - for (i=0;i= len) { - DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", - (int)(ls + (li-lp) - len), - pattern, (int)len)); - break; - } - if (li != lp) { - memmove(p+li,p+lp,strlen(p+lp)+1); - } - memcpy(p, insert, li); - s = p + li; - ls += (li-lp); - } -} - - -/** - Strchr and strrchr_m are a bit complex on general multi-byte strings. -**/ -char *strchr_m(const char *s, char c) -{ - /* characters below 0x3F are guaranteed to not appear in - non-initial position in multi-byte charsets */ - if ((c & 0xC0) == 0) { - return strchr(s, c); - } - - while (*s) { - size_t size; - codepoint_t c2 = next_codepoint(s, &size); - if (c2 == c) { - return discard_const(s); - } - s += size; - } - - return NULL; -} - -char *strrchr_m(const char *s, char c) -{ - char *ret = NULL; - - /* characters below 0x3F are guaranteed to not appear in - non-initial position in multi-byte charsets */ - if ((c & 0xC0) == 0) { - return strrchr(s, c); - } - - while (*s) { - size_t size; - codepoint_t c2 = next_codepoint(s, &size); - if (c2 == c) { - ret = discard_const(s); - } - s += size; - } - - return ret; -} - -/* - return True if any (multi-byte) character is lower case -*/ -BOOL strhaslower(const char *string) -{ - while (*string) { - size_t c_size; - codepoint_t s; - codepoint_t t; - - s = next_codepoint(string, &c_size); - string += c_size; - - t = toupper_w(s); - - if (s != t) { - return True; /* that means it has lower case chars */ - } - } - - return False; -} - -/* - return True if any (multi-byte) character is upper case -*/ -BOOL strhasupper(const char *string) -{ - while (*string) { - size_t c_size; - codepoint_t s; - codepoint_t t; - - s = next_codepoint(string, &c_size); - string += c_size; - - t = tolower_w(s); - - if (s != t) { - return True; /* that means it has upper case chars */ - } - } - - return False; -} - -/** - Convert a string to lower case, allocated with talloc -**/ -char *strlower_talloc(TALLOC_CTX *ctx, const char *src) -{ - size_t size=0; - char *dest; - - /* this takes advantage of the fact that upper/lower can't - change the length of a character by more than 1 byte */ - dest = talloc_size(ctx, 2*(strlen(src))+1); - if (dest == NULL) { - return NULL; - } - - while (*src) { - size_t c_size; - codepoint_t c = next_codepoint(src, &c_size); - src += c_size; - - c = tolower_w(c); - - c_size = push_codepoint(dest+size, c); - if (c_size == -1) { - talloc_free(dest); - return NULL; - } - size += c_size; - } - - dest[size] = 0; - - return dest; -} - -/** - Convert a string to UPPER case, allocated with talloc -**/ -char *strupper_talloc(TALLOC_CTX *ctx, const char *src) -{ - size_t size=0; - char *dest; - - if (!src) { - return NULL; - } - - /* this takes advantage of the fact that upper/lower can't - change the length of a character by more than 1 byte */ - dest = talloc_size(ctx, 2*(strlen(src))+1); - if (dest == NULL) { - return NULL; - } - - while (*src) { - size_t c_size; - codepoint_t c = next_codepoint(src, &c_size); - src += c_size; - - c = toupper_w(c); - - c_size = push_codepoint(dest+size, c); - if (c_size == -1) { - talloc_free(dest); - return NULL; - } - size += c_size; - } - - dest[size] = 0; - - return dest; -} - -/** - Convert a string to lower case. -**/ -void strlower_m(char *s) -{ - char *d; - - /* this is quite a common operation, so we want it to be - fast. We optimise for the ascii case, knowing that all our - supported multi-byte character sets are ascii-compatible - (ie. they match for the first 128 chars) */ - while (*s && !(((uint8_t)*s) & 0x80)) { - *s = tolower((uint8_t)*s); - s++; - } - - if (!*s) - return; - - d = s; - - while (*s) { - size_t c_size, c_size2; - codepoint_t c = next_codepoint(s, &c_size); - c_size2 = push_codepoint(d, tolower_w(c)); - if (c_size2 > c_size) { - DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strlower_m\n", - c, tolower_w(c), (int)c_size, (int)c_size2)); - smb_panic("codepoint expansion in strlower_m\n"); - } - s += c_size; - d += c_size2; - } - *d = 0; -} - -/** - Convert a string to UPPER case. -**/ -void strupper_m(char *s) -{ - char *d; - - /* this is quite a common operation, so we want it to be - fast. We optimise for the ascii case, knowing that all our - supported multi-byte character sets are ascii-compatible - (ie. they match for the first 128 chars) */ - while (*s && !(((uint8_t)*s) & 0x80)) { - *s = toupper((uint8_t)*s); - s++; - } - - if (!*s) - return; - - d = s; - - while (*s) { - size_t c_size, c_size2; - codepoint_t c = next_codepoint(s, &c_size); - c_size2 = push_codepoint(d, toupper_w(c)); - if (c_size2 > c_size) { - DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strupper_m\n", - c, toupper_w(c), (int)c_size, (int)c_size2)); - smb_panic("codepoint expansion in strupper_m\n"); - } - s += c_size; - d += c_size2; - } - *d = 0; -} - -/** - Count the number of UCS2 characters in a string. Normally this will - be the same as the number of bytes in a string for single byte strings, - but will be different for multibyte. -**/ -size_t strlen_m(const char *s) -{ - size_t count = 0; - - if (!s) { - return 0; - } - - while (*s && !(((uint8_t)*s) & 0x80)) { - s++; - count++; - } - - if (!*s) { - return count; - } - - while (*s) { - size_t c_size; - codepoint_t c = next_codepoint(s, &c_size); - if (c < 0x10000) { - count += 1; - } else { - count += 2; - } - s += c_size; - } - - return count; -} - -/** - Work out the number of multibyte chars in a string, including the NULL - terminator. -**/ -size_t strlen_m_term(const char *s) -{ - if (!s) { - return 0; - } - - return strlen_m(s) + 1; -} - -/** - Unescape a URL encoded string, in place. -**/ - -void rfc1738_unescape(char *buf) -{ - char *p=buf; - - while ((p=strchr_m(p,'+'))) - *p = ' '; - - p = buf; - - while (p && *p && (p=strchr_m(p,'%'))) { - int c1 = p[1]; - int c2 = p[2]; - - if (c1 >= '0' && c1 <= '9') - c1 = c1 - '0'; - else if (c1 >= 'A' && c1 <= 'F') - c1 = 10 + c1 - 'A'; - else if (c1 >= 'a' && c1 <= 'f') - c1 = 10 + c1 - 'a'; - else {p++; continue;} - - if (c2 >= '0' && c2 <= '9') - c2 = c2 - '0'; - else if (c2 >= 'A' && c2 <= 'F') - c2 = 10 + c2 - 'A'; - else if (c2 >= 'a' && c2 <= 'f') - c2 = 10 + c2 - 'a'; - else {p++; continue;} - - *p = (c1<<4) | c2; - - memmove(p+1, p+3, strlen(p+3)+1); - p++; - } -} - -/** - * Decode a base64 string into a DATA_BLOB - simple and slow algorithm - **/ -DATA_BLOB base64_decode_data_blob(TALLOC_CTX *mem_ctx, const char *s) -{ - DATA_BLOB ret = data_blob_talloc(mem_ctx, s, strlen(s)+1); - ret.length = ldb_base64_decode((char *)ret.data); - return ret; -} - -/** - * Decode a base64 string in-place - wrapper for the above - **/ -void base64_decode_inplace(char *s) -{ - ldb_base64_decode(s); -} - -/** - * Encode a base64 string into a talloc()ed string caller to free. - **/ -char *base64_encode_data_blob(TALLOC_CTX *mem_ctx, DATA_BLOB data) -{ - return ldb_base64_encode(mem_ctx, (const char *)data.data, data.length); -} - -#ifdef VALGRIND -size_t valgrind_strlen(const char *s) -{ - size_t count; - for(count = 0; *s++; count++) - ; - return count; -} -#endif - - -/* - format a string into length-prefixed dotted domain format, as used in NBT - and in some ADS structures -*/ -const char *str_format_nbt_domain(TALLOC_CTX *mem_ctx, const char *s) -{ - char *ret; - int i; - if (!s || !*s) { - return talloc_strdup(mem_ctx, ""); - } - ret = talloc_size(mem_ctx, strlen(s)+2); - if (!ret) { - return ret; - } - - memcpy(ret+1, s, strlen(s)+1); - ret[0] = '.'; - - for (i=0;ret[i];i++) { - if (ret[i] == '.') { - char *p = strchr(ret+i+1, '.'); - if (p) { - ret[i] = p-(ret+i+1); - } else { - ret[i] = strlen(ret+i+1); - } - } - } - - return ret; -} - -BOOL add_string_to_array(TALLOC_CTX *mem_ctx, - const char *str, const char ***strings, int *num) -{ - char *dup_str = talloc_strdup(mem_ctx, str); - - *strings = talloc_realloc(mem_ctx, - *strings, - const char *, ((*num)+1)); - - if ((*strings == NULL) || (dup_str == NULL)) - return False; - - (*strings)[*num] = dup_str; - *num += 1; - - return True; -} - - - -/* - varient of strcmp() that handles NULL ptrs -*/ -int strcmp_safe(const char *s1, const char *s2) -{ - if (s1 == s2) { - return 0; - } - if (s1 == NULL || s2 == NULL) { - return s1?-1:1; - } - return strcmp(s1, s2); -} - - -/******************************************************************* -return the number of bytes occupied by a buffer in ASCII format -the result includes the null termination -limited by 'n' bytes -********************************************************************/ -size_t ascii_len_n(const char *src, size_t n) -{ - size_t len; - - len = strnlen(src, n); - if (len+1 <= n) { - len += 1; - } - - return len; -} - - -/******************************************************************* - Return a string representing a CIFS attribute for a file. -********************************************************************/ -char *attrib_string(TALLOC_CTX *mem_ctx, uint32_t attrib) -{ - int i, len; - const struct { - char c; - uint16_t attr; - } attr_strs[] = { - {'V', FILE_ATTRIBUTE_VOLUME}, - {'D', FILE_ATTRIBUTE_DIRECTORY}, - {'A', FILE_ATTRIBUTE_ARCHIVE}, - {'H', FILE_ATTRIBUTE_HIDDEN}, - {'S', FILE_ATTRIBUTE_SYSTEM}, - {'N', FILE_ATTRIBUTE_NORMAL}, - {'R', FILE_ATTRIBUTE_READONLY}, - {'d', FILE_ATTRIBUTE_DEVICE}, - {'t', FILE_ATTRIBUTE_TEMPORARY}, - {'s', FILE_ATTRIBUTE_SPARSE}, - {'r', FILE_ATTRIBUTE_REPARSE_POINT}, - {'c', FILE_ATTRIBUTE_COMPRESSED}, - {'o', FILE_ATTRIBUTE_OFFLINE}, - {'n', FILE_ATTRIBUTE_NONINDEXED}, - {'e', FILE_ATTRIBUTE_ENCRYPTED} - }; - char *ret; - - ret = talloc_size(mem_ctx, ARRAY_SIZE(attr_strs)+1); - if (!ret) { - return NULL; - } - - for (len=i=0; ibufused) return -1; - - /* on files being read full buffering is the only option */ - if ((f->open_flags & O_ACCMODE) == O_RDONLY) { - mode = X_IOFBF; - } - - /* destroy any earlier buffer */ - SAFE_FREE(f->buf); - f->buf = 0; - f->bufsize = 0; - f->next = NULL; - f->bufused = 0; - f->buftype = mode; - - if (f->buftype == X_IONBF) return 0; - - /* if buffering then we need some size */ - if (size == 0) size = XBUFSIZE; - - f->bufsize = size; - f->bufused = 0; - - return 0; -} - -/* allocate the buffer */ -static int x_allocate_buffer(XFILE *f) -{ - if (f->buf) return 1; - if (f->bufsize == 0) return 0; - f->buf = malloc(f->bufsize); - if (!f->buf) return 0; - f->next = f->buf; - return 1; -} - - -/* this looks more like open() than fopen(), but that is quite deliberate. - I want programmers to *think* about O_EXCL, O_CREAT etc not just - get them magically added -*/ -XFILE *x_fopen(const char *fname, int flags, mode_t mode) -{ - XFILE *ret; - - ret = malloc_p(XFILE); - if (!ret) return NULL; - - memset(ret, 0, sizeof(XFILE)); - - if ((flags & O_ACCMODE) == O_RDWR) { - /* we don't support RDWR in XFILE - use file - descriptors instead */ - errno = EINVAL; - return NULL; - } - - ret->open_flags = flags; - - ret->fd = open(fname, flags, mode); - if (ret->fd == -1) { - SAFE_FREE(ret); - return NULL; - } - - x_setvbuf(ret, NULL, X_IOFBF, XBUFSIZE); - - return ret; -} - -/* simulate fclose() */ -int x_fclose(XFILE *f) -{ - int ret; - - /* make sure we flush any buffered data */ - x_fflush(f); - - ret = close(f->fd); - f->fd = -1; - if (f->buf) { - /* make sure data can't leak into a later malloc */ - memset(f->buf, 0, f->bufsize); - SAFE_FREE(f->buf); - } - /* check the file descriptor given to the function is NOT one of the static - * descriptor of this libreary or we will free unallocated memory - * --sss */ - if (f != x_stdin && f != x_stdout && f != x_stderr) { - SAFE_FREE(f); - } - return ret; -} - -/* simulate fwrite() */ -size_t x_fwrite(const void *p, size_t size, size_t nmemb, XFILE *f) -{ - ssize_t ret; - size_t total=0; - - /* we might be writing unbuffered */ - if (f->buftype == X_IONBF || - (!f->buf && !x_allocate_buffer(f))) { - ret = write(f->fd, p, size*nmemb); - if (ret == -1) return -1; - return ret/size; - } - - - while (total < size*nmemb) { - size_t n = f->bufsize - f->bufused; - n = MIN(n, (size*nmemb)-total); - - if (n == 0) { - /* it's full, flush it */ - x_fflush(f); - continue; - } - - memcpy(f->buf + f->bufused, total+(const char *)p, n); - f->bufused += n; - total += n; - } - - /* when line buffered we need to flush at the last linefeed. This can - flush a bit more than necessary, but that is harmless */ - if (f->buftype == X_IOLBF && f->bufused) { - int i; - for (i=(size*nmemb)-1; i>=0; i--) { - if (*(i+(const char *)p) == '\n') { - x_fflush(f); - break; - } - } - } - - return total/size; -} - -/* thank goodness for asprintf() */ - int x_vfprintf(XFILE *f, const char *format, va_list ap) -{ - char *p; - int len, ret; - va_list ap2; - - VA_COPY(ap2, ap); - - len = vasprintf(&p, format, ap2); - if (len <= 0) return len; - ret = x_fwrite(p, 1, len, f); - SAFE_FREE(p); - return ret; -} - - int x_fprintf(XFILE *f, const char *format, ...) -{ - va_list ap; - int ret; - - va_start(ap, format); - ret = x_vfprintf(f, format, ap); - va_end(ap); - return ret; -} - -/* at least fileno() is simple! */ -int x_fileno(XFILE *f) -{ - return f->fd; -} - -/* simulate fflush() */ -int x_fflush(XFILE *f) -{ - int ret; - - if (f->flags & X_FLAG_ERROR) return -1; - - if ((f->open_flags & O_ACCMODE) != O_WRONLY) { - errno = EINVAL; - return -1; - } - - if (f->bufused == 0) return 0; - - ret = write(f->fd, f->buf, f->bufused); - if (ret == -1) return -1; - - f->bufused -= ret; - if (f->bufused > 0) { - f->flags |= X_FLAG_ERROR; - memmove(f->buf, ret + (char *)f->buf, f->bufused); - return -1; - } - - return 0; -} - -/* simulate setbuffer() */ -void x_setbuffer(XFILE *f, char *buf, size_t size) -{ - x_setvbuf(f, buf, buf?X_IOFBF:X_IONBF, size); -} - -/* simulate setbuf() */ -void x_setbuf(XFILE *f, char *buf) -{ - x_setvbuf(f, buf, buf?X_IOFBF:X_IONBF, XBUFSIZE); -} - -/* simulate setlinebuf() */ -void x_setlinebuf(XFILE *f) -{ - x_setvbuf(f, NULL, X_IOLBF, 0); -} - - -/* simulate feof() */ -int x_feof(XFILE *f) -{ - if (f->flags & X_FLAG_EOF) return 1; - return 0; -} - -/* simulate ferror() */ -int x_ferror(XFILE *f) -{ - if (f->flags & X_FLAG_ERROR) return 1; - return 0; -} - -/* fill the read buffer */ -static void x_fillbuf(XFILE *f) -{ - int n; - - if (f->bufused) return; - - if (!f->buf && !x_allocate_buffer(f)) return; - - n = read(f->fd, f->buf, f->bufsize); - if (n <= 0) return; - f->bufused = n; - f->next = f->buf; -} - -/* simulate fgetc() */ -int x_fgetc(XFILE *f) -{ - int ret; - - if (f->flags & (X_FLAG_EOF | X_FLAG_ERROR)) return EOF; - - if (f->bufused == 0) x_fillbuf(f); - - if (f->bufused == 0) { - f->flags |= X_FLAG_EOF; - return EOF; - } - - ret = *(uint8_t *)(f->next); - f->next++; - f->bufused--; - return ret; -} - -/* simulate fread */ -size_t x_fread(void *p, size_t size, size_t nmemb, XFILE *f) -{ - size_t total = 0; - while (total < size*nmemb) { - int c = x_fgetc(f); - if (c == EOF) break; - (total+(char *)p)[0] = (char)c; - total++; - } - return total/size; -} - -/* simulate fgets() */ -char *x_fgets(char *s, int size, XFILE *stream) -{ - char *s0 = s; - int l = size; - while (l>1) { - int c = x_fgetc(stream); - if (c == EOF) break; - *s++ = (char)c; - l--; - if (c == '\n') break; - } - if (l==size || x_ferror(stream)) { - return 0; - } - *s = 0; - return s0; -} - -/* trivial seek, works only for SEEK_SET and SEEK_END if SEEK_CUR is - * set then an error is returned */ -off_t x_tseek(XFILE *f, off_t offset, int whence) -{ - if (f->flags & X_FLAG_ERROR) - return -1; - - /* only SEEK_SET and SEEK_END are supported */ - /* SEEK_CUR needs internal offset counter */ - if (whence != SEEK_SET && whence != SEEK_END) { - f->flags |= X_FLAG_EINVAL; - errno = EINVAL; - return -1; - } - - /* empty the buffer */ - switch (f->open_flags & O_ACCMODE) { - case O_RDONLY: - f->bufused = 0; - break; - case O_WRONLY: - if (x_fflush(f) != 0) - return -1; - break; - default: - errno = EINVAL; - return -1; - } - - f->flags &= ~X_FLAG_EOF; - return lseek(f->fd, offset, whence); -} diff --git a/source4/lib/xfile.h b/source4/lib/xfile.h deleted file mode 100644 index 89fa9d1e118..00000000000 --- a/source4/lib/xfile.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - Unix SMB/CIFS implementation. - stdio replacement - Copyright (C) Andrew Tridgell 2001 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 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. -*/ - -#ifndef _XFILE_H_ -#define _XFILE_H_ -/* - see xfile.c for explanations -*/ - -typedef struct { - int fd; - char *buf; - char *next; - int bufsize; - int bufused; - int open_flags; - int buftype; - int flags; -} XFILE; - -extern XFILE *x_stdin, *x_stdout, *x_stderr; - -/* buffering type */ -#define X_IOFBF 0 -#define X_IOLBF 1 -#define X_IONBF 2 - -#define x_getc(f) x_fgetc(f) - -int x_vfprintf(XFILE *f, const char *format, va_list ap) PRINTF_ATTRIBUTE(2, 0); -int x_fprintf(XFILE *f, const char *format, ...) PRINTF_ATTRIBUTE(2, 3); -#endif /* _XFILE_H_ */ diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index 0b9cac4c07c..e8cb5480075 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -23,6 +23,7 @@ #include "includes.h" #include "system/filesys.h" #include "libcli/raw/libcliraw.h" +#include "libcli/libcli.h" /**************************************************************************** Hard/Symlink a file (UNIX extensions). diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 49fe085f2cf..034878a464a 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -19,8 +19,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - /* this structure is just a wrapper for a string, the only reason we bother with this is that it allows us to check the length provided on the wire in testsuite test code to ensure that we are diff --git a/source4/libcli/raw/ioctl.h b/source4/libcli/raw/ioctl.h new file mode 100644 index 00000000000..cd658c121b5 --- /dev/null +++ b/source4/libcli/raw/ioctl.h @@ -0,0 +1,33 @@ +/* + Unix SMB/CIFS implementation. + ioctl and fsctl definitions + + Copyright (C) Andrew Tridgell 2003 + + 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. +*/ + + +/* ioctl codes */ +#define IOCTL_QUERY_JOB_INFO 0x530060 + + +/* filesystem control codes */ +#define FSCTL_FILESYSTEM 0x90000 +#define FSCTL_SET_SPARSE (FSCTL_FILESYSTEM | (49<<2)) +#define FSCTL_REQUEST_BATCH_OPLOCK (FSCTL_FILESYSTEM | (2<<2)) + +#define FSCTL_NAMED_PIPE 0x110000 +#define FSCTL_NAMED_PIPE_READ_WRITE (FSCTL_NAMED_PIPE | 0xc017) diff --git a/source4/libcli/raw/signing.h b/source4/libcli/raw/signing.h index dfc5a4bd7e1..cea8556c2c4 100644 --- a/source4/libcli/raw/signing.h +++ b/source4/libcli/raw/signing.h @@ -27,6 +27,10 @@ enum smb_signing_engine_state { SMB_SIGNING_ENGINE_ON }; +enum smb_signing_state { + SMB_SIGNING_OFF, SMB_SIGNING_SUPPORTED, + SMB_SIGNING_REQUIRED, SMB_SIGNING_AUTO}; + struct smb_signing_context { enum smb_signing_engine_state signing_state; DATA_BLOB mac_key; diff --git a/source4/libcli/raw/trans2.h b/source4/libcli/raw/trans2.h new file mode 100644 index 00000000000..a3f6e28a2af --- /dev/null +++ b/source4/libcli/raw/trans2.h @@ -0,0 +1,435 @@ +/* + Unix SMB/CIFS implementation. + SMB transaction2 handling + Copyright (C) Jeremy Allison 1994-2002. + Copyright (C) Andrew Tridgell 1995-2003. + + 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. +*/ + +#ifndef _TRANS2_H_ +#define _TRANS2_H_ + +/* These are the TRANS2 sub commands */ +#define TRANSACT2_OPEN 0 +#define TRANSACT2_FINDFIRST 1 +#define TRANSACT2_FINDNEXT 2 +#define TRANSACT2_QFSINFO 3 +#define TRANSACT2_SETFSINFO 4 +#define TRANSACT2_QPATHINFO 5 +#define TRANSACT2_SETPATHINFO 6 +#define TRANSACT2_QFILEINFO 7 +#define TRANSACT2_SETFILEINFO 8 +#define TRANSACT2_FSCTL 9 +#define TRANSACT2_IOCTL 0xA +#define TRANSACT2_FINDNOTIFYFIRST 0xB +#define TRANSACT2_FINDNOTIFYNEXT 0xC +#define TRANSACT2_MKDIR 0xD +#define TRANSACT2_SESSION_SETUP 0xE +#define TRANSACT2_GET_DFS_REFERRAL 0x10 +#define TRANSACT2_REPORT_DFS_INCONSISTANCY 0x11 + + +/* trans2 Query FS info levels */ +/* +w2k3 TRANS2ALIASES: +Checking for QFSINFO aliases + Found level 1 (0x001) of size 18 (0x12) + Found level 2 (0x002) of size 12 (0x0c) + Found level 258 (0x102) of size 26 (0x1a) + Found level 259 (0x103) of size 24 (0x18) + Found level 260 (0x104) of size 8 (0x08) + Found level 261 (0x105) of size 20 (0x14) + Found level 1001 (0x3e9) of size 26 (0x1a) + Found level 1003 (0x3eb) of size 24 (0x18) + Found level 1004 (0x3ec) of size 8 (0x08) + Found level 1005 (0x3ed) of size 20 (0x14) + Found level 1006 (0x3ee) of size 48 (0x30) + Found level 1007 (0x3ef) of size 32 (0x20) + Found level 1008 (0x3f0) of size 64 (0x40) +Found 13 levels with success status + Level 261 (0x105) and level 1005 (0x3ed) are possible aliases + Level 260 (0x104) and level 1004 (0x3ec) are possible aliases + Level 259 (0x103) and level 1003 (0x3eb) are possible aliases + Level 258 (0x102) and level 1001 (0x3e9) are possible aliases +Found 4 aliased levels +*/ +#define SMB_QFS_ALLOCATION 1 +#define SMB_QFS_VOLUME 2 +#define SMB_QFS_VOLUME_INFO 0x102 +#define SMB_QFS_SIZE_INFO 0x103 +#define SMB_QFS_DEVICE_INFO 0x104 +#define SMB_QFS_ATTRIBUTE_INFO 0x105 +#define SMB_QFS_UNIX_INFO 0x200 +#define SMB_QFS_POSIX_INFO 0x201 +#define SMB_QFS_VOLUME_INFORMATION 1001 +#define SMB_QFS_SIZE_INFORMATION 1003 +#define SMB_QFS_DEVICE_INFORMATION 1004 +#define SMB_QFS_ATTRIBUTE_INFORMATION 1005 +#define SMB_QFS_QUOTA_INFORMATION 1006 +#define SMB_QFS_FULL_SIZE_INFORMATION 1007 +#define SMB_QFS_OBJECTID_INFORMATION 1008 + + +/* trans2 qfileinfo/qpathinfo */ +/* w2k3 TRANS2ALIASES: +Checking for QPATHINFO aliases +setting up complex file \qpathinfo_aliases.txt + Found level 1 (0x001) of size 22 (0x16) + Found level 2 (0x002) of size 26 (0x1a) + Found level 4 (0x004) of size 41 (0x29) + Found level 6 (0x006) of size 0 (0x00) + Found level 257 (0x101) of size 40 (0x28) + Found level 258 (0x102) of size 24 (0x18) + Found level 259 (0x103) of size 4 (0x04) + Found level 260 (0x104) of size 48 (0x30) + Found level 263 (0x107) of size 126 (0x7e) + Found level 264 (0x108) of size 28 (0x1c) + Found level 265 (0x109) of size 38 (0x26) + Found level 267 (0x10b) of size 16 (0x10) + Found level 1004 (0x3ec) of size 40 (0x28) + Found level 1005 (0x3ed) of size 24 (0x18) + Found level 1006 (0x3ee) of size 8 (0x08) + Found level 1007 (0x3ef) of size 4 (0x04) + Found level 1008 (0x3f0) of size 4 (0x04) + Found level 1009 (0x3f1) of size 48 (0x30) + Found level 1014 (0x3f6) of size 8 (0x08) + Found level 1016 (0x3f8) of size 4 (0x04) + Found level 1017 (0x3f9) of size 4 (0x04) + Found level 1018 (0x3fa) of size 126 (0x7e) + Found level 1021 (0x3fd) of size 28 (0x1c) + Found level 1022 (0x3fe) of size 38 (0x26) + Found level 1028 (0x404) of size 16 (0x10) + Found level 1034 (0x40a) of size 56 (0x38) + Found level 1035 (0x40b) of size 8 (0x08) +Found 27 levels with success status + Level 267 (0x10b) and level 1028 (0x404) are possible aliases + Level 265 (0x109) and level 1022 (0x3fe) are possible aliases + Level 264 (0x108) and level 1021 (0x3fd) are possible aliases + Level 263 (0x107) and level 1018 (0x3fa) are possible aliases + Level 260 (0x104) and level 1009 (0x3f1) are possible aliases + Level 259 (0x103) and level 1007 (0x3ef) are possible aliases + Level 258 (0x102) and level 1005 (0x3ed) are possible aliases + Level 257 (0x101) and level 1004 (0x3ec) are possible aliases +Found 8 aliased levels +*/ +#define SMB_QFILEINFO_STANDARD 1 +#define SMB_QFILEINFO_EA_SIZE 2 +#define SMB_QFILEINFO_EA_LIST 3 +#define SMB_QFILEINFO_ALL_EAS 4 +#define SMB_QFILEINFO_IS_NAME_VALID 6 /* only for QPATHINFO */ +#define SMB_QFILEINFO_BASIC_INFO 0x101 +#define SMB_QFILEINFO_STANDARD_INFO 0x102 +#define SMB_QFILEINFO_EA_INFO 0x103 +#define SMB_QFILEINFO_NAME_INFO 0x104 +#define SMB_QFILEINFO_ALL_INFO 0x107 +#define SMB_QFILEINFO_ALT_NAME_INFO 0x108 +#define SMB_QFILEINFO_STREAM_INFO 0x109 +#define SMB_QFILEINFO_COMPRESSION_INFO 0x10b +#define SMB_QFILEINFO_UNIX_BASIC 0x200 +#define SMB_QFILEINFO_UNIX_LINK 0x201 +#define SMB_QFILEINFO_BASIC_INFORMATION 1004 +#define SMB_QFILEINFO_STANDARD_INFORMATION 1005 +#define SMB_QFILEINFO_INTERNAL_INFORMATION 1006 +#define SMB_QFILEINFO_EA_INFORMATION 1007 +#define SMB_QFILEINFO_ACCESS_INFORMATION 1008 +#define SMB_QFILEINFO_NAME_INFORMATION 1009 +#define SMB_QFILEINFO_POSITION_INFORMATION 1014 +#define SMB_QFILEINFO_MODE_INFORMATION 1016 +#define SMB_QFILEINFO_ALIGNMENT_INFORMATION 1017 +#define SMB_QFILEINFO_ALL_INFORMATION 1018 +#define SMB_QFILEINFO_ALT_NAME_INFORMATION 1021 +#define SMB_QFILEINFO_STREAM_INFORMATION 1022 +#define SMB_QFILEINFO_COMPRESSION_INFORMATION 1028 +#define SMB_QFILEINFO_NETWORK_OPEN_INFORMATION 1034 +#define SMB_QFILEINFO_ATTRIBUTE_TAG_INFORMATION 1035 + + + +/* trans2 setfileinfo/setpathinfo levels */ +/* +w2k3 TRANS2ALIASES +Checking for SETFILEINFO aliases +setting up complex file \setfileinfo_aliases.txt + Found level 1 (0x001) of size 2 (0x02) + Found level 2 (0x002) of size 2 (0x02) + Found level 257 (0x101) of size 40 (0x28) + Found level 258 (0x102) of size 2 (0x02) + Found level 259 (0x103) of size 8 (0x08) + Found level 260 (0x104) of size 8 (0x08) + Found level 1004 (0x3ec) of size 40 (0x28) + Found level 1010 (0x3f2) of size 2 (0x02) + Found level 1013 (0x3f5) of size 2 (0x02) + Found level 1014 (0x3f6) of size 8 (0x08) + Found level 1016 (0x3f8) of size 4 (0x04) + Found level 1019 (0x3fb) of size 8 (0x08) + Found level 1020 (0x3fc) of size 8 (0x08) + Found level 1023 (0x3ff) of size 8 (0x08) + Found level 1025 (0x401) of size 16 (0x10) + Found level 1029 (0x405) of size 72 (0x48) + Found level 1032 (0x408) of size 56 (0x38) + Found level 1039 (0x40f) of size 8 (0x08) + Found level 1040 (0x410) of size 8 (0x08) +Found 19 valid levels + +Checking for SETPATHINFO aliases + Found level 1004 (0x3ec) of size 40 (0x28) + Found level 1010 (0x3f2) of size 2 (0x02) + Found level 1013 (0x3f5) of size 2 (0x02) + Found level 1014 (0x3f6) of size 8 (0x08) + Found level 1016 (0x3f8) of size 4 (0x04) + Found level 1019 (0x3fb) of size 8 (0x08) + Found level 1020 (0x3fc) of size 8 (0x08) + Found level 1023 (0x3ff) of size 8 (0x08) + Found level 1025 (0x401) of size 16 (0x10) + Found level 1029 (0x405) of size 72 (0x48) + Found level 1032 (0x408) of size 56 (0x38) + Found level 1039 (0x40f) of size 8 (0x08) + Found level 1040 (0x410) of size 8 (0x08) +Found 13 valid levels +*/ +#define SMB_SFILEINFO_STANDARD 1 +#define SMB_SFILEINFO_EA_SET 2 +#define SMB_SFILEINFO_BASIC_INFO 0x101 +#define SMB_SFILEINFO_DISPOSITION_INFO 0x102 +#define SMB_SFILEINFO_ALLOCATION_INFO 0x103 +#define SMB_SFILEINFO_END_OF_FILE_INFO 0x104 +#define SMB_SFILEINFO_UNIX_BASIC 0x200 +#define SMB_SFILEINFO_UNIX_LINK 0x201 +#define SMB_SPATHINFO_UNIX_HLINK 0x203 +#define SMB_SPATHINFO_POSIX_ACL 0x204 +#define SMB_SPATHINFO_XATTR 0x205 +#define SMB_SFILEINFO_ATTR_FLAGS 0x206 +#define SMB_SFILEINFO_BASIC_INFORMATION 1004 +#define SMB_SFILEINFO_RENAME_INFORMATION 1010 +#define SMB_SFILEINFO_DISPOSITION_INFORMATION 1013 +#define SMB_SFILEINFO_POSITION_INFORMATION 1014 +#define SMB_SFILEINFO_MODE_INFORMATION 1016 +#define SMB_SFILEINFO_ALLOCATION_INFORMATION 1019 +#define SMB_SFILEINFO_END_OF_FILE_INFORMATION 1020 + +/* filemon shows FilePipeInformation */ +#define SMB_SFILEINFO_1023 1023 + +/* filemon shows FilePipeRemoteInformation */ +#define SMB_SFILEINFO_1025 1025 + +/* filemon shows CopyOnWriteInformation */ +#define SMB_SFILEINFO_1029 1029 + +/* filemon shows OleClassIdInformation */ +#define SMB_SFILEINFO_1032 1032 + +/* seems to be the file size - perhaps valid data size? + filemon shows 'InheritContentIndexInfo' +*/ +#define SMB_SFILEINFO_1039 1039 + +/* OLE_INFORMATION? */ +#define SMB_SFILEINFO_1040 1040 + + +/* trans2 findfirst levels */ +/* +w2k3 TRANS2ALIASES: +Checking for FINDFIRST aliases + Found level 1 (0x001) of size 68 (0x44) + Found level 2 (0x002) of size 70 (0x46) + Found level 257 (0x101) of size 108 (0x6c) + Found level 258 (0x102) of size 116 (0x74) + Found level 259 (0x103) of size 60 (0x3c) + Found level 260 (0x104) of size 140 (0x8c) + Found level 261 (0x105) of size 124 (0x7c) + Found level 262 (0x106) of size 148 (0x94) +Found 8 levels with success status +Found 0 aliased levels +*/ +#define SMB_FIND_STANDARD 1 +#define SMB_FIND_EA_SIZE 2 +#define SMB_FIND_EA_LIST 3 +#define SMB_FIND_DIRECTORY_INFO 0x101 +#define SMB_FIND_FULL_DIRECTORY_INFO 0x102 +#define SMB_FIND_NAME_INFO 0x103 +#define SMB_FIND_BOTH_DIRECTORY_INFO 0x104 +#define SMB_FIND_ID_FULL_DIRECTORY_INFO 0x105 +#define SMB_FIND_ID_BOTH_DIRECTORY_INFO 0x106 +#define SMB_FIND_UNIX_INFO 0x202 + +/* flags on trans2 findfirst/findnext that control search */ +#define FLAG_TRANS2_FIND_CLOSE 0x1 +#define FLAG_TRANS2_FIND_CLOSE_IF_END 0x2 +#define FLAG_TRANS2_FIND_REQUIRE_RESUME 0x4 +#define FLAG_TRANS2_FIND_CONTINUE 0x8 +#define FLAG_TRANS2_FIND_BACKUP_INTENT 0x10 + +/* + * DeviceType and Characteristics returned in a + * SMB_QFS_DEVICE_INFO call. + */ +#define QFS_DEVICETYPE_CD_ROM 0x2 +#define QFS_DEVICETYPE_CD_ROM_FILE_SYSTEM 0x3 +#define QFS_DEVICETYPE_DISK 0x7 +#define QFS_DEVICETYPE_DISK_FILE_SYSTEM 0x8 +#define QFS_DEVICETYPE_FILE_SYSTEM 0x9 + +/* Characteristics. */ +#define QFS_TYPE_REMOVABLE_MEDIA 0x1 +#define QFS_TYPE_READ_ONLY_DEVICE 0x2 +#define QFS_TYPE_FLOPPY 0x4 +#define QFS_TYPE_WORM 0x8 +#define QFS_TYPE_REMOTE 0x10 +#define QFS_TYPE_MOUNTED 0x20 +#define QFS_TYPE_VIRTUAL 0x40 + + +/* + * Thursby MAC extensions.... + */ + +/* + * MAC CIFS Extensions have the range 0x300 - 0x2FF reserved. + * Supposedly Microsoft have agreed to this. + */ + +#define MIN_MAC_INFO_LEVEL 0x300 +#define MAX_MAC_INFO_LEVEL 0x3FF +#define SMB_QFS_MAC_FS_INFO 0x301 + + + +/* UNIX CIFS Extensions - created by HP */ +/* + * UNIX CIFS Extensions have the range 0x200 - 0x2FF reserved. + * Supposedly Microsoft have agreed to this. + */ + +#define MIN_UNIX_INFO_LEVEL 0x200 +#define MAX_UNIX_INFO_LEVEL 0x2FF + +#define INFO_LEVEL_IS_UNIX(level) (((level) >= MIN_UNIX_INFO_LEVEL) && ((level) <= MAX_UNIX_INFO_LEVEL)) + +#define SMB_QFILEINFO_UNIX_BASIC 0x200 /* UNIX File Info*/ +#define SMB_SFILEINFO_UNIX_BASIC 0x200 + +#define SMB_MODE_NO_CHANGE 0xFFFFFFFF /* file mode value which */ + /* means "don't change it" */ +#define SMB_UID_NO_CHANGE 0xFFFFFFFF +#define SMB_GID_NO_CHANGE 0xFFFFFFFF + +#define SMB_SIZE_NO_CHANGE_LO 0xFFFFFFFF +#define SMB_SIZE_NO_CHANGE_HI 0xFFFFFFFF + +#define SMB_TIME_NO_CHANGE_LO 0xFFFFFFFF +#define SMB_TIME_NO_CHANGE_HI 0xFFFFFFFF + +/* +Offset Size Name +0 LARGE_INTEGER EndOfFile File size +8 LARGE_INTEGER Blocks Number of bytes used on disk (st_blocks). +16 LARGE_INTEGER CreationTime Creation time +24 LARGE_INTEGER LastAccessTime Last access time +32 LARGE_INTEGER LastModificationTime Last modification time +40 LARGE_INTEGER Uid Numeric user id for the owner +48 LARGE_INTEGER Gid Numeric group id of owner +56 ULONG Type Enumeration specifying the pathname type: + 0 -- File + 1 -- Directory + 2 -- Symbolic link + 3 -- Character device + 4 -- Block device + 5 -- FIFO (named pipe) + 6 -- Unix domain socket + +60 LARGE_INTEGER devmajor Major device number if type is device +68 LARGE_INTEGER devminor Minor device number if type is device +76 LARGE_INTEGER uniqueid This is a server-assigned unique id for the file. The client + will typically map this onto an inode number. The scope of + uniqueness is the share. +84 LARGE_INTEGER permissions Standard UNIX file permissions - see below. +92 LARGE_INTEGER nlinks The number of directory entries that map to this entry + (number of hard links) + +100 - end. +*/ + +/* UNIX filetype mappings. */ + +#define UNIX_TYPE_FILE 0 +#define UNIX_TYPE_DIR 1 +#define UNIX_TYPE_SYMLINK 2 +#define UNIX_TYPE_CHARDEV 3 +#define UNIX_TYPE_BLKDEV 4 +#define UNIX_TYPE_FIFO 5 +#define UNIX_TYPE_SOCKET 6 +#define UNIX_TYPE_UNKNOWN 0xFFFFFFFF + +/* + * Oh this is fun. "Standard UNIX permissions" has no + * meaning in POSIX. We need to define the mapping onto + * and off the wire as this was not done in the original HP + * spec. JRA. + */ + +#define UNIX_X_OTH 0000001 +#define UNIX_W_OTH 0000002 +#define UNIX_R_OTH 0000004 +#define UNIX_X_GRP 0000010 +#define UNIX_W_GRP 0000020 +#define UNIX_R_GRP 0000040 +#define UNIX_X_USR 0000100 +#define UNIX_W_USR 0000200 +#define UNIX_R_USR 0000400 +#define UNIX_STICKY 0001000 +#define UNIX_SET_GID 0002000 +#define UNIX_SET_UID 0004000 + +/* Masks for the above */ +#define UNIX_OTH_MASK 0000007 +#define UNIX_GRP_MASK 0000070 +#define UNIX_USR_MASK 0000700 +#define UNIX_PERM_MASK 0000777 +#define UNIX_EXTRA_MASK 0007000 +#define UNIX_ALL_MASK 0007777 + +#define SMB_QFILEINFO_UNIX_LINK 0x201 +#define SMB_SFILEINFO_UNIX_LINK 0x201 +#define SMB_SFILEINFO_UNIX_HLINK 0x203 + +#define SMB_FIND_FILE_UNIX 0x202 + +/* + Info level for QVOLINFO - returns version of CIFS UNIX extensions, plus + 64-bits worth of capability fun :-). +*/ + +#define SMB_QUERY_CIFS_UNIX_INFO 0x200 + +/* Returns the following. + + UINT16 major version number + UINT16 minor version number + LARGE_INTEGER capability bitfield + +*/ + +#define CIFS_UNIX_MAJOR_VERSION 1 +#define CIFS_UNIX_MINOR_VERSION 0 + +#define CIFS_UNIX_FCNTL_LOCKS_CAP 0x1 +#define CIFS_UNIX_POSIX_ACLS_CAP 0x2 + +/* ... more as we think of them :-). */ + +#endif diff --git a/source4/librpc/rpc/dcerpc_smb2.c b/source4/librpc/rpc/dcerpc_smb2.c index 90882bd95ea..d22ef6a9f24 100644 --- a/source4/librpc/rpc/dcerpc_smb2.c +++ b/source4/librpc/rpc/dcerpc_smb2.c @@ -25,7 +25,7 @@ #include "libcli/composite/composite.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" -#include "ioctl.h" +#include "libcli/raw/ioctl.h" /* transport private information used by SMB2 pipe transport */ struct smb2_private { diff --git a/source4/main.mk b/source4/main.mk index 8f67e6ad9e0..98ee46cc7e5 100644 --- a/source4/main.mk +++ b/source4/main.mk @@ -246,7 +246,7 @@ include/includes.h: \ librpc/rpc/dcerpc.h \ auth/credentials/credentials_proto.h \ libcli/nbt/libnbt.h \ - lib/basic.h \ + lib/util/util_proto.h \ lib/charset/charset.h clean_pch: diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 3fc3c09316a..6548a2c1993 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -31,6 +31,7 @@ #include "messaging/messaging.h" #include "db_wrap.h" #include "lib/messaging/irpc.h" +#include "libcli/libcli.h" /* in this module a "DATA_BLOB *file_key" is a blob that uniquely identifies @@ -237,7 +238,7 @@ NTSTATUS brl_lock(struct brl_context *brl, struct lock_struct lock, *locks=NULL; NTSTATUS status; - kbuf.dptr = (char *)file_key->data; + kbuf.dptr = (uint8_t *)file_key->data; kbuf.dsize = file_key->length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { @@ -287,7 +288,7 @@ NTSTATUS brl_lock(struct brl_context *brl, status = NT_STATUS_NO_MEMORY; goto fail; } else { - dbuf.dptr = (char *)locks; + dbuf.dptr = (uint8_t *)locks; } locks[count] = lock; dbuf.dsize += sizeof(lock); @@ -382,7 +383,7 @@ NTSTATUS brl_unlock(struct brl_context *brl, struct lock_context context; NTSTATUS status; - kbuf.dptr = (char *)file_key->data; + kbuf.dptr = (uint8_t *)file_key->data; kbuf.dsize = file_key->length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 74b62809f7e..8194fc1963b 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -59,16 +59,6 @@ OBJ_FILES = \ # End MODULE ntvfs_nbench ################################################ -################################################ -# Start SUBSYSTEM ntvfs_common -[SUBSYSTEM::ntvfs_common] -OBJ_FILES = \ - common/brlock.o \ - common/opendb.o \ - common/sidmap.o -# End SUBSYSTEM ntvfs_common -################################################ - ################################################ # Start SUBSYSTEM NTVFS @@ -83,7 +73,10 @@ OBJ_FILES = \ ntvfs_base.o \ ntvfs_generic.o \ ntvfs_interface.o \ - ntvfs_util.o + ntvfs_util.o \ + common/brlock.o \ + common/opendb.o \ + common/sidmap.o # # End SUBSYSTEM NTVFS ################################################ diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index a2a4685d8c7..85fcc10e060 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -31,6 +31,6 @@ OBJ_FILES = \ pvfs_acl.o \ xattr_system.o \ xattr_tdb.o -REQUIRED_SUBSYSTEMS = NDR_XATTR ntvfs_common EXT_LIB_XATTR EXT_LIB_BLKID +REQUIRED_SUBSYSTEMS = NDR_XATTR EXT_LIB_XATTR EXT_LIB_BLKID # End MODULE ntvfs_posix ################################################ diff --git a/source4/ntvfs/posix/pvfs_ioctl.c b/source4/ntvfs/posix/pvfs_ioctl.c index abf575aa3df..b35a98fa875 100644 --- a/source4/ntvfs/posix/pvfs_ioctl.c +++ b/source4/ntvfs/posix/pvfs_ioctl.c @@ -22,7 +22,7 @@ #include "includes.h" #include "vfs_posix.h" -#include "ioctl.h" +#include "libcli/raw/ioctl.h" /* old ioctl interface diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index e933f5502bb..b0c34b2abed 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -23,7 +23,7 @@ */ #include "includes.h" -#include "ioctl.h" +#include "libcli/raw/ioctl.h" #include "smb_server/smb_server.h" #include "ntvfs/ntvfs.h" diff --git a/source4/ntvfs/unixuid/config.mk b/source4/ntvfs/unixuid/config.mk index d99229729c5..bb811bca2bd 100644 --- a/source4/ntvfs/unixuid/config.mk +++ b/source4/ntvfs/unixuid/config.mk @@ -5,7 +5,5 @@ INIT_FUNCTION = ntvfs_unixuid_init SUBSYSTEM = NTVFS OBJ_FILES = \ vfs_unixuid.o -REQUIRED_SUBSYSTEMS = \ - ntvfs_common # End MODULE ntvfs_unixuid ################################################ diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c index 96ba2bbc736..8fc061b53fd 100644 --- a/source4/param/loadparm.c +++ b/source4/param/loadparm.c @@ -61,6 +61,8 @@ #include "system/iconv.h" #include "librpc/gen_ndr/ndr_svcctl.h" #include "librpc/gen_ndr/ndr_samr.h" +#include "smb_server/smb_server.h" +#include "libcli/raw/signing.h" #include "dlinklist.h" #include "param/loadparm.h" diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index 914bb98eda0..b62e1abaefc 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -27,6 +27,7 @@ #include "auth/auth.h" #include "dsdb/samdb/samdb.h" #include "libcli/ldap/ldap.h" +#include "ntvfs/ntvfs.h" /* this type allows us to distinguish handle types diff --git a/source4/rpc_server/unixinfo/dcesrv_unixinfo.c b/source4/rpc_server/unixinfo/dcesrv_unixinfo.c index b85d3f144ed..1224daa76ab 100644 --- a/source4/rpc_server/unixinfo/dcesrv_unixinfo.c +++ b/source4/rpc_server/unixinfo/dcesrv_unixinfo.c @@ -25,6 +25,7 @@ #include "rpc_server/common/common.h" #include "librpc/gen_ndr/ndr_unixinfo.h" #include "lib/events/events.h" +#include "ntvfs/ntvfs.h" #include #include diff --git a/source4/script/mkversion.sh b/source4/script/mkversion.sh index 7f42eded238..7995027998f 100755 --- a/source4/script/mkversion.sh +++ b/source4/script/mkversion.sh @@ -8,7 +8,7 @@ if test -z "$VERSION_FILE";then fi if test -z "$OUTPUT_FILE";then - OUTPUT_FILE="include/version.h" + OUTPUT_FILE="version.h" fi SOURCE_DIR=$3 @@ -114,7 +114,7 @@ echo "#define SAMBA_VERSION_OFFICIAL_STRING \"${SAMBA_VERSION_STRING}\"" >> $OUT echo "#define SAMBA_VERSION_STRING samba_version_string()" >> $OUTPUT_FILE -echo "$0: 'include/version.h' created for Samba(\"${SAMBA_VERSION_STRING}\")" +echo "$0: 'version.h' created for Samba(\"${SAMBA_VERSION_STRING}\")" if test -n "${SAMBA_VERSION_RELEASE_NICKNAME}";then echo "$0: with RELEASE_NICKNAME = ${SAMBA_VERSION_RELEASE_NICKNAME}" diff --git a/source4/smb_server/smb_server.h b/source4/smb_server/smb_server.h index 0c201b2b1d0..5ba17998684 100644 --- a/source4/smb_server/smb_server.h +++ b/source4/smb_server/smb_server.h @@ -206,6 +206,8 @@ struct substitute_context { /* Remote architectures we know about. */ enum remote_arch_types {RA_UNKNOWN, RA_WFWG, RA_OS2, RA_WIN95, RA_WINNT, RA_WIN2K, RA_WINXP, RA_SAMBA}; +enum security_types {SEC_SHARE,SEC_USER} security; + /* smb server context structure. This should contain all the state * information associated with a SMB server connection */ diff --git a/source4/torture/raw/ioctl.c b/source4/torture/raw/ioctl.c index 0fb48c292b3..2c51e4d7b41 100644 --- a/source4/torture/raw/ioctl.c +++ b/source4/torture/raw/ioctl.c @@ -21,7 +21,7 @@ #include "includes.h" #include "torture/torture.h" -#include "ioctl.h" +#include "libcli/raw/ioctl.h" #include "libcli/raw/libcliraw.h" #include "libcli/libcli.h" diff --git a/source4/torture/torture.c b/source4/torture/torture.c index aad44e4a160..26137b18908 100644 --- a/source4/torture/torture.c +++ b/source4/torture/torture.c @@ -24,7 +24,7 @@ #include "system/time.h" #include "system/wait.h" #include "system/filesys.h" -#include "ioctl.h" +#include "libcli/raw/ioctl.h" #include "libcli/libcli.h" #include "librpc/rpc/dcerpc_table.h" diff --git a/source4/winbind/wb_samba3_cmd.c b/source4/winbind/wb_samba3_cmd.c index f930a6052d2..fd36dde16dc 100644 --- a/source4/winbind/wb_samba3_cmd.c +++ b/source4/winbind/wb_samba3_cmd.c @@ -26,7 +26,7 @@ #include "winbind/wb_server.h" #include "winbind/wb_async_helpers.h" #include "libcli/composite/composite.h" -#include "include/version.h" +#include "version.h" #include "librpc/gen_ndr/ndr_netlogon.h" /* -- cgit