lib/username.o \
lib/access.o lib/smbrun.o \
lib/bitmap.o lib/util_sid.o lib/snprintf.o \
- lib/util_str.o lib/util_unistr.o \
+ lib/util_str.o lib/util_unistr.o lib/util_wunistr.o \
lib/util_file.o \
lib/util_sock.o lib/util_sec.o lib/util_array.o \
lib/vagent.o \
rpc_client/cli_eventlog.o \
rpc_client/cli_dfs.o
-LOCKING_OBJ = locking/locking.o
+LOCKING_OBJ = lib/hash.o locking/locking.o locking/brlock.o
GROUPDB_OBJ = groupdb/groupdb.o groupdb/aliasdb.o groupdb/builtindb.o \
groupdb/groupfile.o groupdb/aliasfile.o \
PROFILE_OBJ = profile/profile.o
SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/connection.o \
- lib/set_uid.o \
- smbd/dfree.o smbd/dir.o smbd/password.o smbd/conn.o smbd/fileio.o \
- smbd/ipc.o smbd/lanman.o smbd/mangle.o smbd/negprot.o \
- smbd/message.o smbd/nttrans.o smbd/pipes.o smbd/predict.o \
- smbd/$(QUOTAOBJS) smbd/reply.o smbd/ssl.o smbd/trans2.o \
- smbd/uid.o \
- smbd/dosmode.o smbd/filename.o smbd/open.o smbd/close.o smbd/blocking.o \
- smbd/process.o smbd/oplock.o smbd/service.o smbd/error.o smbd/vfs.o \
- smbd/vfs-wrap.o smbd/dfs.o \
- smbd/challenge.o \
- lib/util_pwdb.o smbd/afsticket.o
+ lib/set_uid.o smbd/dfree.o smbd/dir.o smbd/password.o \
+ smbd/conn.o smbd/fileio.o \
+ smbd/ipc.o smbd/lanman.o smbd/mangle.o smbd/negprot.o \
+ smbd/message.o smbd/nttrans.o smbd/pipes.o smbd/predict.o \
+ smbd/$(QUOTAOBJS) smbd/reply.o smbd/ssl.o smbd/trans2.o \
+ smbd/uid.o smbd/dosmode.o smbd/filename.o smbd/open.o \
+ smbd/close.o smbd/blocking.o smbd/process.o smbd/oplock.o \
+ smbd/service.o smbd/error.o smbd/vfs.o smbd/vfs-wrap.o \
+ smbd/challenge.o lib/util_pwdb.o smbd/afsticket.o
+
PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/printing.o
+MSDFS_OBJ = msdfs/msdfs.o msdfs/msdfs_tdb.o msdfs/parse_dfs_map.o
+
MSRPCD_OBJ = msrpc/msrpcd.o \
msrpc/msrpcd_process.o \
lib/set_vuid.o \
spoolssd/srv_spoolss_nt.o \
printing/nt_printing.o
-SMBD_OBJ = $(SMBD_OBJ1) $(UNIXPASSDB_OBJ) \
+SMBD_OBJ = $(SMBD_OBJ1) $(MSDFS_OBJ) $(UNIXPASSDB_OBJ) \
$(RPC_SERVER_OBJ) \
lib/domain_namemap.o \
$(LOCKING_OBJ) \
SRVSVCD_OBJ = $(MSRPCD_OBJ) $(SRVSVCD_OBJ1) \
$(RPC_SRVUTIL_OBJ) \
- $(LOCKING_OBJ) $(PROFILE_OBJ) \
+ $(PROFILE_OBJ) \
$(SIDDB_OBJ) \
$(LIBSTATUS_OBJ)
WKSSVCD_OBJ = $(MSRPCD_OBJ) $(WKSSVCD_OBJ1) \
$(RPC_SRVUTIL_OBJ) \
$(SIDDB_OBJ) \
- $(LOCKING_OBJ) $(PROFILE_OBJ)
+ $(PROFILE_OBJ)
BROWSERD_OBJ = $(MSRPCD_OBJ) $(BROWSERD_OBJ1) \
$(RPC_SRVUTIL_OBJ) \
$(SIDDB_OBJ) \
- $(LOCKING_OBJ) $(PROFILE_OBJ)
+ $(PROFILE_OBJ)
WINREGD_OBJ = $(MSRPCD_OBJ) $(WINREGD_OBJ1) \
$(RPC_SRVUTIL_OBJ) \
$(SIDDB_OBJ) \
- $(LOCKING_OBJ) $(PROFILE_OBJ)
+ $(PROFILE_OBJ)
SVCCTLD_OBJ = $(MSRPCD_OBJ) $(SVCCTLD_OBJ1) \
$(RPC_SRVUTIL_OBJ) \
$(SIDDB_OBJ) \
- $(LOCKING_OBJ) $(PROFILE_OBJ)
+ $(PROFILE_OBJ)
LSARPCD_OBJ = $(MSRPCD_OBJ) $(LSARPCD_OBJ1) \
$(RPC_SRVUTIL_OBJ) \
- $(SIDDB_OBJ) $(LOCKING_OBJ) \
+ $(SIDDB_OBJ) \
$(PROFILE_OBJ)
LSARPCD_LIBS = $(SAMBA_LIBS)
$(PRINTING_OBJ) \
$(SIDDB_OBJ) \
$(RPC_SRVUTIL_OBJ) \
- $(LOCKING_OBJ) $(PROFILE_OBJ)
+ $(PROFILE_OBJ)
SPOOLSSD_LIBS = $(SAMBA_LIBS) $(UBIQXLIB)
NETLOGOND_OBJ = $(MSRPCD_OBJ) $(NETLOGOND_OBJ1) \
$(RPC_SRVUTIL_OBJ) \
- $(LOCKING_OBJ) \
$(SIDDB_OBJ) \
$(UNIXPASSDB_OBJ) $(LIBSTATUS_OBJ) $(PROFILE_OBJ)
SAMRD_OBJ = $(MSRPCD_OBJ) $(SAMRD_OBJ1) \
$(RPC_SRVUTIL_OBJ) \
- $(LOCKING_OBJ) \
$(SIDDB_OBJ) \
$(PROFILE_OBJ)
web/swat.o libsmb/passchange.o $(LOCKING_OBJ) \
rpc_server/srv_lookup.o \
$(SIDDB_OBJ) \
+ $(PRINTING_OBJ) \
$(UNIXPASSDB_OBJ) \
$(STUB_UID_OBJ)
@echo Linking $@
@$(LINK) -o $@ $(TESTPRNS_OBJ) $(SAMBALIB) $(LIBS)
-bin/smbstatus: $(SAMBALIB) $(STATUS_OBJ) bin/.dummy
+bin/smbstatus: $(SAMBALIB) $(UBIQXLIB) $(STATUS_OBJ) bin/.dummy
@echo Linking $@
- @$(LINK) -o $@ $(STATUS_OBJ) $(SAMBALIB) $(LIBS)
+ @$(LINK) -o $@ $(STATUS_OBJ) $(SAMBALIB) $(UBIQXLIB) $(LIBS)
bin/smbpasswd: $(SMBPASSWD_LIBS) $(SMBPASSWD_OBJ) bin/.dummy
@echo Linking $@
-f script/mkproto.awk `echo $(RPC_CLIENT_OBJ) | tr ' ' '\n' | sed -e 's/\.o/\.c/g' | sort -u | egrep -v 'ubiqx/|wrapped'` > include/rpc_client_proto.h
etags:
- etags `find . -name "*.[ch]"`
+ etags `find . -name "*.[ch]" | grep -v /CVS/`
ctags:
- ctags `find . -name "*.[ch]"`
+ ctags `find . -name "*.[ch]" | grep -v /CVS/`
realclean: clean
-rm -f config.log $(PROGS) $(SPROGS) bin/.dummy
timeout.tv_sec = 20;
timeout.tv_usec = 0;
- sys_select(MAX(cli->fd,fileno(stdin))+1,&fds,NULL, &timeout);
+ sys_select(MAX(cli->fd,fileno(stdin))+1,&fds,NULL,&timeout);
if (FD_ISSET(fileno(stdin),&fds))
return;
timeout.tv_sec = 20;
timeout.tv_usec = 0;
- selrtn = sys_select(MAX(Client,fileno(stdin))+1,&fds,NULL, &timeout);
+ selrtn = sys_select(MAX(Client,fileno(stdin))+1,&fds,NULL,&timeout);
if (FD_ISSET(fileno(stdin),&fds))
return;
fi
fi
-################################################
-# look for a method of setting the effective gid
-setegid=no;
-if test $setegid = no; then
-AC_CACHE_CHECK([for setresgid],samba_cv_USE_SETRESGID,[
-AC_TRY_RUN([
-#define AUTOCONF_TEST 1
-#define USE_SETRESUID 1
-#define USE_SETRESGID 1
-#include "confdefs.h"
-#include "${srcdir-.}/lib/util_sec.c"],
- samba_cv_USE_SETRESGID=yes,samba_cv_USE_SETRESGID=no,samba_cv_USE_SETRESGID=cross)])
-if test x"$samba_cv_USE_SETRESGID" = x"yes"; then
- setegid=yes;AC_DEFINE(USE_SETRESGID)
-fi
-fi
-
-
-if test $setegid = no; then
-AC_CACHE_CHECK([for setregid],samba_cv_USE_SETREGID,[
-AC_TRY_RUN([
-#define AUTOCONF_TEST 1
-#define USE_SETREUID 1
-#define USE_SETREGID 1
-#include "confdefs.h"
-#include "${srcdir-.}/lib/util_sec.c"],
- samba_cv_USE_SETREGID=yes,samba_cv_USE_SETREGID=no,samba_cv_USE_SETREGID=cross)])
-if test x"$samba_cv_USE_SETREGID" = x"yes"; then
- setegid=yes;AC_DEFINE(USE_SETREGID)
-fi
-fi
-
-if test $setegid = no; then
-AC_CACHE_CHECK([for setegid],samba_cv_USE_SETEGID,[
-AC_TRY_RUN([
-#define AUTOCONF_TEST 1
-#define USE_SETEUID 1
-#define USE_SETEGID 1
-#include "confdefs.h"
-#include "${srcdir-.}/lib/util_sec.c"],
- samba_cv_USE_SETEGID=yes,samba_cv_USE_SETEGID=no,samba_cv_USE_SETEGID=cross)])
-if test x"$samba_cv_USE_SETEGID" = x"yes"; then
- setegid=yes;AC_DEFINE(USE_SETEGID)
-fi
-fi
-
-if test $setegid = no; then
-AC_CACHE_CHECK([for setgidx],samba_cv_USE_SETGIDX,[
-AC_TRY_RUN([
-#define AUTOCONF_TEST 1
-#define USE_SETUIDX 1
-#define USE_SETGIDX 1
-#include "confdefs.h"
-#include "${srcdir-.}/lib/util_sec.c"],
- samba_cv_USE_SETGIDX=yes,samba_cv_USE_SETGIDX=no,samba_cv_USE_SETGIDX=cross)])
-if test x"$samba_cv_USE_SETGIDX" = x"yes"; then
- setegid=yes;AC_DEFINE(USE_SETGIDX)
-fi
-fi
AC_CACHE_CHECK([for shared mmap],samba_cv_HAVE_SHARED_MMAP,[
AC_TRY_RUN([#include "${srcdir-.}/tests/shared_mmap.c"],
echo "no"
fi
-# sometimes getopt_long cannot parse same arguments twice
-# e.g. on certain versions of CygWin32
-AC_CACHE_CHECK([for working getopt_long],samba_cv_HAVE_GETOPT_LONG,[
-AC_TRY_RUN([#include <getopt.h>
-main() {
- int i, x = 0; char *argv[] = { "x", "--xx" };
- struct option o[] = {{"xx", 0, 0, 1}, {0,0,0,0}};
- getopt_long(2, argv, "x", o, &i) == 1 ? x++ : 0; optind = 0;
- getopt_long(2, argv, "x", o, &i) == 1 ? x++ : 0;
- exit(x == 2 ? 0 : 1);
-}], samba_cv_HAVE_GETOPT_LONG=yes,samba_cv_HAVE_GETOPT_LONG=no,
- samba_cv_HAVE_GETOPT_LONG=cross)])
-if test x"$samba_cv_HAVE_GETOPT_LONG" = x"yes"; then
- AC_DEFINE(HAVE_GETOPT_LONG)
-fi
-
echo "checking configure summary"
AC_TRY_RUN([#include "${srcdir-.}/tests/summary.c"],
echo "configure OK";,
-*.lo
\ No newline at end of file
+.libs
+*.lo
+#ifndef _CHARSET_H
+#define _CHARSET_H
+
/*
Unix SMB/Netbios implementation.
Version 1.9.
#define CODEPAGE_VERSION_OFFSET 0
#define CODEPAGE_CLIENT_CODEPAGE_OFFSET 2
#define CODEPAGE_LENGTH_OFFSET 4
+
+/* Version id for dynamically loadable unicode map files. */
+#define UNICODE_MAP_FILE_VERSION_ID 0x8001
+/* Version 0x80000001 unicode map file header size. */
+#define UNICODE_MAP_HEADER_SIZE 30
+#define UNICODE_MAP_CODEPAGE_ID_SIZE 20
+/* Offsets for unicode map file header entries. */
+#define UNICODE_MAP_VERSION_OFFSET 0
+#define UNICODE_MAP_CLIENT_CODEPAGE_OFFSET 2
+#define UNICODE_MAP_CP_TO_UNICODE_LENGTH_OFFSET 22
+#define UNICODE_MAP_UNICODE_TO_CP_LENGTH_OFFSET 26
+
+#endif /* _CHARSET_H */
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef _DEBUG_H
-#define _DEBUG_H
+#ifndef _DEBUG_H_
+#define _DEBUG_H_
/* -------------------------------------------------------------------------- **
* Debugging code. See also debug.c
*/
#ifndef SMB_INO_T
-# ifdef HAVE_INO64_T
+# if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_INO64_T)
# define SMB_INO_T ino64_t
# else
# define SMB_INO_T ino_t
#endif
#ifndef LARGE_SMB_INO_T
-# if defined(HAVE_INO64_T) || (defined(SIZEOF_INO_T) && (SIZEOF_INO_T == 8))
+# if (defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_INO64_T)) || (defined(SIZEOF_INO_T) && (SIZEOF_INO_T == 8))
# define LARGE_SMB_INO_T 1
# endif
#endif
#endif
#ifndef SMB_OFF_T
-# ifdef HAVE_OFF64_T
+# if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T)
# define SMB_OFF_T off64_t
# else
# define SMB_OFF_T off_t
# endif
#endif
+/* this should really be a 64 bit type if possible */
+#define br_off SMB_BIG_UINT
+
#define SMB_OFF_T_BITS (sizeof(SMB_OFF_T)*8)
/*
*/
#ifndef LARGE_SMB_OFF_T
-# if defined(HAVE_OFF64_T) || (defined(SIZEOF_OFF_T) && (SIZEOF_OFF_T == 8))
+# if (defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T)) || (defined(SIZEOF_OFF_T) && (SIZEOF_OFF_T == 8))
# define LARGE_SMB_OFF_T 1
# endif
#endif
*/
#ifndef SMB_STRUCT_STAT
-# if defined(HAVE_STAT64) && defined(HAVE_OFF64_T)
+# if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_STAT64) && defined(HAVE_OFF64_T)
# define SMB_STRUCT_STAT struct stat64
# else
# define SMB_STRUCT_STAT struct stat
# endif
#endif
+/*
+ * Type for dirent structure.
+ */
+
+#ifndef SMB_STRUCT_DIRENT
+# if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_STRUCT_DIRENT64)
+# define SMB_STRUCT_DIRENT struct dirent64
+# else
+# define SMB_STRUCT_DIRENT struct dirent
+# endif
+#endif
+
/*
* Defines for 64 bit fcntl locks.
*/
#ifndef SMB_STRUCT_FLOCK
-# if defined(HAVE_STRUCT_FLOCK64) && defined(HAVE_OFF64_T)
+# if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_STRUCT_FLOCK64) && defined(HAVE_OFF64_T)
# define SMB_STRUCT_FLOCK struct flock64
# else
# define SMB_STRUCT_FLOCK struct flock
#endif
#ifndef SMB_F_SETLKW
-# if defined(HAVE_STRUCT_FLOCK64) && defined(HAVE_OFF64_T)
+# if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_STRUCT_FLOCK64) && defined(HAVE_OFF64_T)
# define SMB_F_SETLKW F_SETLKW64
# else
# define SMB_F_SETLKW F_SETLKW
#endif
#ifndef SMB_F_SETLK
-# if defined(HAVE_STRUCT_FLOCK64) && defined(HAVE_OFF64_T)
+# if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_STRUCT_FLOCK64) && defined(HAVE_OFF64_T)
# define SMB_F_SETLK F_SETLK64
# else
# define SMB_F_SETLK F_SETLK
#endif
#ifndef SMB_F_GETLK
-# if defined(HAVE_STRUCT_FLOCK64) && defined(HAVE_OFF64_T)
+# if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_STRUCT_FLOCK64) && defined(HAVE_OFF64_T)
# define SMB_F_GETLK F_GETLK64
# else
# define SMB_F_GETLK F_GETLK
#if defined(HAVE_LONGLONG)
#define SMB_BIG_UINT unsigned long long
#define SMB_BIG_INT long long
+#define SBIG_UINT(p, ofs, v) (SIVAL(p,ofs,(v)&0xFFFFFFFF), SIVAL(p,(ofs)+4,(v)>>32))
#else
#define SMB_BIG_UINT unsigned long
#define SMB_BIG_INT long
+#define SBIG_UINT(p, ofs, v) (SIVAL(p,ofs,v),SIVAL(p,(ofs)+4,0))
#endif
#ifndef MIN
#include "../tdb/tdb.h"
#include "talloc.h"
#include "interfaces.h"
+#include "hash.h"
#ifdef HAVE_FNMATCH
#include <fnmatch.h>
#include "kanji.h"
#include "charset.h"
+#include "msdfs.h"
+
#ifdef WITH_PROFILE
#include "profile.h"
#endif
#define MAXCODEPAGELINES 256
#endif
+/*
+ * Type for wide character dirent structure.
+ * Only d_name is defined by POSIX.
+ */
+
+typedef struct smb_wdirent {
+ wpstring d_name;
+} SMB_STRUCT_WDIRENT;
+
+/*
+ * Type for wide character passwd structure.
+ */
+
+typedef struct smb_wpasswd {
+ wfstring pw_name;
+ char *pw_passwd;
+ uid_t pw_uid;
+ gid_t pw_gid;
+ wpstring pw_gecos;
+ wpstring pw_dir;
+ wpstring pw_shell;
+} SMB_STRUCT_WPASSWD;
+
+/* Defines for wisXXX functions. */
+#define UNI_UPPER 0x1
+#define UNI_LOWER 0x2
+#define UNI_DIGIT 0x4
+#define UNI_XDIGIT 0x8
+#define UNI_SPACE 0x10
+
+#include "../lib/surs.h"
+
/***** automatically generated prototypes *****/
#include "ldapdb.h"
#include "proto.h"
#define bzero(a,b) memset((a),'\0',(b))
#endif
-#ifdef REPLACE_GETPASS
-#define getpass(prompt) getsmbpass((prompt))
+/*
+ * Some older systems seem not to have MAXHOSTNAMELEN
+ * defined.
+ */
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 254
+#endif
+
+/* yuck, I'd like a better way of doing this */
+#define DIRP_SIZE (256 + 32)
+
+/*
+ * glibc on linux doesn't seem to have MSG_WAITALL
+ * defined. I think the kernel has it though..
+ */
+
+#ifndef MSG_WAITALL
+#define MSG_WAITALL 0
+#endif
+
+/* default socket options. Dave Miller thinks we should default to TCP_NODELAY
+ given the socket IO pattern that Samba uses */
+#ifdef TCP_NODELAY
+#define DEFAULT_SOCKET_OPTIONS "TCP_NODELAY"
+#else
+#define DEFAULT_SOCKET_OPTIONS ""
#endif
-
+
+/* Load header file for libdl stuff */
+
+#ifdef HAVE_LIBDL
+#include <dlfcn.h>
+#endif
+
#ifdef USE_RENEWABLE_AFS_TICKET
#include "afsticket.h"
#endif /* USE_RENEWABLE_AFS_TICKET */
-/* yuck, I'd like a better way of doing this */
-#define DIRP_SIZE (256 + 32)
/* change initialization ... support for IRIX cc */
#define VUSER_KEY vuser_key key; key.pid=conn->smbd_pid; key.vuid=vuid
#endif /* _INCLUDES_H */
void pwd_set_cleartext(struct pwd_info *pwd, char *clr);
void pwd_get_cleartext(struct pwd_info *pwd, char *clr);
void pwd_set_lm_nt_16(struct pwd_info *pwd,
- const uchar lm_pwd[16],
- const uchar nt_pwd[16]);
-void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]);
+ const uchar lm_pwd[16], const uchar nt_pwd[16]);
+void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16],
+ uchar nt_pwd[16]);
void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr);
void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8],
- const char *user, const char *server, const char *domain,
- uchar sess_key[16]);
+ const char *user, const char *server,
+ const char *domain, uchar sess_key[16]);
void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8],
- uchar sess_key[16]);
+ uchar sess_key[16]);
void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24],
- uchar *nt_owf, size_t *nt_owf_len);
+ uchar * nt_owf, size_t * nt_owf_len);
/*The following definitions come from libsmb/smbdes.c */
void NTLMSSPOWFencrypt(const uchar pwrd[8], const uchar * ntlmchalresp,
uchar p24[24]);
void SMBNTencrypt(uchar * pwrd, uchar * c8, uchar * p24);
+BOOL make_oem_passwd_hash(uchar data[516],
+ const char *pwrd, int new_pw_len,
+ const uchar old_pw_hash[16], BOOL unicode);
void SMBOWFencrypt_ntv2(const uchar kr[16],
const uchar * srv_chal, int srv_chal_len,
const uchar * cli_chal, int cli_chal_len,
void lm_owf_genW(const UNISTR2 *pwd, uchar p16[16]);
void nt_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16]);
void nt_lm_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16], uchar lm_p16[16]);
-BOOL make_oem_passwd_hash(uchar data[516],
- const char *pwrd, int new_pw_len,
- const uchar old_pw_hash[16], BOOL unicode);
BOOL nt_encrypt_string2(STRING2 * out, const STRING2 * in, const uchar * key);
BOOL nt_decrypt_string2(STRING2 * out, const STRING2 * in, const uchar * key);
BOOL decode_pw_buffer(const char buffer[516], char *new_pwrd,
/*The following definitions come from rpc_parse/parse_net.c */
-BOOL make_log_info(DOM_LOG_INFO *log,
- const char *logon_srv, const char *acct_name,
- uint16 sec_chan, const char *comp_name);
-BOOL smb_io_log_info(char *desc, DOM_LOG_INFO *log, prs_struct *ps, int depth);
-BOOL make_clnt_info2(DOM_CLNT_INFO2 *clnt,
- const char *logon_srv, const char *comp_name,
- DOM_CRED *clnt_cred);
-BOOL smb_io_clnt_info2(char *desc, DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth);
-BOOL make_clnt_info(DOM_CLNT_INFO *clnt,
- const char *logon_srv, const char *acct_name,
- uint16 sec_chan, const char *comp_name,
- DOM_CRED *cred);
-BOOL smb_io_clnt_info(char *desc, DOM_CLNT_INFO *clnt, prs_struct *ps, int depth);
-BOOL make_owf_info(OWF_INFO *hash, const uint8 data[16]);
-BOOL smb_io_owf_info(char *desc, OWF_INFO *hash, prs_struct *ps, int depth);
+BOOL make_log_info(DOM_LOG_INFO * log,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name);
+BOOL smb_io_log_info(char *desc, DOM_LOG_INFO * log, prs_struct *ps,
+ int depth);
+BOOL make_clnt_info2(DOM_CLNT_INFO2 * clnt,
+ const char *logon_srv, const char *comp_name,
+ DOM_CRED * clnt_cred);
+BOOL smb_io_clnt_info2(char *desc, DOM_CLNT_INFO2 * clnt, prs_struct *ps,
+ int depth);
+BOOL make_clnt_info(DOM_CLNT_INFO * clnt,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name, DOM_CRED * cred);
+BOOL smb_io_clnt_info(char *desc, DOM_CLNT_INFO * clnt, prs_struct *ps,
+ int depth);
+BOOL make_owf_info(OWF_INFO * hash, const uint8 data[16]);
+BOOL smb_io_owf_info(char *desc, OWF_INFO * hash, prs_struct *ps, int depth);
BOOL make_q_logon_ctrl2(NET_Q_LOGON_CTRL2 * q_l,
const char *srv_name,
uint32 function_code,
uint32 query_level, uint32 switch_value);
BOOL net_io_q_logon_ctrl2(char *desc, NET_Q_LOGON_CTRL2 * q_l,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_r_logon_ctrl2(NET_R_LOGON_CTRL2 * r_l,
uint32 switch_value,
NETLOGON_INFO * logon_info, uint32 status);
BOOL net_io_r_logon_ctrl2(char *desc, NET_R_LOGON_CTRL2 * r_l,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL net_io_r_trust_dom(char *desc, NET_R_TRUST_DOM_LIST * r_t,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL net_io_q_trust_dom(char *desc, NET_Q_TRUST_DOM_LIST * q_l,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_q_req_chal(NET_Q_REQ_CHAL * q_c,
const char *logon_srv, const char *logon_clnt,
DOM_CHAL * clnt_chal);
-BOOL net_io_q_req_chal(char *desc, NET_Q_REQ_CHAL * q_c, prs_struct * ps,
+BOOL net_io_q_req_chal(char *desc, NET_Q_REQ_CHAL * q_c, prs_struct *ps,
int depth);
-BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL * r_c, prs_struct * ps,
+BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL * r_c, prs_struct *ps,
int depth);
BOOL make_q_auth(NET_Q_AUTH * q_a,
const char *logon_srv, const char *acct_name,
uint16 sec_chan, const char *comp_name, DOM_CHAL * clnt_chal);
-BOOL net_io_q_auth(char *desc, NET_Q_AUTH * q_a, prs_struct * ps, int depth);
-BOOL net_io_r_auth(char *desc, NET_R_AUTH * r_a, prs_struct * ps, int depth);
+BOOL net_io_q_auth(char *desc, NET_Q_AUTH * q_a, prs_struct *ps, int depth);
+BOOL net_io_r_auth(char *desc, NET_R_AUTH * r_a, prs_struct *ps, int depth);
BOOL make_q_auth_2(NET_Q_AUTH_2 * q_a,
const char *logon_srv, const char *acct_name,
uint16 sec_chan, const char *comp_name,
DOM_CHAL * clnt_chal, uint32 clnt_flgs);
-BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 * q_a, prs_struct * ps,
+BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 * q_a, prs_struct *ps,
int depth);
-BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 * r_a, prs_struct * ps,
+BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 * r_a, prs_struct *ps,
int depth);
BOOL make_q_srv_pwset(NET_Q_SRV_PWSET * q_s,
const char *logon_srv, const char *acct_name,
uint16 sec_chan, const char *comp_name,
DOM_CRED * cred, char nt_cypher[16]);
-BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET * q_s, prs_struct * ps,
+BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET * q_s, prs_struct *ps,
int depth);
-BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET * r_s, prs_struct * ps,
+BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET * r_s, prs_struct *ps,
int depth);
BOOL make_id_info1(NET_ID_INFO_1 * id, const char *domain_name,
uint32 param_ctrl,
const NTTIME * pass_last_set_time,
const NTTIME * pass_can_change_time,
const NTTIME * pass_must_change_time,
- const UNISTR2 * user_name,
- const UNISTR2 * full_name,
- const UNISTR2 * log_scr,
- const UNISTR2 * prof_path,
- const UNISTR2 * home_dir,
- const UNISTR2 * dir_drive,
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
uint16 logon_count,
uint16 bad_pw_count,
uint32 user_id,
const DOM_GID * gids,
uint32 user_flgs,
const char sess_key[16],
- const UNISTR2 * logon_srv,
- const UNISTR2 * logon_dom,
- const char *padding, const DOM_SID * dom_sid);
+ const UNISTR2 *logon_srv,
+ const UNISTR2 *logon_dom,
+ const char *padding, const DOM_SID *dom_sid);
BOOL make_net_user_info2(NET_USER_INFO_2 * usr,
NTTIME * logon_time,
NTTIME * logoff_time,
uint32 user_flgs,
char sess_key[16],
char *logon_srv,
- char *logon_dom, char *padding, DOM_SID * dom_sid);
-BOOL net_io_user_info2(char *desc, NET_USER_INFO_2 * usr, prs_struct * ps,
+ char *logon_dom, char *padding, DOM_SID *dom_sid);
+BOOL net_io_user_info2(char *desc, NET_USER_INFO_2 * usr, prs_struct *ps,
int depth);
BOOL net_user_info_3_copy_from_ctr(NET_USER_INFO_3 * usr,
- const NET_USER_INFO_CTR *ctr);
+ const NET_USER_INFO_CTR * ctr);
BOOL make_net_user_info3W(NET_USER_INFO_3 * usr,
const NTTIME * logon_time,
const NTTIME * logoff_time,
const NTTIME * pass_last_set_time,
const NTTIME * pass_can_change_time,
const NTTIME * pass_must_change_time,
- const UNISTR2 * user_name,
- const UNISTR2 * full_name,
- const UNISTR2 * log_scr,
- const UNISTR2 * prof_path,
- const UNISTR2 * home_dir,
- const UNISTR2 * dir_drive,
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
uint16 logon_count,
uint16 bad_pw_count,
uint32 user_id,
const DOM_GID * gids,
uint32 user_flgs,
const char sess_key[16],
- const UNISTR2 * logon_srv,
- const UNISTR2 * logon_dom,
+ const UNISTR2 *logon_srv,
+ const UNISTR2 *logon_dom,
const char *padding,
- const DOM_SID * dom_sid, const char *other_sids);
+ const DOM_SID *dom_sid, const char *other_sids);
BOOL make_net_user_info3(NET_USER_INFO_3 * usr,
NTTIME * logon_time,
NTTIME * logoff_time,
char sess_key[16],
char *logon_srv,
char *logon_dom,
- char *padding, DOM_SID * dom_sid, char *other_sids);
-BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 * usr, prs_struct * ps,
+ char *padding, DOM_SID *dom_sid, char *other_sids);
+BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 * usr, prs_struct *ps,
int depth);
-BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON * q_l, prs_struct * ps,
+BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON * q_l, prs_struct *ps,
int depth);
BOOL make_r_sam_logon(NET_R_SAM_LOGON * r_s,
const DOM_CRED * srv_creds,
- uint16 switch_value,
- void *id, uint32 status);
+ uint16 switch_value, void *id, uint32 status);
BOOL net_io_user_info_ctr(char *desc, NET_USER_INFO_CTR * ctr,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
void free_net_user_info_ctr(NET_USER_INFO_CTR * ctr);
-BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON * r_l, prs_struct * ps,
+BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON * r_l, prs_struct *ps,
int depth);
-BOOL net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF * q_l, prs_struct * ps,
+BOOL net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF * q_l, prs_struct *ps,
int depth);
BOOL make_r_sam_logoff(NET_R_SAM_LOGOFF * r_s,
const DOM_CRED * srv_cred, uint32 status);
-BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF * r_l, prs_struct * ps,
+BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF * r_l, prs_struct *ps,
int depth);
BOOL make_q_sam_sync(NET_Q_SAM_SYNC * q_s,
const char *srv_name,
const char *cli_name,
DOM_CRED * cli_creds, uint32 database_id);
-BOOL net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC * q_s, prs_struct * ps,
+BOOL net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC * q_s, prs_struct *ps,
int depth);
BOOL make_sam_delta_hdr(SAM_DELTA_HDR * delta, uint16 type, uint32 rid);
BOOL make_sam_account_info(SAM_ACCOUNT_INFO * info,
- const UNISTR2 * user_name,
- const UNISTR2 * full_name,
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
uint32 user_rid, uint32 group_rid,
- const UNISTR2 * home_dir,
- const UNISTR2 * dir_drive,
- const UNISTR2 * log_scr,
- const UNISTR2 * desc,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *desc,
uint32 acb_info,
- const UNISTR2 * prof_path,
- const UNISTR2 * wkstas,
- const UNISTR2 * unk_str, const UNISTR2 * mung_dial);
+ const UNISTR2 *prof_path,
+ const UNISTR2 *wkstas,
+ const UNISTR2 *unk_str, const UNISTR2 *mung_dial);
BOOL make_r_sam_sync(NET_R_SAM_SYNC * r_s,
const DOM_CRED * srv_cred,
uint32 sync_context,
SAM_DELTA_HDR * hdr_deltas,
SAM_DELTA_CTR * deltas, uint32 status);
BOOL net_io_r_sam_sync(char *desc, uint8 sess_key[16],
- NET_R_SAM_SYNC * r_s, prs_struct * ps, int depth);
+ NET_R_SAM_SYNC * r_s, prs_struct *ps, int depth);
/*The following definitions come from rpc_parse/parse_ntlmssp.c */
/* max number of directories open at once */
/* note that with the new directory code this no longer requires a
file handle per directory, but large numbers do use more memory */
-#define MAX_OPEN_DIRECTORIES 64
+#define MAX_OPEN_DIRECTORIES 256
+
+/* max number of directory handles */
+/* As this now uses the bitmap code this can be
+ quite large. */
+#define MAX_DIRECTORY_HANDLES 2048
+
+/* maximum number of file caches per smbd */
+#define MAX_WRITE_CACHES 10
/* define what facility to use for syslog */
#ifndef SYSLOG_FACILITY
/* separators for lists */
#define LIST_SEP " \t,;:\n\r"
+/* wchar separators for lists */
+#define LIST_SEP_W wchar_list_sep
+
#ifndef LOCKDIR
/* this should have been set in the Makefile */
#define LOCKDIR "/tmp/samba"
#define GUEST_ACCOUNT "nobody"
#endif
-/* do you want smbd to send a 1 byte packet to nmbd to trigger it to start
- when smbd starts? */
-#ifndef PRIME_NMBD
-#define PRIME_NMBD 1
-#endif
-
/* the default pager to use for the client "more" command. Users can
override this with the PAGER environment variable */
#ifndef PAGER
/* the following control timings of various actions. Don't change
them unless you know what you are doing. These are all in seconds */
#define DEFAULT_SMBD_TIMEOUT (60*60*24*7)
-#define SMBD_RELOAD_CHECK (60)
+#define SMBD_RELOAD_CHECK (180)
#define IDLE_CLOSED_TIMEOUT (60)
#define DPTR_IDLE_TIMEOUT (120)
-#define SMBD_SELECT_LOOP (10)
+#define SMBD_SELECT_TIMEOUT (60)
+#define SMBD_SELECT_TIMEOUT_WITH_PENDING_LOCKS (10)
#define NMBD_SELECT_LOOP (10)
#define BROWSE_INTERVAL (60)
#define REGISTRATION_INTERVAL (10*60)
/* shall we support browse requests via a FIFO to nmbd? */
#define ENABLE_FIFO 1
-/* how long to wait for a socket connect to happen */
-#define LONG_CONNECT_TIMEOUT 30
-#define SHORT_CONNECT_TIMEOUT 5
-
-/* default socket options. Dave Miller thinks we should default to TCP_NODELAY
- given the socket IO pattern that Samba uses*/
-#ifdef TCP_NODELAY
-#define DEFAULT_SOCKET_OPTIONS "TCP_NODELAY"
-#else
-#define DEFAULT_SOCKET_OPTIONS ""
-#endif
+/* how long (in miliseconds) to wait for a socket connect to happen */
+#define LONG_CONNECT_TIMEOUT 30000
+#define SHORT_CONNECT_TIMEOUT 5000
/* the default netbios keepalive timeout */
#define DEFAULT_KEEPALIVE 300
#define OPLOCK_BREAK_TIMEOUT 30
-/* how many times do we try to resend the oplock break request - useful
- for buggy MS clients */
-#define OPLOCK_BREAK_RESENDS 3
-
/* Timout (in seconds) to add to the oplock break timeout
to wait for the smbd to smbd message to return. */
/* name of directory that netatalk uses to store macintosh resource forks */
#define APPLEDOUBLE ".AppleDouble/"
+/*
+ * Default passwd chat script.
+ */
+
+#define DEFAULT_PASSWD_CHAT "*new*password* %n\\n *new*password* %n\\n *changed*"
+
+/* Minimum length of allowed password when changing UNIX password. */
+#define MINPASSWDLENGTH 5
+
#endif
char *unix2dos_format(char *str,BOOL overwrite);
char *dos2unix_format(char *str, BOOL overwrite);
-void interpret_character_set(char *str);
+void interpret_character_set(char *str, int codepage);
/*The following definitions come from lib/charset.c */
int dos_open(char *fname,int flags,mode_t mode);
DIR *dos_opendir(char *dname);
char *dos_readdirname(DIR *p);
+int dos_chown(char *fname, uid_t uid, gid_t gid);
int dos_stat(char *fname,SMB_STRUCT_STAT *sbuf);
int dos_lstat(char *fname,SMB_STRUCT_STAT *sbuf);
int dos_mkdir(char *dname,mode_t mode);
char *getsmbpass(char *prompt) ;
+/*The following definitions come from lib/hash.c */
+
+BOOL hash_table_init(hash_table *table, int num_buckets, compare_function compare_func);
+int string_hash(int hash_size, const char *key);
+hash_element *hash_lookup(hash_table *table, char *key);
+hash_element *hash_insert(hash_table *table, char *value, char *key);
+void hash_remove(hash_table *table, hash_element *hash_elem);
+void hash_clear(hash_table *table);
+
/*The following definitions come from lib/hmacmd5.c */
void hmac_md5_init_rfc2104(uchar* key, int key_len, HMACMD5Context *ctx);
/*The following definitions come from lib/kanji.c */
void interpret_coding_system(char *str);
-BOOL is_multibyte_codepage(void);
void initialize_multibyte_vectors( int client_codepage);
/*The following definitions come from lib/md4.c */
void pwd_set_cleartext(struct pwd_info *pwd, char *clr);
void pwd_get_cleartext(struct pwd_info *pwd, char *clr);
void pwd_set_lm_nt_16(struct pwd_info *pwd,
- const uchar lm_pwd[16],
- const uchar nt_pwd[16]);
-void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]);
+ const uchar lm_pwd[16], const uchar nt_pwd[16]);
+void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16],
+ uchar nt_pwd[16]);
void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr);
void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8],
- const char *user, const char *server, const char *domain,
- uchar sess_key[16]);
+ const char *user, const char *server,
+ const char *domain, uchar sess_key[16]);
void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8],
- uchar sess_key[16]);
+ uchar sess_key[16]);
void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24],
- uchar *nt_owf, size_t *nt_owf_len);
+ uchar * nt_owf, size_t * nt_owf_len);
/*The following definitions come from lib/smbrun.c */
void NTLMSSPOWFencrypt(const uchar pwrd[8], const uchar * ntlmchalresp,
uchar p24[24]);
void SMBNTencrypt(uchar * pwrd, uchar * c8, uchar * p24);
+BOOL make_oem_passwd_hash(uchar data[516],
+ const char *pwrd, int new_pw_len,
+ const uchar old_pw_hash[16], BOOL unicode);
void SMBOWFencrypt_ntv2(const uchar kr[16],
const uchar * srv_chal, int srv_chal_len,
const uchar * cli_chal, int cli_chal_len,
void lm_owf_genW(const UNISTR2 *pwd, uchar p16[16]);
void nt_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16]);
void nt_lm_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16], uchar lm_p16[16]);
-BOOL make_oem_passwd_hash(uchar data[516],
- const char *pwrd, int new_pw_len,
- const uchar old_pw_hash[16], BOOL unicode);
BOOL nt_encrypt_string2(STRING2 * out, const STRING2 * in, const uchar * key);
BOOL nt_decrypt_string2(STRING2 * out, const STRING2 * in, const uchar * key);
BOOL decode_pw_buffer(const char buffer[516], char *new_pwrd,
/*The following definitions come from lib/sursalgdomonly.c */
-BOOL surs_algdomonly_sam_sid_to_unixid(DOM_SID *sid, uint32 type, uint32 *id,
+BOOL surs_algdomonly_sam_sid_to_unixid(DOM_SID *sid, POSIX_ID *id,
BOOL create);
-BOOL surs_algdomonly_unixid_to_sam_sid(uint32 id, uint32 type, DOM_SID *sid,
+BOOL surs_algdomonly_unixid_to_sam_sid(POSIX_ID *id, DOM_SID *sid,
BOOL create);
/*The following definitions come from lib/sursalgnt5ldap.c */
/*The following definitions come from lib/surs.c */
-BOOL surs_sam_sid_to_unixid(DOM_SID *sid, uint32 type, uint32 *id, BOOL create);
-BOOL surs_unixid_to_sam_sid(uint32 id, uint32 type, DOM_SID *sid, BOOL create);
+BOOL surs_sam_sid_to_unixid(DOM_SID *sid, POSIX_ID *id, BOOL create);
+BOOL surs_unixid_to_sam_sid(POSIX_ID *id, DOM_SID *sid, BOOL create);
/*The following definitions come from lib/surstdb.c */
int sys_select(int maxfd, fd_set *fds, fd_set *w_fds, struct timeval *tval);
int sys_select(int maxfd, fd_set *r_fds, fd_set *w_fds, struct timeval *tval);
+int sys_usleep(long usecs);
int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf);
int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf);
int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf);
int sys_open(const char *path, int oflag, mode_t mode);
FILE *sys_fopen(const char *path, const char *type);
void *sys_mmap(void *addr, size_t len, int prot, int flags, int fd, SMB_OFF_T offset);
+SMB_STRUCT_DIRENT *sys_readdir(DIR *dirp);
int sys_waitpid(pid_t pid,int *status,int options);
char *sys_getwd(char *s);
int sys_chown(const char *fname,uid_t uid,gid_t gid);
BOOL set_inherited_process_capability( uint32 cap_flag, BOOL enable );
long sys_random(void);
void sys_srandom(unsigned int seed);
+int groups_max(void);
int sys_getgroups(int setlen, gid_t *gidset);
-struct passwd *copy_passwd_struct(struct passwd *pass);
+int sys_setgroups(int setlen, gid_t *gidset);
struct passwd *sys_getpwnam(const char *name);
struct passwd *sys_getpwuid(uid_t uid);
+int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf);
+int wsys_lstat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf);
+int wsys_creat(const smb_ucs2_t *wfname, mode_t mode);
+int wsys_open(const smb_ucs2_t *wfname, int oflag, mode_t mode);
+FILE *wsys_fopen(const smb_ucs2_t *wfname, const char *type);
+DIR *wsys_opendir(const smb_ucs2_t *wfname);
+smb_ucs2_t *wsys_getwd(smb_ucs2_t *s);
+int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid);
+int wsys_chroot(const smb_ucs2_t *wfname);
+FILE *sys_popen(const char *command, const char *mode, BOOL paranoid);
+int sys_pclose( FILE *fp);
/*The following definitions come from lib/talloc.c */
+TALLOC_CTX *talloc_init(void);
void *talloc(TALLOC_CTX *t, size_t size);
void talloc_destroy(TALLOC_CTX *t);
BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t * groups);
uint32 get_number(const char *tmp);
char *Atoic(char *p, int *n, char *c);
-uint32 *add_num_to_list(uint32 ** num, int *count, int val);
-char *get_numlist(char *p, uint32 ** num, int *count);
-void putip(void *dest, void *src);
+uint32 *add_num_to_list(uint32 **num, int *count, int val);
+char *get_numlist(char *p, uint32 **num, int *count);
BOOL file_exist(char *fname, SMB_STRUCT_STAT * sbuf);
int file_rename(char *from, char *to);
time_t file_modtime(char *fname);
BOOL directory_exist(char *dname, SMB_STRUCT_STAT * st);
SMB_OFF_T file_size(char *file_name);
char *attrib_string(uint16 mode);
-void unix_format(char *fname);
-void dos_format(char *fname);
void show_msg(char *buf);
-int smb_len(char *buf);
-void _smb_setlen(char *buf, int len);
void smb_setlen(char *buf, int len);
int set_message(char *buf, int num_words, int num_bytes, BOOL zero);
-int smb_buflen(char *buf);
-char *smb_buf(char *buf);
-int smb_offset(char *p, char *buf);
void dos_clean_name(char *s);
+void unix_clean_name(char *s);
+BOOL reduce_name(char *s, char *dir, BOOL widelinks);
+void expand_mask(char *Mask, BOOL doext);
void make_dir_struct(char *buf, char *mask, char *fname, SMB_OFF_T size,
int mode, time_t date);
void close_low_fds(void);
int set_blocking(int fd, BOOL set);
-int TvalDiff(struct timeval *tvalold, struct timeval *tvalnew);
SMB_OFF_T transfer_file(int infd, int outfd, SMB_OFF_T n, char *header,
int headlen, int align);
void msleep(int t);
-BOOL get_file_match(const char *dirname, const char *regexp,
- uint32 * total, char ***list);
-BOOL do_match(char *str, const char *regexp, int case_sig);
-BOOL mask_match(char *str, char *regexp, int case_sig, BOOL trans2);
+BOOL unix_do_match(char *str, char *regexp, BOOL case_sig);
+BOOL mask_match(char *str, char *regexp, BOOL case_sig, BOOL trans2);
void become_daemon(void);
BOOL yesno(char *p);
int set_filelen(int fd, SMB_OFF_T len);
+BOOL Memcpy(void *to, const void *from, size_t size);
void *Realloc(void *p, size_t size);
void safe_free(void *p);
BOOL get_myname(char *my_name, struct in_addr *ip);
-BOOL ip_equal(struct in_addr ip1, struct in_addr ip2);
int interpret_protocol(char *str, int def);
uint32 interpret_addr(char *str);
struct in_addr *interpret_addr2(char *str);
void zero_free(void *p, size_t size);
int set_maxfiles(int requested_max);
void reg_get_subkey(char *full_keyname, char *key_name, char *subkey_name);
-BOOL reg_split_key(const char *full_keyname, uint32 * reg_type,
- char *key_name);
+BOOL reg_split_key(const char *full_keyname, uint32 *reg_type, char *key_name);
char *get_trusted_serverlist(const char *domain);
uint16 pwdb_acct_ctrl_from_ad(NTDS_USER_FLAG_ENUM adac);
char *pwdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length);
void pwdb_set_must_change_time(char *p, int max_len, time_t t);
void pwdb_set_last_set_time(char *p, int max_len, time_t t);
void pwdb_sethexpwd(char *p, const uchar * pwd, uint16 acct_ctrl);
-BOOL pwdb_gethexpwd(const char *p, char *pwd, uint32 * acct_ctrl);
+BOOL pwdb_gethexpwd(const char *p, char *pwd, uint32 *acct_ctrl);
+char *smbd_mktemp(char *template);
void *memdup(const void *p, size_t size);
char *myhostname(void);
char *passdb_path(char *name);
char *lock_path(char *name);
+char *parent_dirname(const char *path);
const char *get_sid_name_use_str(uint32 sid_name_use);
/*The following definitions come from lib/util_file.c */
char *fgets_slash(char *s2,int maxlen,FILE *f);
BOOL file_modified(const char *filename, time_t *lastmodified);
void *open_file_if_modified(const char *filename, char *mode, time_t *lastmodified);
+SMB_OFF_T get_file_size(char *file_name);
/*The following definitions come from lib/util_hnd.c */
BOOL strhasupper(const char *s);
BOOL strhaslower(const char *s);
size_t count_chars(const char *s,char c);
+BOOL str_is_all(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 *StrCpy(char *dest,const char *src);
+char *alpha_strcpy(char *dest, const char *src, size_t maxlength);
char *StrnCpy(char *dest,const char *src,size_t n);
-char *strncpyn(char *dest, char *src,size_t n, char c);
+char *strncpyn(char *dest, const char *src,size_t n, char c);
size_t strhex_to_str(char *p, size_t len, const char *strhex);
BOOL in_list(char *s,char *list,BOOL casesensitive);
-BOOL string_init(char **dest,const char *src);
void string_free(char **s);
BOOL string_set(char **dest,const char *src);
-void string_sub(char *s,const char *pattern,const char *insert);
+void string_sub(char *s,const char *pattern,const char *insert, size_t len);
+void fstring_sub(char *s,const char *pattern,const char *insert);
+void pstring_sub(char *s,const char *pattern,const char *insert);
void all_string_sub(char *s,const char *pattern,const char *insert, size_t len);
void split_at_first_component(char *path, char *front, char sep, char *back);
void split_at_last_component(char *path, char *front, char sep, char *back);
char *bit_field_to_str(uint32 type, struct field_info *bs);
char *enum_field_to_str(uint32 type, struct field_info *bs, BOOL first_default);
+char *octal_string(int i);
char *string_truncate(char *s, int length);
/*The following definitions come from lib/util_unistr.c */
-int dos_PutUniCode(char *dst,const char *src, ssize_t len, BOOL null_terminate);
char *ascii_to_unibuf(char *dest, const char *src, int maxlen);
const char* unibuf_to_ascii(char *dest, const char *src, int maxlen);
void ascii_to_unistr(uint16 *dest, const char *src, int maxlen);
int StrCaseCmpW(const UNISTR2 *ws, const UNISTR2 *wt);
BOOL unistr2equal(const UNISTR2 *s1, const UNISTR2 *s2);
+/*The following definitions come from lib/util_wunistr.c */
+
+int dos_PutUniCode(char *dst,const char *src, ssize_t len, BOOL null_terminate);
+char *dos_unistrn2(uint16 *src, int len);
+char *dos_unistr2(uint16 *src);
+char *dos_unistr2_to_str(UNISTR2 *str);
+char *dos_buffer2_to_str(BUFFER2 *str);
+char *dos_buffer2_to_multistr(BUFFER2 *str);
+size_t dos_struni2(char *dst, const char *src, size_t max_len);
+char *dos_unistr(char *buf);
+void default_unicode_map(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp);
+BOOL load_unicode_map(const char *codepage, smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp);
+BOOL load_dos_unicode_map(int codepage);
+BOOL load_unix_unicode_map(const char *unix_char_set);
+smb_ucs2_t *multibyte_to_unicode(smb_ucs2_t *dst, const char *src,
+ size_t dst_len, smb_ucs2_t *cp_to_ucs2);
+char *unicode_to_unix(char *dst, const smb_ucs2_t *src, size_t dst_len);
+smb_ucs2_t *unix_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len);
+char *unicode_to_dos(char *dst, const smb_ucs2_t *src, size_t dst_len);
+smb_ucs2_t *dos_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len);
+size_t strlen_w(const smb_ucs2_t *src);
+smb_ucs2_t *safe_strcpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src, size_t maxlength);
+smb_ucs2_t *safe_strcat_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength);
+int strcmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2);
+int strncmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2, size_t len);
+smb_ucs2_t *strstr_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2);
+smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c);
+smb_ucs2_t *strrchr_w(const smb_ucs2_t *s, smb_ucs2_t c);
+smb_ucs2_t *strtok_w(smb_ucs2_t *s1, const smb_ucs2_t *s2);
+smb_ucs2_t *strdup_w(const smb_ucs2_t *s);
+int isupper_w( smb_ucs2_t val);
+int islower_w( smb_ucs2_t val);
+int isdigit_w( smb_ucs2_t val);
+int isxdigit_w( smb_ucs2_t val);
+int isspace_w( smb_ucs2_t val);
+smb_ucs2_t toupper_w( smb_ucs2_t val );
+smb_ucs2_t tolower_w( smb_ucs2_t val );
+void set_first_token_w(smb_ucs2_t *ptr);
+BOOL next_token_w(smb_ucs2_t **ptr, smb_ucs2_t *buff, smb_ucs2_t *sep, size_t bufsize);
+smb_ucs2_t **toktocliplist_w(int *ctok, smb_ucs2_t *sep);
+int StrCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t);
+int StrnCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t, size_t n);
+BOOL strequal_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2);
+BOOL strnequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2,size_t n);
+BOOL strcsequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2);
+void strlower_w(smb_ucs2_t *s);
+void strupper_w(smb_ucs2_t *s);
+void strnorm_w(smb_ucs2_t *s);
+BOOL strisnormal_w(smb_ucs2_t *s);
+void string_replace_w(smb_ucs2_t *s, smb_ucs2_t oldc, smb_ucs2_t newc);
+smb_ucs2_t *skip_string_w(smb_ucs2_t *buf,size_t n);
+size_t str_charnum_w(const smb_ucs2_t *s);
+BOOL trim_string_w(smb_ucs2_t *s,const smb_ucs2_t *front,const smb_ucs2_t *back);
+BOOL strhasupper_w(const smb_ucs2_t *s);
+BOOL strhaslower_w(const smb_ucs2_t *s);
+size_t count_chars_w(const smb_ucs2_t *s,smb_ucs2_t c);
+BOOL str_is_all_w(const smb_ucs2_t *s,smb_ucs2_t c);
+smb_ucs2_t *alpha_strcpy_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength);
+smb_ucs2_t *StrnCpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src,size_t n);
+smb_ucs2_t *strncpyn_w(smb_ucs2_t *dest, const smb_ucs2_t *src,size_t n, smb_ucs2_t c);
+size_t strhex_to_str_w(char *p, size_t len, const smb_ucs2_t *strhex);
+BOOL in_list_w(smb_ucs2_t *s,smb_ucs2_t *list,BOOL casesensitive);
+BOOL string_init_w(smb_ucs2_t **dest,const smb_ucs2_t *src);
+void string_free_w(smb_ucs2_t **s);
+BOOL string_set_w(smb_ucs2_t **dest,const smb_ucs2_t *src);
+void string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len);
+void fstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert);
+void pstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,smb_ucs2_t *insert);
+void all_string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len);
+void split_at_last_component_w(smb_ucs2_t *path, smb_ucs2_t *front, smb_ucs2_t sep, smb_ucs2_t *back);
+smb_ucs2_t *octal_string_w(int i);
+smb_ucs2_t *string_truncate_w(smb_ucs2_t *s, size_t length);
+
/*The following definitions come from lib/vagent.c */
void init_sock_redir(struct vagent_ops*va);
BOOL tdb_store_vuid( const vuser_key *uk, user_struct *usr);
BOOL vuid_init_db(void);
+/*The following definitions come from locking/brlock.c */
+
+void brl_init(int read_only);
+BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
+ uint16 smbpid, pid_t pid, uint16 tid,
+ br_off start, br_off size,
+ enum brl_type lock_type);
+BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
+ uint16 smbpid, pid_t pid, uint16 tid,
+ br_off start, br_off size);
+BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino,
+ uint16 smbpid, pid_t pid, uint16 tid,
+ br_off start, br_off size,
+ enum brl_type lock_type);
+void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum);
+int brl_forall(BRLOCK_FN(fn));
+
/*The following definitions come from locking/locking.c */
+void locking_close_file(files_struct *fsp);
BOOL is_locked(files_struct *fsp,connection_struct *conn,
- SMB_OFF_T count,SMB_OFF_T offset, int lock_type);
+ SMB_OFF_T count,SMB_OFF_T offset,
+ enum brl_type lock_type);
BOOL do_lock(files_struct *fsp,connection_struct *conn,
- SMB_OFF_T count,SMB_OFF_T offset,int lock_type,
+ SMB_OFF_T count,SMB_OFF_T offset,enum brl_type lock_type,
int *eclass,uint32 *ecode);
BOOL do_unlock(files_struct *fsp,connection_struct *conn,
- SMB_OFF_T count,SMB_OFF_T offset,int *eclass,uint32 *ecode);
+ SMB_OFF_T count,SMB_OFF_T offset,
+ int *eclass,uint32 *ecode);
BOOL locking_init(int read_only);
BOOL locking_end(void);
BOOL lock_share_entry(connection_struct *conn,
BOOL remove_share_oplock(files_struct *fsp);
BOOL downgrade_share_oplock(files_struct *fsp);
BOOL modify_share_mode(files_struct *fsp, int new_mode, uint16 new_oplock);
-int share_mode_forall(void (*fn)(share_mode_entry *, char *));
+int share_mode_forall(SHAREMODE_FN(fn));
/*The following definitions come from lsarpcd/lsarpcd.c */
const UNISTR2 * secret_name, uint32 des_access,
POLICY_HND * hnd_secret);
+/*The following definitions come from msdfs/msdfs.c */
+
+BOOL dfs_redirect(char* pathname, connection_struct* conn);
+BOOL dfs_findfirst_redirect(char* pathname, connection_struct* conn);
+int setup_dfs_referral(char* pathname, int max_referral_level,
+ char** ppdata);
+int dfs_path_error(char* inbuf, char* outbuf);
+int setup_dfs_referral(char* pathname, int max_referral_level,
+ char** ppdata);
+void unistr_to_dos(char* dst,char* src) ;
+
+/*The following definitions come from msdfs/msdfs_tdb.c */
+
+BOOL msdfs_open(BOOL update);
+BOOL add_junction_entry(struct junction_map* junction);
+BOOL get_junction_entry(struct junction_map* junction);
+BOOL isDfsShare(char* svc,char* vol);
+void msdfs_close(void);
+void msdfs_end(void);
+
+/*The following definitions come from msdfs/parse_dfs_map.c */
+
+void load_dfsmaps(void);
+void load_dfsmaps(void);
+
/*The following definitions come from msrpc/msrpcd.c */
void exit_server(char *reason);
/*The following definitions come from param/loadparm.c */
void lp_talloc_free(void);
-struct vfs_options *lp_vfsoptions(int i) ;
char *lp_logfile(void);
char *lp_smbrun(void);
char *lp_configfile(void);
char *lp_serverstring(void);
char *lp_printcapname(void);
char *lp_lockdir(void);
+char *lp_utmpdir(void);
char *lp_rootdir(void);
+char *lp_source_environment(void);
char *lp_defaultservice(void);
char *lp_msg_command(void);
+char *lp_dfree_command(void);
char *lp_hosts_equiv(void);
char *lp_auto_services(void);
char *lp_passwd_program(void);
char *lp_remote_announce(void);
char *lp_remote_browse_sync(void);
char *lp_wins_server(void);
-char *lp_wins_hook(void);
char *lp_interfaces(void);
char *lp_socket_address(void);
char *lp_nis_home_map_name(void);
char *lp_netbios_aliases(void);
char *lp_driverfile(void);
char *lp_panic_action(void);
+char *lp_adduser_script(void);
+char *lp_deluser_script(void);
+char *lp_wins_hook(void);
char *lp_nt_forms(void);
char *lp_nt_drivers_file(void);
-char *lp_dfs_map(void);
char *lp_ldap_server(void);
char *lp_ldap_suffix(void);
char *lp_ldap_bind_as(void);
BOOL lp_ole_locking_compat(void);
BOOL lp_nt_smb_support(void);
BOOL lp_nt_pipe_support(void);
+BOOL lp_nt_acl_support(void);
BOOL lp_stat_cache(void);
+BOOL lp_host_msdfs(void);
int lp_os_level(void);
int lp_max_ttl(void);
int lp_max_wins_ttl(void);
char *lp_hide_files(int );
char *lp_veto_oplocks(int );
char *lp_driverlocation(int );
+char *lp_dfsmap(int );
+BOOL lp_dfsmap_loaded(int );
+BOOL lp_preexec_close(int );
+BOOL lp_rootpreexec_close(int );
BOOL lp_revalidate(int );
BOOL lp_casesensitive(int );
BOOL lp_preservecase(int );
BOOL lp_map_archive(int );
BOOL lp_locking(int );
BOOL lp_strict_locking(int );
+BOOL lp_utmp(int );
BOOL lp_share_modes(int );
BOOL lp_oplocks(int );
+BOOL lp_level2_oplocks(int );
BOOL lp_onlyuser(int );
BOOL lp_manglednames(int );
BOOL lp_widelinks(int );
BOOL lp_dos_filetime_resolution(int );
BOOL lp_fake_dir_create_times(int );
BOOL lp_blocking_locks(int );
-int lp_create_mode(int );
+BOOL lp_inherit_perms(int );
+int lp_create_mask(int );
int lp_force_create_mode(int );
-int lp_dir_mode(int );
+int _lp_security_mask(int );
+int _lp_force_security_mode(int );
+int lp_dir_mask(int );
int lp_force_dir_mode(int );
+int _lp_dir_security_mask(int );
+int _lp_force_dir_security_mode(int );
int lp_max_connections(int );
int lp_defaultcase(int );
int lp_minprintspace(int );
int lp_printing(int );
+int lp_oplock_contention_limit(int );
+int lp_write_cache_size(int );
char lp_magicchar(int );
char *lp_mysql_host(void);
char *lp_mysql_user(void);
int lp_add_service(char *pszService, int iDefaultService);
BOOL lp_add_printer(char *pszPrintername, int iDefaultService);
BOOL lp_file_list_changed(void);
+void set_dfsmap_loaded(int i,BOOL b);
void *lp_local_ptr(int snum, void *ptr);
BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue);
BOOL lp_is_default(int snum, struct parm_struct *parm);
BOOL lp_loaded(void);
void lp_killunused(BOOL (*snumused)(int ));
BOOL lp_load(char *pszFname,BOOL global_only, BOOL save_defaults, BOOL add_ipc);
+void lp_resetnumservices(void);
int lp_numservices(void);
-void lp_dump(FILE *f, BOOL show_defaults);
+void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint);
void lp_dump_one(FILE *f, BOOL show_defaults, int snum);
int lp_servicenumber(char *pszServiceName);
char *volume_label(int snum);
+int lp_server_role(void);
+BOOL lp_domain_master(void);
+BOOL lp_preferred_master(void);
void lp_remove_service(int snum);
void lp_copy_service(int snum, char *new_name);
int lp_default_server_announce(void);
void lp_set_name_resolve_order(char *new_order);
void lp_set_kernel_oplocks(BOOL val);
BOOL lp_kernel_oplocks(void);
-int lp_server_role(void);
-BOOL lp_domain_master(void);
-BOOL lp_preferred_master(void);
+int lp_security_mask(int snum);
+int lp_force_security_mode(int snum);
+int lp_dir_security_mask(int snum);
+int lp_force_dir_security_mode(int snum);
/*The following definitions come from param/params.c */
/*The following definitions come from rpc_parse/parse_net.c */
-BOOL make_log_info(DOM_LOG_INFO *log,
- const char *logon_srv, const char *acct_name,
- uint16 sec_chan, const char *comp_name);
-BOOL smb_io_log_info(char *desc, DOM_LOG_INFO *log, prs_struct *ps, int depth);
-BOOL make_clnt_info2(DOM_CLNT_INFO2 *clnt,
- const char *logon_srv, const char *comp_name,
- DOM_CRED *clnt_cred);
-BOOL smb_io_clnt_info2(char *desc, DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth);
-BOOL make_clnt_info(DOM_CLNT_INFO *clnt,
- const char *logon_srv, const char *acct_name,
- uint16 sec_chan, const char *comp_name,
- DOM_CRED *cred);
-BOOL smb_io_clnt_info(char *desc, DOM_CLNT_INFO *clnt, prs_struct *ps, int depth);
-BOOL make_owf_info(OWF_INFO *hash, const uint8 data[16]);
-BOOL smb_io_owf_info(char *desc, OWF_INFO *hash, prs_struct *ps, int depth);
+BOOL make_log_info(DOM_LOG_INFO * log,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name);
+BOOL smb_io_log_info(char *desc, DOM_LOG_INFO * log, prs_struct *ps,
+ int depth);
+BOOL make_clnt_info2(DOM_CLNT_INFO2 * clnt,
+ const char *logon_srv, const char *comp_name,
+ DOM_CRED * clnt_cred);
+BOOL smb_io_clnt_info2(char *desc, DOM_CLNT_INFO2 * clnt, prs_struct *ps,
+ int depth);
+BOOL make_clnt_info(DOM_CLNT_INFO * clnt,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name, DOM_CRED * cred);
+BOOL smb_io_clnt_info(char *desc, DOM_CLNT_INFO * clnt, prs_struct *ps,
+ int depth);
+BOOL make_owf_info(OWF_INFO * hash, const uint8 data[16]);
+BOOL smb_io_owf_info(char *desc, OWF_INFO * hash, prs_struct *ps, int depth);
BOOL make_q_logon_ctrl2(NET_Q_LOGON_CTRL2 * q_l,
const char *srv_name,
uint32 function_code,
uint32 query_level, uint32 switch_value);
BOOL net_io_q_logon_ctrl2(char *desc, NET_Q_LOGON_CTRL2 * q_l,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_r_logon_ctrl2(NET_R_LOGON_CTRL2 * r_l,
uint32 switch_value,
NETLOGON_INFO * logon_info, uint32 status);
BOOL net_io_r_logon_ctrl2(char *desc, NET_R_LOGON_CTRL2 * r_l,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL net_io_r_trust_dom(char *desc, NET_R_TRUST_DOM_LIST * r_t,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL net_io_q_trust_dom(char *desc, NET_Q_TRUST_DOM_LIST * q_l,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_q_req_chal(NET_Q_REQ_CHAL * q_c,
const char *logon_srv, const char *logon_clnt,
DOM_CHAL * clnt_chal);
-BOOL net_io_q_req_chal(char *desc, NET_Q_REQ_CHAL * q_c, prs_struct * ps,
+BOOL net_io_q_req_chal(char *desc, NET_Q_REQ_CHAL * q_c, prs_struct *ps,
int depth);
-BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL * r_c, prs_struct * ps,
+BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL * r_c, prs_struct *ps,
int depth);
BOOL make_q_auth(NET_Q_AUTH * q_a,
const char *logon_srv, const char *acct_name,
uint16 sec_chan, const char *comp_name, DOM_CHAL * clnt_chal);
-BOOL net_io_q_auth(char *desc, NET_Q_AUTH * q_a, prs_struct * ps, int depth);
-BOOL net_io_r_auth(char *desc, NET_R_AUTH * r_a, prs_struct * ps, int depth);
+BOOL net_io_q_auth(char *desc, NET_Q_AUTH * q_a, prs_struct *ps, int depth);
+BOOL net_io_r_auth(char *desc, NET_R_AUTH * r_a, prs_struct *ps, int depth);
BOOL make_q_auth_2(NET_Q_AUTH_2 * q_a,
const char *logon_srv, const char *acct_name,
uint16 sec_chan, const char *comp_name,
DOM_CHAL * clnt_chal, uint32 clnt_flgs);
-BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 * q_a, prs_struct * ps,
+BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 * q_a, prs_struct *ps,
int depth);
-BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 * r_a, prs_struct * ps,
+BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 * r_a, prs_struct *ps,
int depth);
BOOL make_q_srv_pwset(NET_Q_SRV_PWSET * q_s,
const char *logon_srv, const char *acct_name,
uint16 sec_chan, const char *comp_name,
DOM_CRED * cred, char nt_cypher[16]);
-BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET * q_s, prs_struct * ps,
+BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET * q_s, prs_struct *ps,
int depth);
-BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET * r_s, prs_struct * ps,
+BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET * r_s, prs_struct *ps,
int depth);
BOOL make_id_info1(NET_ID_INFO_1 * id, const char *domain_name,
uint32 param_ctrl,
const NTTIME * pass_last_set_time,
const NTTIME * pass_can_change_time,
const NTTIME * pass_must_change_time,
- const UNISTR2 * user_name,
- const UNISTR2 * full_name,
- const UNISTR2 * log_scr,
- const UNISTR2 * prof_path,
- const UNISTR2 * home_dir,
- const UNISTR2 * dir_drive,
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
uint16 logon_count,
uint16 bad_pw_count,
uint32 user_id,
const DOM_GID * gids,
uint32 user_flgs,
const char sess_key[16],
- const UNISTR2 * logon_srv,
- const UNISTR2 * logon_dom,
- const char *padding, const DOM_SID * dom_sid);
+ const UNISTR2 *logon_srv,
+ const UNISTR2 *logon_dom,
+ const char *padding, const DOM_SID *dom_sid);
BOOL make_net_user_info2(NET_USER_INFO_2 * usr,
NTTIME * logon_time,
NTTIME * logoff_time,
uint32 user_flgs,
char sess_key[16],
char *logon_srv,
- char *logon_dom, char *padding, DOM_SID * dom_sid);
-BOOL net_io_user_info2(char *desc, NET_USER_INFO_2 * usr, prs_struct * ps,
+ char *logon_dom, char *padding, DOM_SID *dom_sid);
+BOOL net_io_user_info2(char *desc, NET_USER_INFO_2 * usr, prs_struct *ps,
int depth);
BOOL net_user_info_3_copy_from_ctr(NET_USER_INFO_3 * usr,
- const NET_USER_INFO_CTR *ctr);
+ const NET_USER_INFO_CTR * ctr);
BOOL make_net_user_info3W(NET_USER_INFO_3 * usr,
const NTTIME * logon_time,
const NTTIME * logoff_time,
const NTTIME * pass_last_set_time,
const NTTIME * pass_can_change_time,
const NTTIME * pass_must_change_time,
- const UNISTR2 * user_name,
- const UNISTR2 * full_name,
- const UNISTR2 * log_scr,
- const UNISTR2 * prof_path,
- const UNISTR2 * home_dir,
- const UNISTR2 * dir_drive,
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
uint16 logon_count,
uint16 bad_pw_count,
uint32 user_id,
const DOM_GID * gids,
uint32 user_flgs,
const char sess_key[16],
- const UNISTR2 * logon_srv,
- const UNISTR2 * logon_dom,
+ const UNISTR2 *logon_srv,
+ const UNISTR2 *logon_dom,
const char *padding,
- const DOM_SID * dom_sid, const char *other_sids);
+ const DOM_SID *dom_sid, const char *other_sids);
BOOL make_net_user_info3(NET_USER_INFO_3 * usr,
NTTIME * logon_time,
NTTIME * logoff_time,
char sess_key[16],
char *logon_srv,
char *logon_dom,
- char *padding, DOM_SID * dom_sid, char *other_sids);
-BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 * usr, prs_struct * ps,
+ char *padding, DOM_SID *dom_sid, char *other_sids);
+BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 * usr, prs_struct *ps,
int depth);
-BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON * q_l, prs_struct * ps,
+BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON * q_l, prs_struct *ps,
int depth);
BOOL make_r_sam_logon(NET_R_SAM_LOGON * r_s,
const DOM_CRED * srv_creds,
- uint16 switch_value,
- void *id, uint32 status);
+ uint16 switch_value, void *id, uint32 status);
BOOL net_io_user_info_ctr(char *desc, NET_USER_INFO_CTR * ctr,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
void free_net_user_info_ctr(NET_USER_INFO_CTR * ctr);
-BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON * r_l, prs_struct * ps,
+BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON * r_l, prs_struct *ps,
int depth);
-BOOL net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF * q_l, prs_struct * ps,
+BOOL net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF * q_l, prs_struct *ps,
int depth);
BOOL make_r_sam_logoff(NET_R_SAM_LOGOFF * r_s,
const DOM_CRED * srv_cred, uint32 status);
-BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF * r_l, prs_struct * ps,
+BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF * r_l, prs_struct *ps,
int depth);
BOOL make_q_sam_sync(NET_Q_SAM_SYNC * q_s,
const char *srv_name,
const char *cli_name,
DOM_CRED * cli_creds, uint32 database_id);
-BOOL net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC * q_s, prs_struct * ps,
+BOOL net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC * q_s, prs_struct *ps,
int depth);
BOOL make_sam_delta_hdr(SAM_DELTA_HDR * delta, uint16 type, uint32 rid);
BOOL make_sam_account_info(SAM_ACCOUNT_INFO * info,
- const UNISTR2 * user_name,
- const UNISTR2 * full_name,
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
uint32 user_rid, uint32 group_rid,
- const UNISTR2 * home_dir,
- const UNISTR2 * dir_drive,
- const UNISTR2 * log_scr,
- const UNISTR2 * desc,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *desc,
uint32 acb_info,
- const UNISTR2 * prof_path,
- const UNISTR2 * wkstas,
- const UNISTR2 * unk_str, const UNISTR2 * mung_dial);
+ const UNISTR2 *prof_path,
+ const UNISTR2 *wkstas,
+ const UNISTR2 *unk_str, const UNISTR2 *mung_dial);
BOOL make_r_sam_sync(NET_R_SAM_SYNC * r_s,
const DOM_CRED * srv_cred,
uint32 sync_context,
SAM_DELTA_HDR * hdr_deltas,
SAM_DELTA_CTR * deltas, uint32 status);
BOOL net_io_r_sam_sync(char *desc, uint8 sess_key[16],
- NET_R_SAM_SYNC * r_s, prs_struct * ps, int depth);
+ NET_R_SAM_SYNC * r_s, prs_struct *ps, int depth);
/*The following definitions come from rpc_parse/parse_netsec.c */
-BOOL rpc_hdr_netsec_auth_chk(RPC_HDR_AUTH *rai);
-BOOL make_rpc_auth_netsec_neg(RPC_AUTH_NETSEC_NEG *neg,
- fstring domain,
- fstring myname);
-BOOL smb_io_rpc_auth_netsec_neg(char *desc, RPC_AUTH_NETSEC_NEG *neg, prs_struct *ps, int depth);
-BOOL make_rpc_auth_netsec_resp(RPC_AUTH_NETSEC_RESP *rsp, uint32 flags);
-BOOL smb_io_rpc_auth_netsec_resp(char *desc, RPC_AUTH_NETSEC_RESP *rsp, prs_struct *ps, int depth);
-BOOL rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK *chk);
-BOOL make_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK *chk,
- const uchar sig[8],
- const uchar data1[8],
- const uchar data3[8],
- const uchar data8[8]);
-BOOL smb_io_rpc_auth_netsec_chk(char *desc, RPC_AUTH_NETSEC_CHK *chk, prs_struct *ps, int depth);
+BOOL rpc_hdr_netsec_auth_chk(RPC_HDR_AUTH * rai);
+BOOL make_rpc_auth_netsec_neg(RPC_AUTH_NETSEC_NEG * neg,
+ fstring domain, fstring myname);
+BOOL smb_io_rpc_auth_netsec_neg(char *desc, RPC_AUTH_NETSEC_NEG * neg,
+ prs_struct *ps, int depth);
+BOOL make_rpc_auth_netsec_resp(RPC_AUTH_NETSEC_RESP * rsp, uint32 flags);
+BOOL smb_io_rpc_auth_netsec_resp(char *desc, RPC_AUTH_NETSEC_RESP * rsp,
+ prs_struct *ps, int depth);
+BOOL rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK * chk);
+BOOL make_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK * chk,
+ const uchar sig[8],
+ const uchar data1[8],
+ const uchar data3[8], const uchar data8[8]);
+BOOL smb_io_rpc_auth_netsec_chk(char *desc, RPC_AUTH_NETSEC_CHK * chk,
+ prs_struct *ps, int depth);
BOOL netsec_encode(struct netsec_auth_struct *a,
- RPC_AUTH_NETSEC_CHK *verf,
- char *data, size_t data_len);
+ RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len);
BOOL netsec_decode(struct netsec_auth_struct *a,
- RPC_AUTH_NETSEC_CHK *verf,
- char *data, size_t data_len);
+ RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len);
/*The following definitions come from rpc_parse/parse_ntlmssp.c */
/*The following definitions come from rpc_parse/parse_sec.c */
-BOOL make_sec_access(SEC_ACCESS *t, uint32 mask);
-BOOL sec_io_access(char *desc, SEC_ACCESS *t, prs_struct *ps, int depth);
-BOOL make_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag);
-BOOL sec_io_ace(char *desc, SEC_ACE *t, prs_struct *ps, int depth);
-BOOL make_sec_acl(SEC_ACL *t, uint16 revision, int num_aces, SEC_ACE *ace);
-void free_sec_acl(SEC_ACL *t);
-BOOL sec_io_acl(char *desc, SEC_ACL *t, prs_struct *ps, int depth);
-int make_sec_desc(SEC_DESC *t, uint16 revision, uint16 type,
- DOM_SID *owner_sid, DOM_SID *grp_sid,
- SEC_ACL *sacl, SEC_ACL *dacl);
-void free_sec_desc(SEC_DESC *t);
-BOOL sec_io_desc(char *desc, SEC_DESC *t, prs_struct *ps, int depth);
-BOOL make_sec_desc_buf(SEC_DESC_BUF *buf, int len, SEC_DESC *data);
-void free_sec_desc_buf(SEC_DESC_BUF *buf);
-BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF *sec, prs_struct *ps, int depth);
+BOOL make_sec_access(SEC_ACCESS * t, uint32 mask);
+BOOL sec_io_access(char *desc, SEC_ACCESS * t, prs_struct *ps, int depth);
+BOOL make_sec_ace(SEC_ACE * t, const DOM_SID *sid, uint8 type,
+ SEC_ACCESS mask, uint8 flag);
+BOOL sec_io_ace(char *desc, SEC_ACE * t, prs_struct *ps, int depth);
+BOOL make_sec_acl(SEC_ACL * t, uint16 revision, int num_aces, SEC_ACE * ace);
+void free_sec_acl(SEC_ACL * t);
+BOOL sec_io_acl(char *desc, SEC_ACL * t, prs_struct *ps, int depth);
+int make_sec_desc(SEC_DESC * t, uint16 revision, uint16 type,
+ DOM_SID *owner_sid, DOM_SID *grp_sid,
+ SEC_ACL * sacl, SEC_ACL * dacl);
+void free_sec_desc(SEC_DESC * t);
+BOOL sec_io_desc(char *desc, SEC_DESC * t, prs_struct *ps, int depth);
+BOOL make_sec_desc_buf(SEC_DESC_BUF * buf, int len, SEC_DESC * data);
+void free_sec_desc_buf(SEC_DESC_BUF * buf);
+BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF * sec, prs_struct *ps,
+ int depth);
/*The following definitions come from rpc_parse/parse_vuid.c */
/*The following definitions come from rpc_server/srv_reg.c */
-BOOL api_reg_rpc(rpcsrv_struct *p);
+BOOL api_reg_rpc(rpcsrv_struct * p);
/*The following definitions come from rpc_server/srv_samr.c */
-BOOL api_samr_rpc(rpcsrv_struct *p);
+BOOL api_samr_rpc(rpcsrv_struct * p);
/*The following definitions come from rpc_server/srv_spoolss.c */
/*The following definitions come from rpc_server/srv_svcctl.c */
-BOOL api_svcctl_rpc(rpcsrv_struct *p);
+BOOL api_svcctl_rpc(rpcsrv_struct * p);
/*The following definitions come from rpc_server/srv_wkssvc.c */
BOOL tdb_lookup_user(TDB_CONTEXT * tdb, SAM_USER_INFO_21 * usr);
uint32 _samr_get_usrdom_pwinfo(const POLICY_HND *user_pol,
- uint16 * unknown_0,
- uint16 *unknown_1,
- uint32 * unknown_2);
+ uint16 *unknown_0,
+ uint16 *unknown_1, uint32 *unknown_2);
uint32 _samr_query_usergroups(const POLICY_HND *pol,
- uint32 * num_groups, DOM_GID ** gids);
+ uint32 *num_groups, DOM_GID ** gids);
uint32 _samr_query_useraliases(const POLICY_HND *domain_pol,
- const uint32 * ptr_sid, const DOM_SID2 * sid,
- uint32 * num_aliases, uint32 ** rid);
+ const uint32 *ptr_sid, const DOM_SID2 * sid,
+ uint32 *num_aliases, uint32 **rid);
uint32 _samr_open_user(const POLICY_HND *domain_pol,
uint32 access_mask, uint32 user_rid,
POLICY_HND *user_pol);
uint32 _samr_set_userinfo2(const POLICY_HND *pol, uint16 switch_value,
SAM_USERINFO_CTR * ctr);
uint32 _samr_create_user(const POLICY_HND *domain_pol,
- const UNISTR2 * uni_username,
+ const UNISTR2 *uni_username,
uint16 acb_info, uint32 access_mask,
POLICY_HND *user_pol,
- uint32 * unknown_0, uint32 * user_rid);
+ uint32 *unknown_0, uint32 *user_rid);
uint32 _samr_delete_dom_user(POLICY_HND *user_pol);
/*The following definitions come from smbd/afsticket.c */
BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num);
void remove_pending_lock_requests_by_fid(files_struct *fsp);
void remove_pending_lock_requests_by_mid(int mid);
+BOOL blocking_locks_pending(void);
void process_blocking_lock_queue(time_t t);
/*The following definitions come from smbd/challenge.c */
/*The following definitions come from smbd/close.c */
-void close_file(files_struct *fsp, BOOL normal_close);
-void close_directory(files_struct *fsp);
+int close_file(files_struct *fsp, BOOL normal_close);
/*The following definitions come from smbd/conn.c */
/*The following definitions come from smbd/dfree.c */
-SMB_BIG_UINT sys_disk_free(char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize);
-
-/*The following definitions come from smbd/dfs.c */
-
-BOOL init_dfs_table(void);
-int under_dfs(connection_struct *conn, const char *path,
- char *local_path, size_t local_plen);
+SMB_BIG_UINT sys_disk_free(char *path, BOOL small_query,
+ SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize);
/*The following definitions come from smbd/dir.c */
BOOL dptr_set_wcard(int key, char *wcard);
BOOL dptr_set_attr(int key, uint16 attr);
uint16 dptr_attr(int key);
-void dptr_close(int key);
+void dptr_close(int *key);
void dptr_closecnum(connection_struct *conn);
void dptr_idlecnum(connection_struct *conn);
-void dptr_closepath(char *path,int pid);
-int dptr_create(connection_struct *conn,char *path, BOOL expect_close,int pid);
+void dptr_closepath(char *path,uint16 spid);
+int dptr_create(connection_struct *conn,char *path, BOOL old_handle, BOOL expect_close,uint16 spid);
BOOL dptr_fill(char *buf1,unsigned int key);
-BOOL dptr_zero(char *buf);
void *dptr_fetch(char *buf,int *num);
void *dptr_fetch_lanman2(int dptr_num);
BOOL dir_check_ftype(connection_struct *conn,int mode,SMB_STRUCT_STAT *st,int dirtype);
/*The following definitions come from smbd/dosmode.c */
-mode_t unix_mode(connection_struct *conn,int dosmode);
+mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname);
int dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf);
int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT *st);
int file_utime(connection_struct *conn, char *fname, struct utimbuf *times);
/*The following definitions come from smbd/fileio.c */
SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos);
+BOOL read_from_write_cache(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n);
ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n);
-ssize_t write_file(files_struct *fsp,char *data,size_t n);
-void sys_sync_file(int fd);
+ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n);
+void delete_write_cache(files_struct *fsp);
+void set_filelen_write_cache(files_struct *fsp, SMB_OFF_T filesize);
+ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason);
+void sys_fsync_file(connection_struct *conn, files_struct *fsp);
/*The following definitions come from smbd/filename.c */
void print_stat_cache_statistics(void);
-BOOL unix_dfs_convert(char *name,connection_struct *conn,
- char *saved_last_component,
- BOOL *bad_path, SMB_STRUCT_STAT *pst);
-BOOL unix_convert(char *name,connection_struct *conn,
- char *saved_last_component,
- BOOL *bad_path, SMB_STRUCT_STAT *pst);
+BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
+ BOOL *bad_path, SMB_STRUCT_STAT *pst);
BOOL check_name(char *name,connection_struct *conn);
+BOOL reset_stat_cache( void );
/*The following definitions come from smbd/files.c */
/*The following definitions come from smbd/ipc.c */
void send_trans_reply(char *outbuf,
- prs_struct *rdata,
- prs_struct *rparam,
- uint16 *setup, int lsetup, int max_data_ret,
- BOOL pipe_data_outstanding);
-int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int bufsize);
+ prs_struct *rdata,
+ prs_struct *rparam,
+ uint16 *setup, int lsetup, int max_data_ret,
+ BOOL pipe_data_outstanding);
+int reply_trans(connection_struct * conn, char *inbuf, char *outbuf, int size,
+ int bufsize);
/*The following definitions come from smbd/lanman.c */
-int api_reply(connection_struct *conn,uint16 vuid,char *outbuf,char *data,char *params,
- int tdscnt,int tpscnt,int mdrcnt,int mprcnt);
+int api_reply(connection_struct * conn, uint16 vuid, char *outbuf, char *data,
+ char *params, int tdscnt, int tpscnt, int mdrcnt, int mprcnt);
/*The following definitions come from smbd/mangle.c */
void reset_mangled_cache( void );
BOOL check_mangled_cache( char *s );
void mangle_name_83( char *s);
-BOOL name_map_mangle(char *OutName, BOOL need83, int snum);
+BOOL name_map_mangle(char *OutName, BOOL need83, BOOL cache83, int snum);
/*The following definitions come from smbd/message.c */
/*The following definitions come from smbd/nttrans.c */
void fail_next_srvsvc_open(void);
+BOOL should_fail_next_srvsvc_open(const char *pipename);
int reply_ntcreate_and_X(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize);
int reply_ntcancel(connection_struct *conn,
int reply_nttranss(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize);
void remove_pending_change_notify_requests_by_fid(files_struct *fsp);
-void process_pending_change_notify_queue(time_t t);
+void remove_pending_change_notify_requests_by_filename(files_struct *fsp);
+BOOL process_pending_change_notify_queue(time_t t);
+BOOL change_notifies_pending(void);
int reply_nttrans(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize);
/*The following definitions come from smbd/open.c */
void fd_add_to_uid_cache(file_fd_struct *fd_ptr, uid_t u);
-uint16 fd_attempt_close(files_struct *fsp);
-void open_file_shared(files_struct *fsp, connection_struct *conn,
- char *fname, int share_mode, int ofun,
- mode_t mode, int oplock_request, int *Access,
- int *action);
+uint16 fd_attempt_close(files_struct *fsp, int *err_ret);
+void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int share_mode,int ofun,
+ mode_t mode,int oplock_request, int *Access,int *action);
+int open_file_stat(files_struct *fsp,connection_struct *conn,
+ char *fname, int smb_ofun, SMB_STRUCT_STAT *pst, int *action);
int open_directory(files_struct *fsp,connection_struct *conn,
char *fname, int smb_ofun, mode_t unixmode, int *action);
BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op);
/*The following definitions come from smbd/oplock.c */
+int32 get_number_of_exclusive_open_oplocks(void);
BOOL setup_kernel_oplock_pipe(void);
BOOL open_oplock_ipc(void);
BOOL receive_local_message(fd_set *fds, char *buffer, int buffer_len, int timeout);
-BOOL set_file_oplock(files_struct *fsp);
+BOOL set_file_oplock(files_struct *fsp, int oplock_type);
+void release_file_oplock(files_struct *fsp);
+BOOL remove_oplock(files_struct *fsp);
int setup_oplock_select_set( fd_set *fds);
BOOL process_local_message(char *buffer, int buf_size);
+BOOL oplock_break_level2(files_struct *fsp, BOOL local_request, int token);
BOOL request_oplock_break(share_mode_entry *share_entry,
SMB_DEV_T dev, SMB_INO_T inode);
BOOL attempt_close_oplocked_file(files_struct *fsp);
void add_session_user(char *user);
BOOL password_ok(const char *orig_user, const char *domain,
- const char *smb_apasswd, int smb_apasslen,
- const char *smb_ntpasswd, int smb_ntpasslen,
- struct passwd *pwd,
- NET_USER_INFO_3 *info3);
+ const char *smb_apasswd, int smb_apasslen,
+ const char *smb_ntpasswd, int smb_ntpasslen,
+ struct passwd *pwd, NET_USER_INFO_3 * info3);
BOOL authorise_login(int snum, char *user, char *domain,
- char *password, int pwlen,
- BOOL *guest,BOOL *force,
- const vuser_key *key);
+ char *password, int pwlen,
+ BOOL *guest, BOOL *force, const vuser_key * key);
+BOOL check_user_equiv_line(char *buf, const char *user, const char *remote,
+ BOOL *plus_allowed, BOOL *ret);
BOOL check_hosts_equiv(char *user);
/*The following definitions come from smbd/pipes.c */
-int reply_open_pipe_and_X(connection_struct *conn,
- char *inbuf,char *outbuf,int length,int bufsize);
-int reply_pipe_write(char *inbuf,char *outbuf,int length,int bufsize);
-int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize);
-int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize);
-int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf);
+int reply_open_pipe_and_X(connection_struct * conn,
+ char *inbuf, char *outbuf, int length, int bufsize);
+int reply_pipe_write(char *inbuf, char *outbuf, int length, int bufsize);
+int reply_pipe_write_and_X(char *inbuf, char *outbuf, int length, int bufsize);
+int reply_pipe_read_and_X(char *inbuf, char *outbuf, int length, int bufsize);
+int reply_pipe_close(connection_struct * conn, char *inbuf, char *outbuf);
/*The following definitions come from smbd/predict.c */
BOOL push_oplock_pending_smb_message(char *buf, int msg_len);
BOOL receive_next_smb(char *inbuf, int bufsize, int timeout);
+void respond_to_all_remaining_local_messages(void);
void process_smb(char *inbuf, char *outbuf);
char *smb_fn_name(int type);
void construct_reply_common(char *inbuf,char *outbuf);
int chain_reply(char *inbuf,char *outbuf,int size,int bufsize);
+void check_reload(int t);
void smbd_process(void);
/*The following definitions come from smbd/reply.c */
int dum_size, int dum_buffsize);
int reply_lockread(connection_struct * conn, char *inbuf, char *outbuf,
int length, int dum_buffsiz);
-int reply_read(connection_struct * conn, char *inbuf, char *outbuf,
- int dum_size, int dum_buffsize);
+int reply_read(connection_struct * conn, char *inbuf, char *outbuf, int size,
+ int dum_buffsize);
int reply_read_and_X(connection_struct * conn, char *inbuf, char *outbuf,
int length, int bufsize);
int reply_writebraw(connection_struct * conn, char *inbuf, char *outbuf,
- int dum_size, int dum_buffsize);
+ int size, int dum_buffsize);
int reply_writeunlock(connection_struct * conn, char *inbuf, char *outbuf,
- int dum_size, int dum_buffsize);
-int reply_write(connection_struct * conn, char *inbuf, char *outbuf,
- int dum_size, int dum_buffsize);
+ int size, int dum_buffsize);
+int reply_write(connection_struct * conn, char *inbuf, char *outbuf, int size,
+ int dum_buffsize);
int reply_write_and_X(connection_struct * conn, char *inbuf, char *outbuf,
int length, int bufsize);
-int reply_lseek(connection_struct * conn, char *inbuf, char *outbuf,
- int dum_size, int dum_buffsize);
-int reply_flush(connection_struct * conn, char *inbuf, char *outbuf,
- int dum_size, int dum_buffsize);
+int reply_lseek(connection_struct * conn, char *inbuf, char *outbuf, int size,
+ int dum_buffsize);
+int reply_flush(connection_struct * conn, char *inbuf, char *outbuf, int size,
+ int dum_buffsize);
int reply_exit(connection_struct * conn,
char *inbuf, char *outbuf, int dum_size, int dum_buffsize);
-int reply_close(connection_struct * conn,
- char *inbuf, char *outbuf, int dum_size, int dum_buffsize);
+int reply_close(connection_struct * conn, char *inbuf, char *outbuf, int size,
+ int dum_buffsize);
int reply_writeclose(connection_struct * conn,
- char *inbuf, char *outbuf, int dum_size,
- int dum_buffsize);
+ char *inbuf, char *outbuf, int size, int dum_buffsize);
int reply_lock(connection_struct * conn,
char *inbuf, char *outbuf, int length, int dum_buffsize);
int reply_unlock(connection_struct * conn, char *inbuf, char *outbuf,
- int dum_size, int dum_buffsize);
+ int size, int dum_buffsize);
int reply_tdis(connection_struct * conn,
char *inbuf, char *outbuf, int dum_size, int dum_buffsize);
int reply_echo(connection_struct * conn,
int dum_size, int dum_buffsize);
int reply_mkdir(connection_struct * conn, char *inbuf, char *outbuf,
int dum_size, int dum_buffsize);
+BOOL rmdir_internals(connection_struct * conn, char *directory);
int reply_rmdir(connection_struct * conn, char *inbuf, char *outbuf,
int dum_size, int dum_buffsize);
int rename_internals(connection_struct * conn,
int dum_size, int dum_buffsize);
int reply_setdir(connection_struct * conn, char *inbuf, char *outbuf,
int dum_size, int dum_buffsize);
+SMB_OFF_T get_lock_count(char *data, int data_offset, BOOL large_file_format,
+ BOOL *err);
+SMB_OFF_T get_lock_offset(char *data, int data_offset, BOOL large_file_format,
+ BOOL *err);
int reply_lockingX(connection_struct * conn, char *inbuf, char *outbuf,
int length, int bufsize);
int reply_readbmpx(connection_struct * conn, char *inbuf, char *outbuf,
int length, int bufsize);
int reply_writebmpx(connection_struct * conn, char *inbuf, char *outbuf,
- int dum_size, int dum_buffsize);
+ int size, int dum_buffsize);
int reply_writebs(connection_struct * conn, char *inbuf, char *outbuf,
int dum_size, int dum_buffsize);
int reply_setattrE(connection_struct * conn, char *inbuf, char *outbuf,
- int dum_size, int dum_buffsize);
+ int size, int dum_buffsize);
int reply_getattrE(connection_struct * conn, char *inbuf, char *outbuf,
- int dum_size, int dum_buffsize);
+ int size, int dum_buffsize);
/*The following definitions come from smbd/server.c */
int vfs_init_default(connection_struct *conn);
BOOL vfs_init_custom(connection_struct *conn);
+BOOL vfs_directory_exist(connection_struct *conn, char *dname,
+ SMB_STRUCT_STAT *st);
BOOL vfs_file_exist(connection_struct *conn,char *fname,SMB_STRUCT_STAT *sbuf);
ssize_t vfs_write_data(files_struct *fsp,char *buffer,size_t N);
SMB_OFF_T vfs_transfer_file(int in_fd, files_struct *in_fsp,
int vfswrap_dummy_connect(struct vfs_connection_struct *conn, char *service,
char *user);
void vfswrap_dummy_disconnect(void);
-SMB_BIG_UINT vfswrap_disk_free(char *path, SMB_BIG_UINT *bsize,
+SMB_BIG_UINT vfswrap_disk_free(char *path, BOOL small_query, SMB_BIG_UINT *bsize,
SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize);
DIR *vfswrap_opendir(char *fname);
struct dirent *vfswrap_readdir(DIR *dirp);
ssize_t vfswrap_write(int fd, char *data, size_t n);
SMB_OFF_T vfswrap_lseek(int filedes, SMB_OFF_T offset, int whence);
int vfswrap_rename(char *old, char *new);
-void vfswrap_sync_file(int fd);
+void vfswrap_fsync(int fd);
int vfswrap_stat(char *fname, SMB_STRUCT_STAT *sbuf);
int vfswrap_fstat(int fd, SMB_STRUCT_STAT *sbuf);
int vfswrap_lstat(char *path,
SMB_STRUCT_STAT *sbuf);
-BOOL vfswrap_fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count,
- int type);
int vfswrap_unlink(char *path);
int vfswrap_chmod(char *path, mode_t mode);
int vfswrap_utime(char *path, struct utimbuf *times);
/*The following definitions come from rpc_parse/parse_netsec.c */
-BOOL rpc_hdr_netsec_auth_chk(RPC_HDR_AUTH *rai);
-BOOL make_rpc_auth_netsec_neg(RPC_AUTH_NETSEC_NEG *neg,
- fstring domain,
- fstring myname);
-BOOL smb_io_rpc_auth_netsec_neg(char *desc, RPC_AUTH_NETSEC_NEG *neg, prs_struct *ps, int depth);
-BOOL make_rpc_auth_netsec_resp(RPC_AUTH_NETSEC_RESP *rsp, uint32 flags);
-BOOL smb_io_rpc_auth_netsec_resp(char *desc, RPC_AUTH_NETSEC_RESP *rsp, prs_struct *ps, int depth);
-BOOL rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK *chk);
-BOOL make_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK *chk,
- const uchar sig[8],
- const uchar data1[8],
- const uchar data3[8],
- const uchar data8[8]);
-BOOL smb_io_rpc_auth_netsec_chk(char *desc, RPC_AUTH_NETSEC_CHK *chk, prs_struct *ps, int depth);
+BOOL rpc_hdr_netsec_auth_chk(RPC_HDR_AUTH * rai);
+BOOL make_rpc_auth_netsec_neg(RPC_AUTH_NETSEC_NEG * neg,
+ fstring domain, fstring myname);
+BOOL smb_io_rpc_auth_netsec_neg(char *desc, RPC_AUTH_NETSEC_NEG * neg,
+ prs_struct *ps, int depth);
+BOOL make_rpc_auth_netsec_resp(RPC_AUTH_NETSEC_RESP * rsp, uint32 flags);
+BOOL smb_io_rpc_auth_netsec_resp(char *desc, RPC_AUTH_NETSEC_RESP * rsp,
+ prs_struct *ps, int depth);
+BOOL rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK * chk);
+BOOL make_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK * chk,
+ const uchar sig[8],
+ const uchar data1[8],
+ const uchar data3[8], const uchar data8[8]);
+BOOL smb_io_rpc_auth_netsec_chk(char *desc, RPC_AUTH_NETSEC_CHK * chk,
+ prs_struct *ps, int depth);
BOOL netsec_encode(struct netsec_auth_struct *a,
- RPC_AUTH_NETSEC_CHK *verf,
- char *data, size_t data_len);
+ RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len);
BOOL netsec_decode(struct netsec_auth_struct *a,
- RPC_AUTH_NETSEC_CHK *verf,
- char *data, size_t data_len);
+ RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len);
/*The following definitions come from rpc_parse/parse_reg.c */
-BOOL make_reg_q_open_hkcr(REG_Q_OPEN_HKCR *q_o,
- uint16 unknown_0, uint32 level);
-BOOL reg_io_q_open_hkcr(char *desc, REG_Q_OPEN_HKCR *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_open_hkcr(char *desc, REG_R_OPEN_HKCR *r_r, prs_struct *ps, int depth);
-BOOL make_reg_q_open_hklm(REG_Q_OPEN_HKLM *q_o,
- uint16 unknown_0, uint32 access_mask);
-BOOL reg_io_q_open_hklm(char *desc, REG_Q_OPEN_HKLM *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_open_hklm(char *desc, REG_R_OPEN_HKLM *r_r, prs_struct *ps, int depth);
-BOOL make_reg_q_flush_key(REG_Q_FLUSH_KEY *q_u, POLICY_HND *pol);
-BOOL reg_io_q_flush_key(char *desc, REG_Q_FLUSH_KEY *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_flush_key(char *desc, REG_R_FLUSH_KEY *r_r, prs_struct *ps, int depth);
-BOOL make_reg_q_create_key(REG_Q_CREATE_KEY *q_c, POLICY_HND *hnd,
- char *key_name, char *key_class,
- SEC_ACCESS *sam_access,
- SEC_DESC_BUF *sec_buf,
- int sec_len, SEC_DESC *sec);
-BOOL reg_io_q_create_key(char *desc, REG_Q_CREATE_KEY *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_create_key(char *desc, REG_R_CREATE_KEY *r_r, prs_struct *ps, int depth);
-BOOL make_reg_q_delete_val(REG_Q_DELETE_VALUE *q_c, POLICY_HND *hnd,
- char *name);
-BOOL reg_io_q_delete_val(char *desc, REG_Q_DELETE_VALUE *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_delete_val(char *desc, REG_R_DELETE_VALUE *r_r, prs_struct *ps, int depth);
-BOOL make_reg_q_delete_key(REG_Q_DELETE_KEY *q_c, POLICY_HND *hnd,
- char *name);
-BOOL reg_io_q_delete_key(char *desc, REG_Q_DELETE_KEY *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_delete_key(char *desc, REG_R_DELETE_KEY *r_r, prs_struct *ps, int depth);
-BOOL make_reg_q_query_key(REG_Q_QUERY_KEY *q_o, POLICY_HND *hnd,
- uint32 max_class_len);
-BOOL reg_io_q_query_key(char *desc, REG_Q_QUERY_KEY *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_query_key(char *desc, REG_R_QUERY_KEY *r_r, prs_struct *ps, int depth);
-BOOL make_reg_q_unk_1a(REG_Q_UNK_1A *q_o, POLICY_HND *hnd);
-BOOL reg_io_q_unk_1a(char *desc, REG_Q_UNK_1A *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_unk_1a(char *desc, REG_R_UNK_1A *r_r, prs_struct *ps, int depth);
-BOOL make_reg_q_open_hku(REG_Q_OPEN_HKU *q_o,
- uint16 unknown_0, uint32 level);
-BOOL reg_io_q_open_hku(char *desc, REG_Q_OPEN_HKU *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_open_hku(char *desc, REG_R_OPEN_HKU *r_r, prs_struct *ps, int depth);
-BOOL make_reg_q_close(REG_Q_CLOSE *q_c, POLICY_HND *hnd);
-BOOL reg_io_q_close(char *desc, REG_Q_CLOSE *q_u, prs_struct *ps, int depth);
-BOOL reg_io_r_close(char *desc, REG_R_CLOSE *r_u, prs_struct *ps, int depth);
-BOOL make_reg_q_set_key_sec(REG_Q_SET_KEY_SEC *q_i, POLICY_HND *pol,
- uint32 sec_info,
- uint32 buf_len, SEC_DESC *sec_desc);
-BOOL reg_io_q_set_key_sec(char *desc, REG_Q_SET_KEY_SEC *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_set_key_sec(char *desc, REG_R_SET_KEY_SEC *r_q, prs_struct *ps, int depth);
-BOOL make_reg_q_get_key_sec(REG_Q_GET_KEY_SEC *q_i, POLICY_HND *pol,
- uint32 sec_info,
- uint32 buf_len, SEC_DESC_BUF *sec_buf);
-BOOL reg_io_q_get_key_sec(char *desc, REG_Q_GET_KEY_SEC *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_get_key_sec(char *desc, REG_R_GET_KEY_SEC *r_q, prs_struct *ps, int depth);
-BOOL make_reg_q_info(REG_Q_INFO *q_i, POLICY_HND *pol, const char *val_name,
- uint8 major, uint8 minor);
-BOOL reg_io_q_info(char *desc, REG_Q_INFO *r_q, prs_struct *ps, int depth);
-BOOL make_reg_r_info(REG_R_INFO *r_r,
- uint32 *type, BUFFER2 *buf,
- uint32 status);
-BOOL reg_io_r_info(char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth);
-BOOL make_reg_q_enum_val(REG_Q_ENUM_VALUE *q_i, POLICY_HND *pol,
- uint32 val_idx, uint32 max_val_len,
- uint32 max_buf_len);
-BOOL reg_io_q_enum_val(char *desc, REG_Q_ENUM_VALUE *q_q, prs_struct *ps, int depth);
-BOOL reg_io_r_enum_val(char *desc, REG_R_ENUM_VALUE *r_q, prs_struct *ps, int depth);
-BOOL make_reg_q_create_val(REG_Q_CREATE_VALUE *q_i, POLICY_HND *pol,
- char *val_name, uint32 type,
- BUFFER3 *val);
-BOOL reg_io_q_create_val(char *desc, REG_Q_CREATE_VALUE *q_q, prs_struct *ps, int depth);
-BOOL reg_io_r_create_val(char *desc, REG_R_CREATE_VALUE *r_q, prs_struct *ps, int depth);
-BOOL make_reg_q_enum_key(REG_Q_ENUM_KEY *q_i, POLICY_HND *pol, uint32 key_idx);
-BOOL reg_io_q_enum_key(char *desc, REG_Q_ENUM_KEY *q_q, prs_struct *ps, int depth);
-BOOL reg_io_r_enum_key(char *desc, REG_R_ENUM_KEY *r_q, prs_struct *ps, int depth);
-BOOL make_reg_q_open_entry(REG_Q_OPEN_ENTRY *r_q, POLICY_HND *pol,
- char *key_name, uint32 access_mask);
-BOOL reg_io_q_open_entry(char *desc, REG_Q_OPEN_ENTRY *r_q, prs_struct *ps, int depth);
-BOOL make_reg_r_open_entry(REG_R_OPEN_ENTRY *r_r,
- POLICY_HND *pol, uint32 status);
-BOOL reg_io_r_open_entry(char *desc, REG_R_OPEN_ENTRY *r_r, prs_struct *ps, int depth);
-BOOL make_reg_q_shutdown(REG_Q_SHUTDOWN *q_i,
- const char *msg, uint32 timeout, uint16 flags);
-BOOL reg_io_q_shutdown(char *desc, REG_Q_SHUTDOWN *q_q, prs_struct *ps, int depth);
-BOOL reg_io_r_shutdown(char *desc, REG_R_SHUTDOWN *r_q, prs_struct *ps, int depth);
+BOOL make_reg_q_open_hkcr(REG_Q_OPEN_HKCR * q_o,
+ uint16 unknown_0, uint32 level);
+BOOL reg_io_q_open_hkcr(char *desc, REG_Q_OPEN_HKCR * r_q, prs_struct *ps,
+ int depth);
+BOOL reg_io_r_open_hkcr(char *desc, REG_R_OPEN_HKCR * r_r, prs_struct *ps,
+ int depth);
+BOOL make_reg_q_open_hklm(REG_Q_OPEN_HKLM * q_o,
+ uint16 unknown_0, uint32 access_mask);
+BOOL reg_io_q_open_hklm(char *desc, REG_Q_OPEN_HKLM * r_q, prs_struct *ps,
+ int depth);
+BOOL reg_io_r_open_hklm(char *desc, REG_R_OPEN_HKLM * r_r, prs_struct *ps,
+ int depth);
+BOOL make_reg_q_flush_key(REG_Q_FLUSH_KEY * q_u, POLICY_HND *pol);
+BOOL reg_io_q_flush_key(char *desc, REG_Q_FLUSH_KEY * r_q, prs_struct *ps,
+ int depth);
+BOOL reg_io_r_flush_key(char *desc, REG_R_FLUSH_KEY * r_r, prs_struct *ps,
+ int depth);
+BOOL make_reg_q_create_key(REG_Q_CREATE_KEY * q_c, POLICY_HND *hnd,
+ char *key_name, char *key_class,
+ SEC_ACCESS * sam_access,
+ SEC_DESC_BUF * sec_buf,
+ int sec_len, SEC_DESC * sec);
+BOOL reg_io_q_create_key(char *desc, REG_Q_CREATE_KEY * r_q, prs_struct *ps,
+ int depth);
+BOOL reg_io_r_create_key(char *desc, REG_R_CREATE_KEY * r_r, prs_struct *ps,
+ int depth);
+BOOL make_reg_q_delete_val(REG_Q_DELETE_VALUE * q_c, POLICY_HND *hnd,
+ char *name);
+BOOL reg_io_q_delete_val(char *desc, REG_Q_DELETE_VALUE * r_q, prs_struct *ps,
+ int depth);
+BOOL reg_io_r_delete_val(char *desc, REG_R_DELETE_VALUE * r_r, prs_struct *ps,
+ int depth);
+BOOL make_reg_q_delete_key(REG_Q_DELETE_KEY * q_c, POLICY_HND *hnd,
+ char *name);
+BOOL reg_io_q_delete_key(char *desc, REG_Q_DELETE_KEY * r_q, prs_struct *ps,
+ int depth);
+BOOL reg_io_r_delete_key(char *desc, REG_R_DELETE_KEY * r_r, prs_struct *ps,
+ int depth);
+BOOL make_reg_q_query_key(REG_Q_QUERY_KEY * q_o, POLICY_HND *hnd,
+ uint32 max_class_len);
+BOOL reg_io_q_query_key(char *desc, REG_Q_QUERY_KEY * r_q, prs_struct *ps,
+ int depth);
+BOOL reg_io_r_query_key(char *desc, REG_R_QUERY_KEY * r_r, prs_struct *ps,
+ int depth);
+BOOL make_reg_q_unk_1a(REG_Q_UNK_1A * q_o, POLICY_HND *hnd);
+BOOL reg_io_q_unk_1a(char *desc, REG_Q_UNK_1A * r_q, prs_struct *ps,
+ int depth);
+BOOL reg_io_r_unk_1a(char *desc, REG_R_UNK_1A * r_r, prs_struct *ps,
+ int depth);
+BOOL make_reg_q_open_hku(REG_Q_OPEN_HKU * q_o, uint16 unknown_0, uint32 level);
+BOOL reg_io_q_open_hku(char *desc, REG_Q_OPEN_HKU * r_q, prs_struct *ps,
+ int depth);
+BOOL reg_io_r_open_hku(char *desc, REG_R_OPEN_HKU * r_r, prs_struct *ps,
+ int depth);
+BOOL make_reg_q_close(REG_Q_CLOSE * q_c, POLICY_HND *hnd);
+BOOL reg_io_q_close(char *desc, REG_Q_CLOSE * q_u, prs_struct *ps, int depth);
+BOOL reg_io_r_close(char *desc, REG_R_CLOSE * r_u, prs_struct *ps, int depth);
+BOOL make_reg_q_set_key_sec(REG_Q_SET_KEY_SEC * q_i, POLICY_HND *pol,
+ uint32 sec_info,
+ uint32 buf_len, SEC_DESC * sec_desc);
+BOOL reg_io_q_set_key_sec(char *desc, REG_Q_SET_KEY_SEC * r_q, prs_struct *ps,
+ int depth);
+BOOL reg_io_r_set_key_sec(char *desc, REG_R_SET_KEY_SEC * r_q, prs_struct *ps,
+ int depth);
+BOOL make_reg_q_get_key_sec(REG_Q_GET_KEY_SEC * q_i, POLICY_HND *pol,
+ uint32 sec_info,
+ uint32 buf_len, SEC_DESC_BUF * sec_buf);
+BOOL reg_io_q_get_key_sec(char *desc, REG_Q_GET_KEY_SEC * r_q, prs_struct *ps,
+ int depth);
+void make_reg_r_get_key_sec(REG_R_GET_KEY_SEC * r_i, POLICY_HND *pol,
+ uint32 buf_len, uint8 *buf, uint32 status);
+BOOL reg_io_r_get_key_sec(char *desc, REG_R_GET_KEY_SEC * r_q, prs_struct *ps,
+ int depth);
+BOOL make_reg_q_info(REG_Q_INFO * q_i, POLICY_HND *pol, const char *val_name,
+ uint8 major, uint8 minor);
+BOOL reg_io_q_info(char *desc, REG_Q_INFO * r_q, prs_struct *ps, int depth);
+BOOL make_reg_r_info(REG_R_INFO * r_r,
+ uint32 *type, BUFFER2 * buf, uint32 status);
+BOOL reg_io_r_info(char *desc, REG_R_INFO * r_r, prs_struct *ps, int depth);
+BOOL make_reg_q_enum_val(REG_Q_ENUM_VALUE * q_i, POLICY_HND *pol,
+ uint32 val_idx, uint32 max_val_len,
+ uint32 max_buf_len);
+BOOL reg_io_q_enum_val(char *desc, REG_Q_ENUM_VALUE * q_q, prs_struct *ps,
+ int depth);
+BOOL reg_io_r_enum_val(char *desc, REG_R_ENUM_VALUE * r_q, prs_struct *ps,
+ int depth);
+BOOL make_reg_q_create_val(REG_Q_CREATE_VALUE * q_i, POLICY_HND *pol,
+ char *val_name, uint32 type, BUFFER3 * val);
+BOOL reg_io_q_create_val(char *desc, REG_Q_CREATE_VALUE * q_q, prs_struct *ps,
+ int depth);
+BOOL reg_io_r_create_val(char *desc, REG_R_CREATE_VALUE * r_q, prs_struct *ps,
+ int depth);
+BOOL make_reg_q_enum_key(REG_Q_ENUM_KEY * q_i, POLICY_HND *pol,
+ uint32 key_idx);
+BOOL reg_io_q_enum_key(char *desc, REG_Q_ENUM_KEY * q_q, prs_struct *ps,
+ int depth);
+BOOL reg_io_r_enum_key(char *desc, REG_R_ENUM_KEY * r_q, prs_struct *ps,
+ int depth);
+BOOL make_reg_q_open_entry(REG_Q_OPEN_ENTRY * r_q, POLICY_HND *pol,
+ char *key_name, uint32 access_mask);
+BOOL reg_io_q_open_entry(char *desc, REG_Q_OPEN_ENTRY * r_q, prs_struct *ps,
+ int depth);
+BOOL make_reg_r_open_entry(REG_R_OPEN_ENTRY * r_r,
+ POLICY_HND *pol, uint32 status);
+BOOL reg_io_r_open_entry(char *desc, REG_R_OPEN_ENTRY * r_r, prs_struct *ps,
+ int depth);
+BOOL make_reg_q_shutdown(REG_Q_SHUTDOWN * q_i,
+ const char *msg, uint32 timeout, uint16 flags);
+BOOL reg_io_q_shutdown(char *desc, REG_Q_SHUTDOWN * q_q, prs_struct *ps,
+ int depth);
+BOOL reg_io_r_shutdown(char *desc, REG_R_SHUTDOWN * r_q, prs_struct *ps,
+ int depth);
/*The following definitions come from rpc_parse/parse_rpc.c */
/*The following definitions come from rpc_parse/parse_samr.c */
-BOOL make_samr_q_close_hnd(SAMR_Q_CLOSE_HND * q_c, POLICY_HND * hnd);
+BOOL make_samr_q_close_hnd(SAMR_Q_CLOSE_HND * q_c, POLICY_HND *hnd);
BOOL samr_io_q_close_hnd(char *desc, SAMR_Q_CLOSE_HND * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL samr_io_r_close_hnd(char *desc, SAMR_R_CLOSE_HND * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_lookup_domain(SAMR_Q_LOOKUP_DOMAIN * q_u,
- POLICY_HND * pol, const char *dom_name);
+ POLICY_HND *pol, const char *dom_name);
BOOL samr_io_q_lookup_domain(char *desc, SAMR_Q_LOOKUP_DOMAIN * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_r_lookup_domain(SAMR_R_LOOKUP_DOMAIN * r_u,
- DOM_SID * dom_sid, uint32 status);
+ DOM_SID *dom_sid, uint32 status);
BOOL samr_io_r_lookup_domain(char *desc, SAMR_R_LOOKUP_DOMAIN * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_unknown_2d(SAMR_Q_UNKNOWN_2D * q_u,
- const POLICY_HND * dom_pol, const DOM_SID * sid);
+ const POLICY_HND *dom_pol, const DOM_SID *sid);
BOOL samr_io_q_unknown_2d(char *desc, SAMR_Q_UNKNOWN_2D * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL samr_io_r_unknown_2d(char *desc, SAMR_R_UNKNOWN_2D * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_open_domain(SAMR_Q_OPEN_DOMAIN * q_u,
- const POLICY_HND * connect_pol, uint32 flags,
- const DOM_SID * sid);
+ const POLICY_HND *connect_pol, uint32 flags,
+ const DOM_SID *sid);
BOOL samr_io_q_open_domain(char *desc, SAMR_Q_OPEN_DOMAIN * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL samr_io_r_open_domain(char *desc, SAMR_R_OPEN_DOMAIN * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_get_usrdom_pwinfo(SAMR_Q_GET_USRDOM_PWINFO * q_u,
- POLICY_HND * user_pol);
+ POLICY_HND *user_pol);
BOOL samr_io_q_get_usrdom_pwinfo(char *desc, SAMR_Q_GET_USRDOM_PWINFO * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL samr_io_r_get_usrdom_pwinfo(char *desc, SAMR_R_GET_USRDOM_PWINFO * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_query_sec_obj(SAMR_Q_QUERY_SEC_OBJ * q_u,
- const POLICY_HND * user_pol, uint32 sec_info);
+ const POLICY_HND *user_pol, uint32 sec_info);
BOOL samr_io_q_query_sec_obj(char *desc, SAMR_Q_QUERY_SEC_OBJ * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO * q_u,
- POLICY_HND * domain_pol, uint16 switch_value);
+ POLICY_HND *domain_pol, uint16 switch_value);
BOOL samr_io_q_query_dom_info(char *desc, SAMR_Q_QUERY_DOMAIN_INFO * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_unk_info3(SAM_UNK_INFO_3 * u_3);
BOOL make_unk_info6(SAM_UNK_INFO_6 * u_6);
BOOL make_unk_info7(SAM_UNK_INFO_7 * u_7);
uint16 switch_value, SAM_UNK_CTR * ctr,
uint32 status);
BOOL samr_io_r_query_dom_info(char *desc, SAMR_R_QUERY_DOMAIN_INFO * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL samr_io_r_query_sec_obj(char *desc, SAMR_R_QUERY_SEC_OBJ * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_sam_entry(SAM_ENTRY * sam, uint32 len_sam_name, uint32 rid);
-BOOL make_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS * q_e, POLICY_HND * pol,
+BOOL make_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS * q_e, POLICY_HND *pol,
uint32 start_idx,
uint16 acb_mask, uint16 unk_1, uint32 size);
BOOL samr_io_q_enum_dom_users(char *desc, SAMR_Q_ENUM_DOM_USERS * q_e,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_r_enum_dom_users(SAMR_R_ENUM_DOM_USERS * r_u,
uint32 next_idx, uint32 num_sam_entries);
BOOL samr_io_r_enum_dom_users(char *desc, SAMR_R_ENUM_DOM_USERS * r_u,
- prs_struct * ps, int depth);
-BOOL make_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO * q_e, POLICY_HND * pol,
+ prs_struct *ps, int depth);
+BOOL make_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO * q_e, POLICY_HND *pol,
uint16 switch_level, uint32 start_idx,
uint32 max_entries);
BOOL samr_io_q_query_dispinfo(char *desc, SAMR_Q_QUERY_DISPINFO * q_e,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_sam_dispinfo_1(SAM_DISPINFO_1 * sam, uint32 *num_entries,
uint32 *data_size, uint32 start_idx,
SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]);
uint16 switch_level, SAM_DISPINFO_CTR * ctr,
uint32 status);
BOOL samr_io_r_query_dispinfo(char *desc, SAMR_R_QUERY_DISPINFO * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_open_group(SAMR_Q_OPEN_GROUP * q_c,
- const POLICY_HND * hnd,
+ const POLICY_HND *hnd,
uint32 access_mask, uint32 rid);
BOOL samr_io_q_open_group(char *desc, SAMR_Q_OPEN_GROUP * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL samr_io_r_open_group(char *desc, SAMR_R_OPEN_GROUP * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_group_info1(GROUP_INFO1 * gr1,
char *acct_name, char *acct_desc,
uint32 num_members);
BOOL samr_io_group_info1(char *desc, GROUP_INFO1 * gr1,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_group_info4(GROUP_INFO4 * gr4, const char *acct_desc);
BOOL samr_io_group_info4(char *desc, GROUP_INFO4 * gr4,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_create_dom_group(SAMR_Q_CREATE_DOM_GROUP * q_e,
- POLICY_HND * pol, const char *acct_desc);
+ POLICY_HND *pol, const char *acct_desc);
BOOL samr_io_q_create_dom_group(char *desc, SAMR_Q_CREATE_DOM_GROUP * q_e,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL samr_io_r_create_dom_group(char *desc, SAMR_R_CREATE_DOM_GROUP * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_delete_dom_group(SAMR_Q_DELETE_DOM_GROUP * q_c,
- POLICY_HND * hnd);
+ POLICY_HND *hnd);
BOOL samr_io_q_delete_dom_group(char *desc, SAMR_Q_DELETE_DOM_GROUP * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL samr_io_r_delete_dom_group(char *desc, SAMR_R_DELETE_DOM_GROUP * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_del_groupmem(SAMR_Q_DEL_GROUPMEM * q_e,
- POLICY_HND * pol, uint32 rid);
+ POLICY_HND *pol, uint32 rid);
BOOL samr_io_q_del_groupmem(char *desc, SAMR_Q_DEL_GROUPMEM * q_e,
- prs_struct * ps, int depth);
-BOOL make_samr_r_del_groupmem(SAMR_R_DEL_GROUPMEM * r_u, POLICY_HND * pol,
+ prs_struct *ps, int depth);
+BOOL make_samr_r_del_groupmem(SAMR_R_DEL_GROUPMEM * r_u, POLICY_HND *pol,
uint32 status);
BOOL samr_io_r_del_groupmem(char *desc, SAMR_R_DEL_GROUPMEM * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_add_groupmem(SAMR_Q_ADD_GROUPMEM * q_e,
- POLICY_HND * pol, uint32 rid);
+ POLICY_HND *pol, uint32 rid);
BOOL samr_io_q_add_groupmem(char *desc, SAMR_Q_ADD_GROUPMEM * q_e,
- prs_struct * ps, int depth);
-BOOL make_samr_r_add_groupmem(SAMR_R_ADD_GROUPMEM * r_u, POLICY_HND * pol,
+ prs_struct *ps, int depth);
+BOOL make_samr_r_add_groupmem(SAMR_R_ADD_GROUPMEM * r_u, POLICY_HND *pol,
uint32 status);
BOOL samr_io_r_add_groupmem(char *desc, SAMR_R_ADD_GROUPMEM * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_set_groupinfo(SAMR_Q_SET_GROUPINFO * q_e,
- POLICY_HND * pol, GROUP_INFO_CTR * ctr);
+ POLICY_HND *pol, GROUP_INFO_CTR * ctr);
BOOL samr_io_q_set_groupinfo(char *desc, SAMR_Q_SET_GROUPINFO * q_e,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_r_set_groupinfo(SAMR_R_SET_GROUPINFO * r_u, uint32 status);
BOOL samr_io_r_set_groupinfo(char *desc, SAMR_R_SET_GROUPINFO * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_query_groupinfo(SAMR_Q_QUERY_GROUPINFO * q_e,
- POLICY_HND * pol, uint16 switch_level);
+ POLICY_HND *pol, uint16 switch_level);
BOOL samr_io_q_query_groupinfo(char *desc, SAMR_Q_QUERY_GROUPINFO * q_e,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_r_query_groupinfo(SAMR_R_QUERY_GROUPINFO * r_u,
GROUP_INFO_CTR * ctr, uint32 status);
BOOL samr_io_r_query_groupinfo(char *desc, SAMR_R_QUERY_GROUPINFO * r_u,
- prs_struct * ps, int depth);
-BOOL make_samr_q_query_groupmem(SAMR_Q_QUERY_GROUPMEM * q_c, POLICY_HND * hnd);
+ prs_struct *ps, int depth);
+BOOL make_samr_q_query_groupmem(SAMR_Q_QUERY_GROUPMEM * q_c, POLICY_HND *hnd);
BOOL samr_io_q_query_groupmem(char *desc, SAMR_Q_QUERY_GROUPMEM * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_r_query_groupmem(SAMR_R_QUERY_GROUPMEM * r_u,
uint32 num_entries, uint32 *rid,
uint32 *attr, uint32 status);
BOOL samr_io_r_query_groupmem(char *desc, SAMR_R_QUERY_GROUPMEM * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
void samr_free_r_query_groupmem(SAMR_R_QUERY_GROUPMEM * r_u);
BOOL make_samr_q_query_usergroups(SAMR_Q_QUERY_USERGROUPS * q_u,
- POLICY_HND * hnd);
+ POLICY_HND *hnd);
BOOL samr_io_q_query_usergroups(char *desc, SAMR_Q_QUERY_USERGROUPS * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS * r_u,
uint32 num_gids, DOM_GID * gid,
uint32 status);
BOOL samr_io_gids(char *desc, uint32 *num_gids, DOM_GID ** gid,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL samr_io_r_query_usergroups(char *desc, SAMR_R_QUERY_USERGROUPS * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_enum_domains(SAMR_Q_ENUM_DOMAINS * q_e,
- const POLICY_HND * pol,
+ const POLICY_HND *pol,
uint32 start_idx, uint32 size);
BOOL samr_io_q_enum_domains(char *desc, SAMR_Q_ENUM_DOMAINS * q_e,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_r_enum_domains(SAMR_R_ENUM_DOMAINS * r_u,
uint32 next_idx, uint32 num_sam_entries);
BOOL samr_io_r_enum_domains(char *desc, SAMR_R_ENUM_DOMAINS * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS * q_e,
- const POLICY_HND * pol,
+ const POLICY_HND *pol,
uint32 start_idx, uint32 size);
BOOL samr_io_q_enum_dom_groups(char *desc, SAMR_Q_ENUM_DOM_GROUPS * q_e,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_r_enum_dom_groups(SAMR_R_ENUM_DOM_GROUPS * r_u,
uint32 next_idx, uint32 num_sam_entries);
BOOL samr_io_r_enum_dom_groups(char *desc, SAMR_R_ENUM_DOM_GROUPS * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES * q_e,
- POLICY_HND * pol, uint32 start_idx,
+ POLICY_HND *pol, uint32 start_idx,
uint32 size);
BOOL samr_io_q_enum_dom_aliases(char *desc, SAMR_Q_ENUM_DOM_ALIASES * q_e,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_r_enum_dom_aliases(SAMR_R_ENUM_DOM_ALIASES * r_u,
uint32 next_idx, uint32 num_sam_entries);
BOOL samr_io_r_enum_dom_aliases(char *desc, SAMR_R_ENUM_DOM_ALIASES * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_alias_info3(ALIAS_INFO3 * al3, const char *acct_desc);
BOOL samr_io_alias_info3(char *desc, ALIAS_INFO3 * al3,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL samr_alias_info_ctr(char *desc, ALIAS_INFO_CTR * ctr,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO * q_e,
- const POLICY_HND * pol, uint16 switch_level);
+ const POLICY_HND *pol, uint16 switch_level);
BOOL samr_io_q_query_aliasinfo(char *desc, SAMR_Q_QUERY_ALIASINFO * q_e,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_r_query_aliasinfo(SAMR_R_QUERY_ALIASINFO * r_u,
ALIAS_INFO_CTR * ctr, uint32 status);
BOOL samr_io_r_query_aliasinfo(char *desc, SAMR_R_QUERY_ALIASINFO * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_set_aliasinfo(SAMR_Q_SET_ALIASINFO * q_u,
- const POLICY_HND * hnd, ALIAS_INFO_CTR * ctr);
+ const POLICY_HND *hnd, ALIAS_INFO_CTR * ctr);
BOOL samr_io_q_set_aliasinfo(char *desc, SAMR_Q_SET_ALIASINFO * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL samr_io_r_set_aliasinfo(char *desc, SAMR_R_SET_ALIASINFO * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_query_useraliases(SAMR_Q_QUERY_USERALIASES * q_u,
- const POLICY_HND * hnd,
+ const POLICY_HND *hnd,
uint32 num_sids,
uint32 *ptr_sid, DOM_SID2 * sid);
BOOL samr_io_q_query_useraliases(char *desc, SAMR_Q_QUERY_USERALIASES * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
void samr_free_q_query_useraliases(SAMR_Q_QUERY_USERALIASES * q_u);
BOOL make_samr_r_query_useraliases(SAMR_R_QUERY_USERALIASES * r_u,
uint32 num_rids, uint32 *rid,
uint32 status);
BOOL samr_io_rids(char *desc, uint32 *num_rids, uint32 **rid,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL samr_io_r_query_useraliases(char *desc, SAMR_R_QUERY_USERALIASES * r_u,
- prs_struct * ps, int depth);
-BOOL make_samr_q_open_alias(SAMR_Q_OPEN_ALIAS * q_u, const POLICY_HND * pol,
+ prs_struct *ps, int depth);
+BOOL make_samr_q_open_alias(SAMR_Q_OPEN_ALIAS * q_u, const POLICY_HND *pol,
uint32 unknown_0, uint32 rid);
BOOL samr_io_q_open_alias(char *desc, SAMR_Q_OPEN_ALIAS * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL samr_io_r_open_alias(char *desc, SAMR_R_OPEN_ALIAS * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_lookup_rids(SAMR_Q_LOOKUP_RIDS * q_u,
- const POLICY_HND * pol, uint32 flags,
+ const POLICY_HND *pol, uint32 flags,
uint32 num_rids, const uint32 *rid);
BOOL samr_io_q_lookup_rids(char *desc, SAMR_Q_LOOKUP_RIDS * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
void samr_free_q_lookup_rids(SAMR_Q_LOOKUP_RIDS * q_u);
BOOL make_samr_r_lookup_rids(SAMR_R_LOOKUP_RIDS * r_u,
uint32 num_names, UNIHDR * hdr_name,
- UNISTR2 * uni_name, uint32 *type);
+ UNISTR2 *uni_name, uint32 *type);
BOOL samr_io_r_lookup_rids(char *desc, SAMR_R_LOOKUP_RIDS * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
void samr_free_r_lookup_rids(SAMR_R_LOOKUP_RIDS * r_u);
-BOOL make_samr_q_delete_alias(SAMR_Q_DELETE_DOM_ALIAS * q_u, POLICY_HND * hnd);
+BOOL make_samr_q_delete_alias(SAMR_Q_DELETE_DOM_ALIAS * q_u, POLICY_HND *hnd);
BOOL samr_io_q_delete_alias(char *desc, SAMR_Q_DELETE_DOM_ALIAS * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL samr_io_r_delete_alias(char *desc, SAMR_R_DELETE_DOM_ALIAS * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_create_dom_alias(SAMR_Q_CREATE_DOM_ALIAS * q_u,
- POLICY_HND * hnd, const char *acct_desc);
+ POLICY_HND *hnd, const char *acct_desc);
BOOL samr_io_q_create_dom_alias(char *desc, SAMR_Q_CREATE_DOM_ALIAS * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL samr_io_r_create_dom_alias(char *desc, SAMR_R_CREATE_DOM_ALIAS * r_u,
- prs_struct * ps, int depth);
-BOOL make_samr_q_add_aliasmem(SAMR_Q_ADD_ALIASMEM * q_u, POLICY_HND * hnd,
- DOM_SID * sid);
+ prs_struct *ps, int depth);
+BOOL make_samr_q_add_aliasmem(SAMR_Q_ADD_ALIASMEM * q_u, POLICY_HND *hnd,
+ DOM_SID *sid);
BOOL samr_io_q_add_aliasmem(char *desc, SAMR_Q_ADD_ALIASMEM * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL samr_io_r_add_aliasmem(char *desc, SAMR_R_ADD_ALIASMEM * r_u,
- prs_struct * ps, int depth);
-BOOL make_samr_q_del_aliasmem(SAMR_Q_DEL_ALIASMEM * q_u, POLICY_HND * hnd,
- DOM_SID * sid);
+ prs_struct *ps, int depth);
+BOOL make_samr_q_del_aliasmem(SAMR_Q_DEL_ALIASMEM * q_u, POLICY_HND *hnd,
+ DOM_SID *sid);
BOOL samr_io_q_del_aliasmem(char *desc, SAMR_Q_DEL_ALIASMEM * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL samr_io_r_del_aliasmem(char *desc, SAMR_R_DEL_ALIASMEM * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_delete_dom_alias(SAMR_Q_DELETE_DOM_ALIAS * q_c,
- POLICY_HND * hnd);
+ POLICY_HND *hnd);
BOOL samr_io_q_delete_dom_alias(char *desc, SAMR_Q_DELETE_DOM_ALIAS * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_r_delete_dom_alias(SAMR_R_DELETE_DOM_ALIAS * r_u,
uint32 status);
BOOL samr_io_r_delete_dom_alias(char *desc, SAMR_R_DELETE_DOM_ALIAS * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_query_aliasmem(SAMR_Q_QUERY_ALIASMEM * q_c,
- const POLICY_HND * hnd);
+ const POLICY_HND *hnd);
BOOL samr_io_q_query_aliasmem(char *desc, SAMR_Q_QUERY_ALIASMEM * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_r_query_aliasmem(SAMR_R_QUERY_ALIASMEM * r_u,
uint32 num_sids, DOM_SID2 * sid,
uint32 status);
BOOL samr_io_r_query_aliasmem(char *desc, SAMR_R_QUERY_ALIASMEM * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_lookup_names(SAMR_Q_LOOKUP_NAMES * q_u,
- const POLICY_HND * pol, uint32 flags,
+ const POLICY_HND *pol, uint32 flags,
uint32 num_names, char **name);
BOOL samr_io_q_lookup_names(char *desc, SAMR_Q_LOOKUP_NAMES * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
void samr_free_q_lookup_names(SAMR_Q_LOOKUP_NAMES * q_l);
BOOL make_samr_r_lookup_names(SAMR_R_LOOKUP_NAMES * r_u,
uint32 num_rids,
const uint32 *rid, const uint32 *type,
uint32 status);
BOOL samr_io_r_lookup_names(char *desc, SAMR_R_LOOKUP_NAMES * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
void samr_free_r_lookup_names(SAMR_R_LOOKUP_NAMES * r_l);
BOOL make_samr_q_delete_dom_user(SAMR_Q_DELETE_DOM_USER * q_c,
- POLICY_HND * hnd);
+ POLICY_HND *hnd);
BOOL samr_io_q_delete_dom_user(char *desc, SAMR_Q_DELETE_DOM_USER * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL samr_io_r_delete_dom_user(char *desc, SAMR_R_DELETE_DOM_USER * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_open_user(SAMR_Q_OPEN_USER * q_u,
- const POLICY_HND * pol,
+ const POLICY_HND *pol,
uint32 access_mask, uint32 rid);
BOOL samr_io_q_open_user(char *desc, SAMR_Q_OPEN_USER * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL samr_io_r_open_user(char *desc, SAMR_R_OPEN_USER * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_create_user(SAMR_Q_CREATE_USER * q_u,
- POLICY_HND * pol,
+ POLICY_HND *pol,
const char *name,
uint32 acb_info, uint32 access_mask);
BOOL samr_io_q_create_user(char *desc, SAMR_Q_CREATE_USER * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL samr_io_r_create_user(char *desc, SAMR_R_CREATE_USER * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_query_userinfo(SAMR_Q_QUERY_USERINFO * q_u,
- POLICY_HND * hnd, uint16 switch_value);
+ POLICY_HND *hnd, uint16 switch_value);
BOOL samr_io_q_query_userinfo(char *desc, SAMR_Q_QUERY_USERINFO * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_sam_user_info12(SAM_USER_INFO_12 * usr,
const uint8 lm_pwd[16], const uint8 nt_pwd[16]);
BOOL sam_io_user_info12(char *desc, SAM_USER_INFO_12 * u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_sam_user_info10(SAM_USER_INFO_10 * usr, uint32 acb_info);
BOOL sam_io_user_info10(char *desc, SAM_USER_INFO_10 * usr,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_sam_user_info11(SAM_USER_INFO_11 * usr,
NTTIME * expiry,
char *mach_acct,
uint32 rid_user, uint32 rid_group, uint16 acct_ctrl);
BOOL sam_io_user_info11(char *desc, SAM_USER_INFO_11 * usr,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_sam_user_info24(SAM_USER_INFO_24 * usr,
const char newpass[516], uint16 passlen);
BOOL make_sam_user_info23W(SAM_USER_INFO_23 * usr, const NTTIME * logon_time, /* all zeros */
const NTTIME * pass_last_set_time, /* all zeros */
const NTTIME * pass_can_change_time, /* all zeros */
const NTTIME * pass_must_change_time, /* all zeros */
- const UNISTR2 * user_name,
- const UNISTR2 * full_name,
- const UNISTR2 * home_dir,
- const UNISTR2 * dir_drive,
- const UNISTR2 * log_scr,
- const UNISTR2 * prof_path,
- const UNISTR2 * desc,
- const UNISTR2 * wkstas,
- const UNISTR2 * unk_str,
- const UNISTR2 * mung_dial, uint32 user_rid, /* 0x0000 0000 */
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name, const UNISTR2 *home_dir, const UNISTR2 *dir_drive, const UNISTR2 *log_scr, const UNISTR2 *prof_path, const UNISTR2 *desc, const UNISTR2 *wkstas, const UNISTR2 *unk_str, const UNISTR2 *mung_dial, uint32 user_rid, /* 0x0000 0000 */
uint32 group_rid,
uint32 acb_info,
uint32 unknown_3,
const NTTIME * pass_last_set_time,
const NTTIME * pass_can_change_time,
const NTTIME * pass_must_change_time,
- const UNISTR2 * user_name,
- const UNISTR2 * full_name,
- const UNISTR2 * home_dir,
- const UNISTR2 * dir_drive,
- const UNISTR2 * log_scr,
- const UNISTR2 * prof_path,
- const UNISTR2 * desc,
- const UNISTR2 * wkstas,
- const UNISTR2 * unk_str,
- const UNISTR2 * mung_dial,
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *desc,
+ const UNISTR2 *wkstas,
+ const UNISTR2 *unk_str,
+ const UNISTR2 *mung_dial,
const uchar lm_pwd[16],
const uchar nt_pwd[16],
uint32 user_rid,
LOGON_HRS * hrs,
uint32 unknown_5, uint32 unknown_6);
BOOL sam_io_user_info21(char *desc, SAM_USER_INFO_21 * usr,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
uint32 make_samr_userinfo_ctr_usr21(SAM_USERINFO_CTR * ctr,
uint16 switch_value,
const SAM_USER_INFO_21 * usr);
BOOL make_samr_r_query_userinfo(SAMR_R_QUERY_USERINFO * r_u,
SAM_USERINFO_CTR * ctr, uint32 status);
BOOL samr_io_r_query_userinfo(char *desc, SAMR_R_QUERY_USERINFO * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_set_userinfo(SAMR_Q_SET_USERINFO * q_u,
- POLICY_HND * hnd,
+ POLICY_HND *hnd,
uint16 switch_value, void *info);
BOOL samr_io_q_set_userinfo(char *desc, SAMR_Q_SET_USERINFO * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
void free_samr_q_set_userinfo(SAMR_Q_SET_USERINFO * q_u);
BOOL make_samr_r_set_userinfo(SAMR_R_SET_USERINFO * r_u, uint32 status);
BOOL samr_io_r_set_userinfo(char *desc, SAMR_R_SET_USERINFO * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 * q_u,
- POLICY_HND * hnd,
+ POLICY_HND *hnd,
uint16 switch_value, SAM_USERINFO_CTR * ctr);
BOOL samr_io_q_set_userinfo2(char *desc, SAMR_Q_SET_USERINFO2 * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
void free_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 * q_u);
BOOL make_samr_r_set_userinfo2(SAMR_R_SET_USERINFO2 * r_u, uint32 status);
BOOL samr_io_r_set_userinfo2(char *desc, SAMR_R_SET_USERINFO2 * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_connect(SAMR_Q_CONNECT * q_u,
const char *srv_name, uint32 access_mask);
BOOL samr_io_q_connect(char *desc, SAMR_Q_CONNECT * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL samr_io_r_connect(char *desc, SAMR_R_CONNECT * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_connect_anon(SAMR_Q_CONNECT_ANON * q_u);
BOOL samr_io_q_connect_anon(char *desc, SAMR_Q_CONNECT_ANON * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL samr_io_r_connect_anon(char *desc, SAMR_R_CONNECT_ANON * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_get_dom_pwinfo(SAMR_Q_GET_DOM_PWINFO * q_u,
const char *srv_name);
BOOL samr_io_q_get_dom_pwinfo(char *desc, SAMR_Q_GET_DOM_PWINFO * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL samr_io_r_get_dom_pwinfo(char *desc, SAMR_R_GET_DOM_PWINFO * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_enc_passwd(SAMR_ENC_PASSWD * pwd, const char pass[512]);
BOOL samr_io_enc_passwd(char *desc, SAMR_ENC_PASSWD * pwd,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_enc_hash(SAMR_ENC_HASH * hsh, const uchar hash[16]);
BOOL samr_io_enc_hash(char *desc, SAMR_ENC_HASH * hsh,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER * q_u,
const char *dest_host, const char *user_name,
const char nt_newpass[516],
const char lm_newpass[516],
const uchar lm_oldhash[16]);
BOOL samr_io_q_chgpasswd_user(char *desc, SAMR_Q_CHGPASSWD_USER * q_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
BOOL make_samr_r_chgpasswd_user(SAMR_R_CHGPASSWD_USER * r_u, uint32 status);
BOOL samr_io_r_chgpasswd_user(char *desc, SAMR_R_CHGPASSWD_USER * r_u,
- prs_struct * ps, int depth);
+ prs_struct *ps, int depth);
/*The following definitions come from rpc_parse/parse_sec.c */
-BOOL make_sec_access(SEC_ACCESS *t, uint32 mask);
-BOOL sec_io_access(char *desc, SEC_ACCESS *t, prs_struct *ps, int depth);
-BOOL make_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag);
-BOOL sec_io_ace(char *desc, SEC_ACE *t, prs_struct *ps, int depth);
-BOOL make_sec_acl(SEC_ACL *t, uint16 revision, int num_aces, SEC_ACE *ace);
-void free_sec_acl(SEC_ACL *t);
-BOOL sec_io_acl(char *desc, SEC_ACL *t, prs_struct *ps, int depth);
-int make_sec_desc(SEC_DESC *t, uint16 revision, uint16 type,
- DOM_SID *owner_sid, DOM_SID *grp_sid,
- SEC_ACL *sacl, SEC_ACL *dacl);
-void free_sec_desc(SEC_DESC *t);
-BOOL sec_io_desc(char *desc, SEC_DESC *t, prs_struct *ps, int depth);
-BOOL make_sec_desc_buf(SEC_DESC_BUF *buf, int len, SEC_DESC *data);
-void free_sec_desc_buf(SEC_DESC_BUF *buf);
-BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF *sec, prs_struct *ps, int depth);
+BOOL make_sec_access(SEC_ACCESS * t, uint32 mask);
+BOOL sec_io_access(char *desc, SEC_ACCESS * t, prs_struct *ps, int depth);
+BOOL make_sec_ace(SEC_ACE * t, const DOM_SID *sid, uint8 type,
+ SEC_ACCESS mask, uint8 flag);
+BOOL sec_io_ace(char *desc, SEC_ACE * t, prs_struct *ps, int depth);
+BOOL make_sec_acl(SEC_ACL * t, uint16 revision, int num_aces, SEC_ACE * ace);
+void free_sec_acl(SEC_ACL * t);
+BOOL sec_io_acl(char *desc, SEC_ACL * t, prs_struct *ps, int depth);
+int make_sec_desc(SEC_DESC * t, uint16 revision, uint16 type,
+ DOM_SID *owner_sid, DOM_SID *grp_sid,
+ SEC_ACL * sacl, SEC_ACL * dacl);
+void free_sec_desc(SEC_DESC * t);
+BOOL sec_io_desc(char *desc, SEC_DESC * t, prs_struct *ps, int depth);
+BOOL make_sec_desc_buf(SEC_DESC_BUF * buf, int len, SEC_DESC * data);
+void free_sec_desc_buf(SEC_DESC_BUF * buf);
+BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF * sec, prs_struct *ps,
+ int depth);
/*The following definitions come from rpc_parse/parse_spoolss.c */
/*The following definitions come from rpc_parse/parse_svc.c */
-BOOL make_svc_q_open_sc_man(SVC_Q_OPEN_SC_MAN *q_u,
- const char *server, const char *database,
- uint32 des_access);
-BOOL svc_io_q_open_sc_man(char *desc, SVC_Q_OPEN_SC_MAN *q_u, prs_struct *ps, int depth);
-BOOL svc_io_r_open_sc_man(char *desc, SVC_R_OPEN_SC_MAN *r_u, prs_struct *ps, int depth);
-BOOL make_svc_q_open_service(SVC_Q_OPEN_SERVICE *q_u,
- POLICY_HND *hnd,
- const char *server,
- uint32 des_access);
-BOOL svc_io_q_open_service(char *desc, SVC_Q_OPEN_SERVICE *q_u, prs_struct *ps, int depth);
-BOOL svc_io_r_open_service(char *desc, SVC_R_OPEN_SERVICE *r_u, prs_struct *ps, int depth);
-BOOL make_svc_q_stop_service(SVC_Q_STOP_SERVICE *q_c, POLICY_HND *hnd,
- uint32 unk);
-BOOL svc_io_q_stop_service(char *desc, SVC_Q_STOP_SERVICE *q_s, prs_struct *ps, int depth);
-BOOL svc_io_r_stop_service(char *desc, SVC_R_STOP_SERVICE *r_s, prs_struct *ps, int depth);
-BOOL make_svc_q_start_service(SVC_Q_START_SERVICE *q_c, POLICY_HND *hnd,
- uint32 argc,
- char **argv);
-BOOL svc_io_q_start_service(char *desc, SVC_Q_START_SERVICE *q_s, prs_struct *ps, int depth);
-BOOL svc_io_r_start_service(char *desc, SVC_R_START_SERVICE *r_s, prs_struct *ps, int depth);
-BOOL make_svc_query_svc_cfg(QUERY_SERVICE_CONFIG *q_u,
- uint32 service_type, uint32 start_type,
- uint32 error_control,
- char* bin_path_name, char* load_order_grp,
- uint32 tag_id,
- char* dependencies, char* service_start_name,
- char* disp_name);
-BOOL svc_io_query_svc_cfg(char *desc, QUERY_SERVICE_CONFIG *q_u, prs_struct *ps, int depth);
-BOOL make_svc_q_enum_svcs_status(SVC_Q_ENUM_SVCS_STATUS *q_c, POLICY_HND *hnd,
- uint32 service_type, uint32 service_state,
- uint32 buf_size, uint32 resume_hnd );
-BOOL svc_io_q_enum_svcs_status(char *desc, SVC_Q_ENUM_SVCS_STATUS *q_u, prs_struct *ps, int depth);
-BOOL make_svc_r_enum_svcs_status(SVC_R_ENUM_SVCS_STATUS *r_c,
- ENUM_SRVC_STATUS *svcs, uint32 more_buf_size,
- uint32 num_svcs, ENUM_HND *resume_hnd,
- uint32 dos_status);
-BOOL svc_io_r_enum_svcs_status(char *desc, SVC_R_ENUM_SVCS_STATUS *svc, prs_struct *ps, int depth);
-BOOL svc_io_svc_status(char *desc, SVC_STATUS *svc, prs_struct *ps, int depth);
-BOOL make_svc_q_query_svc_config(SVC_Q_QUERY_SVC_CONFIG *q_c, POLICY_HND *hnd,
- uint32 buf_size);
-BOOL svc_io_q_query_svc_config(char *desc, SVC_Q_QUERY_SVC_CONFIG *q_u, prs_struct *ps, int depth);
-BOOL make_svc_r_query_svc_config(SVC_R_QUERY_SVC_CONFIG *r_c,
- QUERY_SERVICE_CONFIG *cfg,
- uint32 buf_size);
-BOOL svc_io_r_query_svc_config(char *desc, SVC_R_QUERY_SVC_CONFIG *r_u, prs_struct *ps, int depth);
-BOOL svc_io_q_query_disp_name(char *desc, SVC_Q_QUERY_DISP_NAME *q_u, prs_struct *ps, int depth);
-BOOL svc_io_r_query_disp_name(char *desc, SVC_R_QUERY_DISP_NAME *r_u, prs_struct *ps, int depth);
-BOOL make_svc_q_close(SVC_Q_CLOSE *q_c, POLICY_HND *hnd);
-BOOL svc_io_q_close(char *desc, SVC_Q_CLOSE *q_u, prs_struct *ps, int depth);
-BOOL svc_io_r_close(char *desc, SVC_R_CLOSE *r_u, prs_struct *ps, int depth);
-BOOL make_svc_q_change_svc_config(SVC_Q_CHANGE_SVC_CONFIG *q_u, POLICY_HND *hnd,
- uint32 service_type, uint32 start_type,
- uint32 unknown_0,
- uint32 error_control,
- char* bin_path_name, char* load_order_grp,
- uint32 tag_id,
- char* dependencies, char* service_start_name,
- char* password,
- char* disp_name);
-BOOL svc_io_q_change_svc_config(char *desc, SVC_Q_CHANGE_SVC_CONFIG *q_u, prs_struct *ps, int depth);
-BOOL make_svc_r_change_svc_config(SVC_R_CHANGE_SVC_CONFIG *r_c,
- uint32 unknown_0, uint32 status);
-BOOL svc_io_r_change_svc_config(char *desc, SVC_R_CHANGE_SVC_CONFIG *r_u, prs_struct *ps, int depth);
-BOOL svc_io_q_unknown_3(char *desc, SVC_Q_UNKNOWN_3 *q_u,
+BOOL make_svc_q_open_sc_man(SVC_Q_OPEN_SC_MAN * q_u,
+ const char *server, const char *database,
+ uint32 des_access);
+BOOL svc_io_q_open_sc_man(char *desc, SVC_Q_OPEN_SC_MAN * q_u, prs_struct *ps,
+ int depth);
+BOOL svc_io_r_open_sc_man(char *desc, SVC_R_OPEN_SC_MAN * r_u, prs_struct *ps,
+ int depth);
+BOOL make_svc_q_open_service(SVC_Q_OPEN_SERVICE * q_u,
+ POLICY_HND *hnd,
+ const char *server, uint32 des_access);
+BOOL svc_io_q_open_service(char *desc, SVC_Q_OPEN_SERVICE * q_u,
+ prs_struct *ps, int depth);
+BOOL svc_io_r_open_service(char *desc, SVC_R_OPEN_SERVICE * r_u,
+ prs_struct *ps, int depth);
+BOOL make_svc_q_stop_service(SVC_Q_STOP_SERVICE * q_c, POLICY_HND *hnd,
+ uint32 unk);
+BOOL svc_io_q_stop_service(char *desc, SVC_Q_STOP_SERVICE * q_s,
+ prs_struct *ps, int depth);
+BOOL svc_io_r_stop_service(char *desc, SVC_R_STOP_SERVICE * r_s,
+ prs_struct *ps, int depth);
+BOOL make_svc_q_start_service(SVC_Q_START_SERVICE * q_c, POLICY_HND *hnd,
+ uint32 argc, char **argv);
+BOOL svc_io_q_start_service(char *desc, SVC_Q_START_SERVICE * q_s,
+ prs_struct *ps, int depth);
+BOOL svc_io_r_start_service(char *desc, SVC_R_START_SERVICE * r_s,
+ prs_struct *ps, int depth);
+BOOL make_svc_query_svc_cfg(QUERY_SERVICE_CONFIG * q_u,
+ uint32 service_type, uint32 start_type,
+ uint32 error_control,
+ char *bin_path_name, char *load_order_grp,
+ uint32 tag_id,
+ char *dependencies, char *service_start_name,
+ char *disp_name);
+BOOL svc_io_query_svc_cfg(char *desc, QUERY_SERVICE_CONFIG * q_u,
+ prs_struct *ps, int depth);
+BOOL make_svc_q_enum_svcs_status(SVC_Q_ENUM_SVCS_STATUS * q_c,
+ POLICY_HND *hnd, uint32 service_type,
+ uint32 service_state, uint32 buf_size,
+ uint32 resume_hnd);
+BOOL svc_io_q_enum_svcs_status(char *desc, SVC_Q_ENUM_SVCS_STATUS * q_u,
+ prs_struct *ps, int depth);
+BOOL make_svc_r_enum_svcs_status(SVC_R_ENUM_SVCS_STATUS * r_c,
+ ENUM_SRVC_STATUS * svcs,
+ uint32 more_buf_size, uint32 num_svcs,
+ ENUM_HND * resume_hnd, uint32 dos_status);
+BOOL svc_io_r_enum_svcs_status(char *desc, SVC_R_ENUM_SVCS_STATUS * svc,
+ prs_struct *ps, int depth);
+BOOL svc_io_svc_status(char *desc, SVC_STATUS * svc, prs_struct *ps,
+ int depth);
+BOOL make_svc_q_query_svc_config(SVC_Q_QUERY_SVC_CONFIG * q_c,
+ POLICY_HND *hnd, uint32 buf_size);
+BOOL svc_io_q_query_svc_config(char *desc, SVC_Q_QUERY_SVC_CONFIG * q_u,
+ prs_struct *ps, int depth);
+BOOL make_svc_r_query_svc_config(SVC_R_QUERY_SVC_CONFIG * r_c,
+ QUERY_SERVICE_CONFIG * cfg, uint32 buf_size);
+BOOL svc_io_r_query_svc_config(char *desc, SVC_R_QUERY_SVC_CONFIG * r_u,
+ prs_struct *ps, int depth);
+BOOL svc_io_q_query_disp_name(char *desc, SVC_Q_QUERY_DISP_NAME * q_u,
+ prs_struct *ps, int depth);
+BOOL svc_io_r_query_disp_name(char *desc, SVC_R_QUERY_DISP_NAME * r_u,
+ prs_struct *ps, int depth);
+BOOL make_svc_q_close(SVC_Q_CLOSE * q_c, POLICY_HND *hnd);
+BOOL svc_io_q_close(char *desc, SVC_Q_CLOSE * q_u, prs_struct *ps, int depth);
+BOOL svc_io_r_close(char *desc, SVC_R_CLOSE * r_u, prs_struct *ps, int depth);
+BOOL make_svc_q_change_svc_config(SVC_Q_CHANGE_SVC_CONFIG * q_u,
+ POLICY_HND *hnd, uint32 service_type,
+ uint32 start_type, uint32 unknown_0,
+ uint32 error_control, char *bin_path_name,
+ char *load_order_grp, uint32 tag_id,
+ char *dependencies,
+ char *service_start_name, char *password,
+ char *disp_name);
+BOOL svc_io_q_change_svc_config(char *desc, SVC_Q_CHANGE_SVC_CONFIG * q_u,
+ prs_struct *ps, int depth);
+BOOL make_svc_r_change_svc_config(SVC_R_CHANGE_SVC_CONFIG * r_c,
+ uint32 unknown_0, uint32 status);
+BOOL svc_io_r_change_svc_config(char *desc, SVC_R_CHANGE_SVC_CONFIG * r_u,
+ prs_struct *ps, int depth);
+BOOL svc_io_q_unknown_3(char *desc, SVC_Q_UNKNOWN_3 * q_u,
prs_struct *ps, int depth);
-BOOL svc_io_r_unknown_3(char *desc, SVC_R_UNKNOWN_3 *r_u,
+BOOL svc_io_r_unknown_3(char *desc, SVC_R_UNKNOWN_3 * r_u,
prs_struct *ps, int depth);
/*The following definitions come from rpc_parse/parse_wks.c */
#define fstrcpy(d,s) safe_strcpy((d),(s),sizeof(fstring)-1)
#define fstrcat(d,s) safe_strcat((d),(s),sizeof(fstring)-1)
+#define wpstrcpy(d,s) safe_strcpy_w((d),(s),sizeof(wpstring))
+#define wpstrcat(d,s) safe_strcat_w((d),(s),sizeof(wpstring))
+#define wfstrcpy(d,s) safe_strcpy_w((d),(s),sizeof(wfstring))
+#define wfstrcat(d,s) safe_strcat_w((d),(s),sizeof(wfstring))
+
#endif
uint32 low;
uint32 high;
-}
-NTTIME;
+} NTTIME;
/* Allowable account control bits */
#define ACB_DISABLED 0x0001 /* 1 = User account disabled */
*/
uint32 sub_auths[MAXSUBAUTHS]; /* pointer to sub-authorities. */
-}
-DOM_SID;
+} DOM_SID;
typedef struct group_name_info
uint32 type;
uint32 unix_id;
-} DOM_NAME_MAP;
+}
+DOM_NAME_MAP;
/* map either local aliases, domain groups or builtin aliases */
typedef enum
uint8 sid_use; /* usr=1 grp=2 dom=3 alias=4 wkng=5 del=6 inv=7 unk=8 */
fstring name; /* matches with sid: must be of the form "DOMAIN\account" */
-} LOCAL_GRP_MEMBER;
+}
+LOCAL_GRP_MEMBER;
/* enumerate these to get list of local groups */
fstring comment;
uint32 rid; /* alias rid */
-} LOCAL_GRP;
+}
+LOCAL_GRP;
/*** query a domain group, get a list of these: shows who is in that group ***/
uint32 rid; /* rid of domain group member */
uint8 sid_use; /* usr=1 grp=2 dom=3 alias=4 wkng=5 del=6 inv=7 unk=8 */
-} DOMAIN_GRP_MEMBER;
+}
+DOMAIN_GRP_MEMBER;
/*** enumerate these to get list of domain groups ***/
uint32 rid; /* group rid */
uint8 attr; /* attributes forced to be set to 0x7: SE_GROUP_xxx */
-} DOMAIN_GRP;
+}
+DOMAIN_GRP;
/* DOM_CHAL - challenge info */
typedef struct chal_info
typedef struct time_info
{
uint32 time;
-}
-UTIME;
+} UTIME;
/* DOM_CREDs - timestamped client or server credentials */
typedef struct cred_info
int32 wr_error; /* Cached errors */
BOOL wr_mode; /* write through mode) */
BOOL wr_discard; /* discard all further data */
-} write_bmpx_struct;
+}
+write_bmpx_struct;
+
+typedef struct write_cache
+{
+ SMB_OFF_T file_size;
+ SMB_OFF_T offset;
+ size_t alloc_size;
+ size_t data_size;
+ char *data;
+}
+write_cache;
/*
* Structure used to indirect fd's from the files_struct.
int fd_writeonly;
int real_open_flags;
BOOL delete_on_close;
-} file_fd_struct;
+}
+file_fd_struct;
typedef struct files_struct
{
SMB_OFF_T size;
mode_t mode;
uint16 vuid;
- char *mmap_ptr;
- SMB_OFF_T mmap_size;
write_bmpx_struct *wbmpx_ptr;
+ write_cache *wcp;
struct timeval open_time;
int share_mode;
time_t pending_modtime;
+ int oplock_type;
+ int sent_oplock_break;
BOOL open;
BOOL can_lock;
BOOL can_read;
BOOL can_write;
BOOL print_file;
BOOL modified;
- BOOL granted_oplock;
- BOOL sent_oplock_break;
BOOL is_directory;
+ BOOL directory_delete_on_close;
+ BOOL stat_open;
char *fsp_name;
-} files_struct;
+}
+files_struct;
/*
* Structure used to keep directory state information around.
{
char *name;
BOOL is_wild;
-} name_compare_entry;
+}
+name_compare_entry;
/* Include VFS stuff */
BOOL read_only;
BOOL admin_user;
#ifdef USE_RENEWABLE_AFS_TICKET
- pid_t afs_ticket_pid;
-#endif /* USE_RENEWABLE_AFS_TICKET */
+ pid_t afs_ticket_pid;
+#endif /* USE_RENEWABLE_AFS_TICKET */
char *dirpath;
char *connectpath;
name_compare_entry *veto_list; /* Per-share list of files to veto (never show). */
name_compare_entry *veto_oplock_list; /* Per-share list of files to refuse oplocks on. */
-} connection_struct;
+}
+connection_struct;
/* Domain controller authentication protocol info */
struct dcinfo
time_t time;
char user[30];
char file[100];
-} print_queue_struct;
+}
+print_queue_struct;
enum
{ LPSTAT_OK, LPSTAT_STOPPED, LPSTAT_ERROR };
{
fstring message;
int status;
-} print_status_struct;
+}
+print_status_struct;
/* used for server information: client, nameserv and ipc */
struct server_info_struct
share_mode_entry;
+#define SHAREMODE_FN_CAST() \
+ void (*)(share_mode_entry *, char*)
+
+#define SHAREMODE_FN(fn) \
+ void (*fn)(share_mode_entry *, char*)
+
/* each implementation of the share mode code needs
to support the following operations */
struct share_ops
BOOL (*getuseraliasntnam) (const char *, LOCAL_GRP **, int *);
};
+/*
+ * Flags for local user manipulation.
+ */
+
+#define LOCAL_ADD_USER 0x1
+#define LOCAL_DELETE_USER 0x2
+#define LOCAL_DISABLE_USER 0x4
+#define LOCAL_ENABLE_USER 0x8
+#define LOCAL_TRUST_ACCOUNT 0x10
+#define LOCAL_SET_NO_PASSWORD 0x20
+
/* this is used for smbstatus */
struct connect_record
}
parm_class;
+/* passed to br lock code */
+enum brl_type
+{ READ_LOCK, WRITE_LOCK };
+
struct enum_list
{
int value;
char *name;
};
+#define BRLOCK_FN_CAST() \
+ void (*)(SMB_DEV_T dev, SMB_INO_T ino, int pid, \
+ enum brl_type lock_type, \
+ br_off start, br_off size)
+#define BRLOCK_FN(fn) \
+ void (*fn)(SMB_DEV_T dev, SMB_INO_T ino, int pid, \
+ enum brl_type lock_type, \
+ br_off start, br_off size)
+
struct parm_struct
{
char *label;
int ivalue;
char *svalue;
char cvalue;
- } def;
+ }
+ def;
};
struct bitmap
int n;
};
-#define FLAG_BASIC 1 /* fundamental options */
-#define FLAG_HIDE 2 /* options that should be hidden in SWAT */
-#define FLAG_PRINT 4 /* printing options */
-#define FLAG_GLOBAL 8 /* local options that should be globally settable in SWAT */
+#define FLAG_BASIC 0x01 /* fundamental options */
+#define FLAG_SHARE 0x02 /* file sharing options */
+#define FLAG_PRINT 0x04 /* printing options */
+#define FLAG_GLOBAL 0x08 /* local options that should be globally settable in SWAT */
#define FLAG_DEPRECATED 0x10 /* options that should no longer be used */
+#define FLAG_HIDE 0x20 /* options that should be hidden in SWAT */
+#define FLAG_DOS_STRING 0x40 /* convert from UNIX to DOS codepage when reading this string. */
#ifndef LOCKING_VERSION
#define LOCKING_VERSION 4
#endif /* LOCKING_VERSION */
-
/* the basic packet size, assuming no words or bytes */
#define smb_size 39
#define NT_TRANSACT_QUERY_SECURITY_DESC 6
#define NT_TRANSACT_GET_DFS_REFERRAL 0x10
+/* Relevant IOCTL codes */
+#define IOCTL_QUERY_JOB_INFO 0x530060
+
/* these are the trans2 sub fields for primary requests */
#define smb_tpscnt smb_vwv0
#define smb_tdscnt smb_vwv1
/* this is used on a TConX. I'm not sure the name is very helpful though */
#define SMB_SUPPORT_SEARCH_BITS 0x0001
+#define SMB_SHARE_IN_DFS 0x0002
+
+/* Named pipe write mode flags. Used in writeX calls. */
+#define PIPE_RAW_MODE 0x4
+#define PIPE_START_MESSAGE 0x8
/* these are the constants used in the above call. */
/* DesiredAccess */
#define FILE_READ_ATTRIBUTES 0x080
#define FILE_WRITE_ATTRIBUTES 0x100
+#define FILE_ALL_ATTRIBUTES 0x1FF
+
/* Generic access masks & rights. */
#define SPECIFIC_RIGHTS_MASK 0x00FFFFL
#define STANDARD_RIGHTS_MASK 0xFF0000L
#define WRITE_DAC_ACCESS (1L<<18)
#define WRITE_OWNER_ACCESS (1L<<19)
#define SYNCHRONIZE_ACCESS (1L<<20)
+
#define SYSTEM_SECURITY_ACCESS (1L<<24)
+#define GENERIC_ALL_ACCESS (1<<28)
+#define GENERIC_EXECUTE_ACCESS (1<<29)
+#define GENERIC_WRITE_ACCESS (1<<30)
+#define GENERIC_READ_ACCESS (((unsigned)1)<<31)
+
+#define FILE_ALL_STANDARD_ACCESS 0x1F0000
+
+/* Mapping of access rights to UNIX perms. */
+#if 0 /* Don't use all here... JRA. */
+#define UNIX_ACCESS_RWX (FILE_ALL_ATTRIBUTES|FILE_ALL_STANDARD_ACCESS)
+#else
+#define UNIX_ACCESS_RWX (UNIX_ACCESS_R|UNIX_ACCESS_W|UNIX_ACCESS_X)
+#endif
+
+#define UNIX_ACCESS_R (READ_CONTROL_ACCESS|SYNCHRONIZE_ACCESS|\
+ FILE_READ_ATTRIBUTES|FILE_READ_EA|FILE_READ_DATA)
+#define UNIX_ACCESS_W (READ_CONTROL_ACCESS|SYNCHRONIZE_ACCESS|\
+ FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA|\
+ FILE_APPEND_DATA|FILE_WRITE_DATA)
+#define UNIX_ACCESS_X (READ_CONTROL_ACCESS|SYNCHRONIZE_ACCESS|\
+ FILE_EXECUTE|FILE_READ_ATTRIBUTES)
+
+#define UNIX_ACCESS_NONE (WRITE_OWNER_ACCESS)
/* Flags field. */
#define REQUEST_OPLOCK 2
#define RENAME_REPLACE_IF_EXISTS 1
/* Filesystem Attributes. */
-#define FILE_CASE_SENSITIVE_SEARCH 0x1
-#define FILE_CASE_PRESERVED_NAMES 0x2
-#define FILE_UNICODE_ON_DISK 0x4
-#define FILE_PERISITANT_ACLS 0x8
+#define FILE_CASE_SENSITIVE_SEARCH 0x01
+#define FILE_CASE_PRESERVED_NAMES 0x02
+#define FILE_UNICODE_ON_DISK 0x04
+/* According to cifs9f, this is 4, not 8 */
+/* Acconding to testing, this actually sets the security attribute! */
+#define FILE_PERSISTENT_ACLS 0x08
+/* These entries added from cifs9f --tsb */
+#define FILE_FILE_COMPRESSION 0x08
+#define FILE_VOLUME_QUOTAS 0x10
+#define FILE_DEVICE_IS_MOUNTED 0x20
+#define FILE_VOLUME_IS_COMPRESSED 0x8000
/* ChangeNotify flags. */
#define FILE_NOTIFY_CHANGE_FILE_NAME 0x001
#define FLAGS2_32_BIT_ERROR_CODES 0x4000
#define FLAGS2_UNICODE_STRINGS 0x8000
+#define FLAGS2_WIN2K_SIGNATURE 0xC852 /* Hack alert ! For now... JRA. */
+
/* Capabilities. see ftp.microsoft.com/developr/drg/cifs/cifs/cifs4.txt */
#define CAP_RAW_MODE 0x00000001
/* printing types */
enum printing_types
{ PRINT_BSD, PRINT_SYSV, PRINT_AIX, PRINT_HPUX,
- PRINT_QNX, PRINT_PLP, PRINT_LPRNG, PRINT_SOFTQ
+ PRINT_QNX, PRINT_PLP, PRINT_LPRNG, PRINT_SOFTQ, PRINT_CUPS
};
/* Remote architectures we know about. */
enum remote_arch_types
-{ RA_UNKNOWN, RA_WFWG, RA_OS2, RA_WIN95, RA_WINNT, RA_SAMBA };
+{ RA_UNKNOWN, RA_WFWG, RA_OS2, RA_WIN95, RA_WINNT, RA_WIN2K, RA_SAMBA };
/* case handling */
enum case_handling
#define DEFAULT_CLIENT_CODE_PAGE MSDOS_LATIN_1_CODEPAGE
#endif /* KANJI */
+/* Global val set if multibyte codepage. */
+extern int global_is_multibyte_codepage;
+
+#define get_character_len(x) (global_is_multibyte_codepage ? skip_multibyte_char((x)) : 0)
+
/*
* Size of buffer to use when moving files across filesystems.
*/
extern int unix_ERR_class;
extern int unix_ERR_code;
+/*
+ * Used in chaining code.
+ */
+
+extern int chain_size;
+
/*
* Map the Core and Extended Oplock requesst bits down
* to common bits (EXCLUSIVE_OPLOCK & BATCH_OPLOCK).
#define CORE_OPLOCK_GRANTED (1<<5)
#define EXTENDED_OPLOCK_GRANTED (1<<15)
+/*
+ * Return values for oplock types.
+ */
+
+#define NO_OPLOCK_RETURN 0
+#define EXCLUSIVE_OPLOCK_RETURN 1
+#define BATCH_OPLOCK_RETURN 2
+#define LEVEL_II_OPLOCK_RETURN 3
+
/*
* Loopback command offsets.
*/
/*
* Oplock break command code to send over the udp socket.
+ * The same message is sent for both exlusive and level II breaks.
*
- * Form of this is :
+ * The form of this is :
*
* 0 2 6 10 14 14+devsize 14+devsize+inodesize
* +----+--------+--------+--------+-------+--------+
#define OPLOCK_BREAK_CMD 0x1
#define OPLOCK_BREAK_PID_OFFSET 2
-#define OPLOCK_BREAK_SEC_OFFSET 6
-#define OPLOCK_BREAK_USEC_OFFSET 10
-#define OPLOCK_BREAK_DEV_OFFSET 14
+#define OPLOCK_BREAK_SEC_OFFSET (OPLOCK_BREAK_PID_OFFSET + sizeof(pid_t))
+#define OPLOCK_BREAK_USEC_OFFSET (OPLOCK_BREAK_SEC_OFFSET + sizeof(time_t))
+#define OPLOCK_BREAK_DEV_OFFSET (OPLOCK_BREAK_USEC_OFFSET + sizeof(long))
#define OPLOCK_BREAK_INODE_OFFSET (OPLOCK_BREAK_DEV_OFFSET + sizeof(SMB_DEV_T))
#define OPLOCK_BREAK_MSG_LEN (OPLOCK_BREAK_INODE_OFFSET + sizeof(SMB_INO_T))
+#define LEVEL_II_OPLOCK_BREAK_CMD 0x3
+
/*
* Capabilities abstracted for different systems.
*/
uint32 pid;
uint16 vuid;
-}
-vuser_key;
+} vuser_key;
struct use_info
{
NET_USER_INFO_3 usr;
-} user_struct;
+}
+user_struct;
struct current_user
{
gid_t *groups;
};
+/*
+ * Reasons for cache flush.
+ */
+
+#define NUM_FLUSH_REASONS 8 /* Keep this in sync with the enum below. */
+enum flush_reason_enum
+{ SEEK_FLUSH, READ_FLUSH, WRITE_FLUSH, READRAW_FLUSH,
+ OPLOCK_RELEASE_FLUSH, CLOSE_FLUSH, SYNC_FLUSH, SIZECHANGE_FLUSH
+};
+
+/* Defines for the sent_oplock_break field above. */
+#define NO_BREAK_SENT 0
+#define EXCLUSIVE_BREAK_SENT 1
+#define LEVEL_II_BREAK_SENT 2
+
/* A netbios name structure. */
struct nmb_name
{
fstring myhostname;
fstring remote_machine;
-} CREDS_SUBST;
+}
+CREDS_SUBST;
#include "rpc_creds.h"
uchar sess_key[16]; /* NETLOGON session key */
-} netsec_creds;
+}
+netsec_creds;
struct policy;
struct bitmap;
/* for readability... */
#define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
-#define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
-#define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
-#define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
-#define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
+#define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
+#define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
+#define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
+#define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
/* memory-allocation-helpers (idea and names from glib) */
#define g_new(type, count) \
#define SMB_ROUNDUP(x,g) (((x)+((g)-1))&~((g)-1))
+/* Extra macros added by Ying Chen at IBM - speed increase by inlining. */
+#define smb_buf(buf) (buf + smb_size + CVAL(buf,smb_wct)*2)
+#define smb_buflen(buf) (SVAL(buf,smb_vwv0 + (int)CVAL(buf, smb_wct)*2))
+
+/* Note that chain_size must be available as an extern int to this macro. */
+#define smb_offset(p,buf) (PTR_DIFF(p,buf+4) + chain_size)
+
+#define smb_len(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|((PVAL(buf,1)&1)<<16))
+#define _smb_setlen(buf,len) buf[0] = 0; buf[1] = (len&0x10000)>>16; \
+ buf[2] = (len&0xFF00)>>8; buf[3] = len&0xFF;
+
+/*********************************************************
+* Routine to check if a given string matches exactly.
+* Case can be significant or not.
+**********************************************************/
+
+#define exact_match(str, regexp, case_sig) \
+ ((case_sig?strcmp(str,regexp):strcasecmp(str,regexp)) == 0)
+
+/*******************************************************************
+find the difference in milliseconds between two struct timeval
+values
+********************************************************************/
+
+#define TvalDiff(tvalold,tvalnew) \
+ (((tvalnew)->tv_sec - (tvalold)->tv_sec)*1000 + \
+ ((int)(tvalnew)->tv_usec - (int)(tvalold)->tv_usec)/1000)
+
+/****************************************************************************
+true if two IP addresses are equal
+****************************************************************************/
+
+#define ip_equal(ip1,ip2) ((ip1).s_addr == (ip2).s_addr)
+
+/****************************************************************************
+ Used by dptr_zero.
+****************************************************************************/
+
+#define DPTR_MASK ((uint32)(((uint32)1)<<31))
+
+/****************************************************************************
+ Return True if the offset is at zero.
+****************************************************************************/
+
+#define dptr_zero(buf) ((IVAL(buf,1)&~DPTR_MASK) == 0)
+
+/*******************************************************************
+copy an IP address from one buffer to another
+********************************************************************/
+
+#define putip(dest,src) memcpy(dest,src,4)
+
+/****************************************************************************
+ Make a filename into unix format.
+****************************************************************************/
+
+#define unix_format(fname) string_replace(fname,'\\','/')
+
+/****************************************************************************
+ Make a file into DOS format.
+****************************************************************************/
+
+#define dos_format(fname) string_replace(fname,'/','\\')
+
+
#endif /* _SMB_MACROS_H */
BOOL read_only;
BOOL admin_user;
+ /* Handle on dlopen() call */
+
+ void *dl_handle;
+
/* Paths */
pstring dirpath;
int (*connect)(struct vfs_connection_struct *conn, char *service,
char *user);
void (*disconnect)(void);
- SMB_BIG_UINT (*disk_free)(char *path, SMB_BIG_UINT *bsize,
+ SMB_BIG_UINT (*disk_free)(char *path, BOOL small_query, SMB_BIG_UINT *bsize,
SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize);
/* Directory operations */
ssize_t (*write)(int fd, char *data, size_t n);
SMB_OFF_T (*lseek)(int filedes, SMB_OFF_T offset, int whence);
int (*rename)(char *old, char *new);
- void (*sync)(int fd);
+ void (*fsync)(int fd);
int (*stat)(char *fname, SMB_STRUCT_STAT *sbuf);
int (*fstat)(int fd, SMB_STRUCT_STAT *sbuf);
int (*lstat)(char *path, SMB_STRUCT_STAT *sbuf);
- BOOL (*lock)(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
int (*unlink)(char *path);
int (*chmod)(char *path, mode_t mode);
int (*utime)(char *path, struct utimbuf *times);
};
-/* VFS options for configuration file */
-
struct vfs_options {
struct vfs_options *prev, *next;
char *name;
}
/* string_match - match string against token */
-static int string_match(char *tok,char *s)
+static int string_match(char *tok,char *s, char *invalid_char)
{
- int tok_len;
- int str_len;
+ size_t tok_len;
+ size_t str_len;
char *cut;
+ *invalid_char = '\0';
+
/* Return True if a token has the magic value "ALL". Return
* FAIL if the token is "FAIL". If the token starts with a "."
* (domain name), return True if it matches the last fields of
} else if ((cut = strchr(tok, '/')) != 0) { /* netnumber/netmask */
if (isdigit((int)s[0]) && masked_match(tok, cut, s))
return (True);
+ } else if (strchr(tok, '*') != 0) {
+ *invalid_char = '*';
+ } else if (strchr(tok, '?') != 0) {
+ *invalid_char = '?';
}
return (False);
}
{
char **client = (char **)item;
int match;
+ char invalid_char = '\0';
/*
* Try to match the address first. If that fails, try to match the host
* name if available.
*/
- if ((match = string_match(tok, client[1])) == 0)
- if (client[0][0] != 0)
- match = string_match(tok, client[0]);
+ if ((match = string_match(tok, client[1], &invalid_char)) == 0) {
+ if(invalid_char)
+ DEBUG(0,("client_match: address match failing due to invalid character '%c' found in \
+token '%s' in an allow/deny hosts line.\n", invalid_char, tok ));
+
+ if (client[0][0] != 0)
+ match = string_match(tok, client[0], &invalid_char);
+
+ if(invalid_char)
+ DEBUG(0,("client_match: address match failing due to invalid character '%c' found in \
+token '%s' in an allow/deny hosts line.\n", invalid_char, tok ));
+ }
+
return (match);
}
client[0] = cname;
client[1] = caddr;
+ /* if it is loopback then always allow unless specifically denied */
+ if (strcmp(caddr, "127.0.0.1") == 0) {
+ if (deny_list &&
+ list_match(deny_list,(char *)client,client_match)) {
+ return False;
+ }
+ return True;
+ }
+
/* if theres no deny list and no allow list then allow access */
if ((!deny_list || *deny_list == 0) &&
(!allow_list || *allow_list == 0)) {
struct bitmap *bm;
bm = (struct bitmap *)malloc(sizeof(*bm));
- bm->n = n;
if (!bm) return NULL;
+ bm->n = n;
bm->b = (uint32 *)malloc(sizeof(bm->b[0])*(n+31)/32);
if (!bm->b) {
free(bm);
#define CTRLZ 26
extern int DEBUGLEVEL;
-static char cvtbuf[1024];
+static char cvtbuf[sizeof(pstring)];
static BOOL mapsinited = 0;
mapsinited = True;
}
-static void update_map(char * str) {
+static void update_map(char *str) {
char *p;
for (p = str; *p; p++) {
}
}
-static void init_iso8859_1(void) {
-
+static void setupmaps(void)
+{
int i;
if (!mapsinited) initmaps();
/* Do not map undefined characters to some accidental code */
- for (i = 128; i < 256; i++)
+ for (i = 128; i < 256; i++)
{
unix2dos[i] = CTRLZ;
dos2unix[i] = CTRLZ;
}
+}
-/* MSDOS Code Page 850 -> ISO-8859 */
-update_map("\240\377\241\255\242\275\243\234\244\317\245\276\246\335\247\365");
-update_map("\250\371\251\270\252\246\253\256\254\252\255\360\256\251\257\356");
-update_map("\260\370\261\361\262\375\263\374\264\357\265\346\266\364\267\372");
-update_map("\270\367\271\373\272\247\273\257\274\254\275\253\276\363\277\250");
-update_map("\300\267\301\265\302\266\303\307\304\216\305\217\306\222\307\200");
-update_map("\310\324\311\220\312\322\313\323\314\336\315\326\316\327\317\330");
-update_map("\320\321\321\245\322\343\323\340\324\342\325\345\326\231\327\236");
-update_map("\330\235\331\353\332\351\333\352\334\232\335\355\336\350\337\341");
-update_map("\340\205\341\240\342\203\343\306\344\204\345\206\346\221\347\207");
-update_map("\350\212\351\202\352\210\353\211\354\215\355\241\356\214\357\213");
-update_map("\360\320\361\244\362\225\363\242\364\223\365\344\366\224\367\366");
-update_map("\370\233\371\227\372\243\373\226\374\201\375\354\376\347\377\230");
+static void init_iso8859_1(int codepage) {
+ setupmaps();
+
+ if (codepage == 437) {
+ /* MSDOS Code Page 437 -> ISO-8859-1 */
+ update_map("\xA1\xAD\xA2\x98\xA3\x9C\xA4\xED\xA5\x9D\xA6\xB3\xA7\xEE");
+ update_map("\xAA\xA6\xAB\xAE\xAC\xAA\xAE\xE9\xAF\xC4");
+ update_map("\xB0\xF8\xB1\xF1\xB2\xFD\xB5\xE6\xB7\xFA\xBA\xA7\xBC\xAC\xBD\xAB\xBF\xA8");
+ update_map("\xC0\x85\xC1\xA0\xC2\x83\xC4\x8E\xC5\x8F\xC6\x92\xC7\x80\xC8\x8A");
+ update_map("\xC9\x90\xCA\x88\xCB\x89\xCC\x8D\xCD\xA1\xCE\x8C\xCF\x8B");
+ update_map("\xD1\xA5\xD2\x96\xD3\xA2\xD4\x93\xD6\x99\xD9\x97\xDA\xA3\xDB\x96\xDC\x9A\xDF\xE1");
+ update_map("\xE0\x85\xE1\xA0\xE2\x83\xE4\x84\xE5\x86\xE6\x91\xE7\x87\xE8\x8A\xE9\x82\xEA\x88\xEB\x89\xEC\x8D\xED\xA1\xEE\x8C\xEF\x8B");
+ update_map("\xF0\xEB\xF1\xA4\xF2\x95\xF3\xA2\xF4\x93\xF6\x94\xF7\xF6\xF8\xED\xF9\x97\xFA\xA3\xFB\x96\xFC\x81\xFF\x98");
+ } else {
+ /* MSDOS Code Page 850 -> ISO-8859-1 */
+ update_map("\240\377\241\255\242\275\243\234\244\317\245\276\246\335\247\365");
+ update_map("\250\371\251\270\252\246\253\256\254\252\255\360\256\251\257\356");
+ update_map("\260\370\261\361\262\375\263\374\264\357\265\346\266\364\267\372");
+ update_map("\270\367\271\373\272\247\273\257\274\254\275\253\276\363\277\250");
+ update_map("\300\267\301\265\302\266\303\307\304\216\305\217\306\222\307\200");
+ update_map("\310\324\311\220\312\322\313\323\314\336\315\326\316\327\317\330");
+ update_map("\320\321\321\245\322\343\323\340\324\342\325\345\326\231\327\236");
+ update_map("\330\235\331\353\332\351\333\352\334\232\335\355\336\350\337\341");
+ update_map("\340\205\341\240\342\203\343\306\344\204\345\206\346\221\347\207");
+ update_map("\350\212\351\202\352\210\353\211\354\215\355\241\356\214\357\213");
+ update_map("\360\320\361\244\362\225\363\242\364\223\365\344\366\224\367\366");
+ update_map("\370\233\371\227\372\243\373\226\374\201\375\354\376\347\377\230");
+ }
}
/* Init for eastern european languages. */
static void init_iso8859_2(void) {
- int i;
- if (!mapsinited) initmaps();
-
- /* Do not map undefined characters to some accidental code */
- for (i = 128; i < 256; i++)
- {
- unix2dos[i] = CTRLZ;
- dos2unix[i] = CTRLZ;
- }
+ setupmaps();
/*
* Tranlation table created by Petr Hubeny <psh@capitol.cz>
*/
/* MSDOS Code Page 852 -> ISO-8859-2 */
+update_map("\240\377"); /* Fix for non-breaking space */
update_map("\241\244\242\364\243\235\244\317\245\225\246\227\247\365");
update_map("\250\371\251\346\252\270\253\233\254\215\256\246\257\275");
update_map("\261\245\262\362\263\210\264\357\265\226\266\230\267\363");
static void init_iso8859_5(void)
{
- int i;
- if (!mapsinited) initmaps();
-
- /* Do not map undefined characters to some accidental code */
- for (i = 128; i < 256; i++)
- {
- unix2dos[i] = CTRLZ;
- dos2unix[i] = CTRLZ;
- }
+ setupmaps();
/* MSDOS Code Page 866 -> ISO8859-5 */
-update_map("\200\260\201\261\202\262\203\263\204\264\205\265\206\266\207\267");
-update_map("\210\270\211\271\212\272\213\273\214\274\215\275\216\276\217\277");
-update_map("\220\300\221\301\222\302\223\303\224\304\225\305\226\306\227\307");
-update_map("\230\310\231\311\232\312\233\313\234\314\235\315\236\316\237\317");
-update_map("\240\320\241\321\242\322\243\323\244\324\245\325\246\326\247\327");
-update_map("\250\330\251\331\252\332\253\333\254\334\255\335\256\336\257\337");
+update_map("\260\200\261\201\262\202\263\203\264\204\265\205\266\206\267\207");
+update_map("\270\210\271\211\272\212\273\213\274\214\275\215\276\216\277\217");
+update_map("\300\220\301\221\302\222\303\223\304\224\305\225\306\226\307\227");
+update_map("\310\230\311\231\312\232\313\233\314\234\315\235\316\236\317\237");
+update_map("\320\240\321\241\322\242\323\243\324\244\325\245\326\246\327\247");
+update_map("\330\250\331\251\332\252\333\253\334\254\335\255\336\256\337\257");
update_map("\340\340\341\341\342\342\343\343\344\344\345\345\346\346\347\347");
update_map("\350\350\351\351\352\352\353\353\354\354\355\355\356\356\357\357");
-update_map("\360\241\361\361\362\244\363\364\364\247\365\367\366\256\367\376");
-update_map("\374\360\377\240");
+update_map("\241\360\361\361\244\362\364\363\247\364\367\365\256\366\376\367");
+update_map("\360\374\240\377");
+}
+
+/* Added by Antonios Kavarnos (Antonios.Kavarnos@softlab.ece.ntua.gr */
+
+static void init_iso8859_7(void)
+{
+ setupmaps();
+
+/* MSDOS Code Page 737 -> ISO-8859-7 (Greek-Hellenic) */
+
+update_map("\301\200\302\201\303\202\304\203\305\204\306\205\307\206");
+update_map("\310\207\311\210\312\211\313\212\314\213\315\214\316\215\317\216");
+update_map("\320\217\321\220\323\221\324\222\325\223\326\224\327\225");
+update_map("\330\226\331\227");
+update_map("\341\230\342\231\343\232\344\233\345\234\346\235\347\236");
+update_map("\350\237\351\240\352\241\353\242\354\243\355\244\356\245\357\246");
+update_map("\360\247\361\250\362\252\363\251\364\253\365\254\366\255\367\256");
+update_map("\370\257\371\340");
+update_map("\332\364\333\365\334\341\335\342\336\343\337\345");
+update_map("\372\344\373\350\374\346\375\347\376\351");
+update_map("\266\352");
+update_map("\270\353\271\354\272\355\274\356\276\357\277\360");
}
/* Init for russian language (koi8) */
static void init_koi8_r(void)
{
- if (!mapsinited) initmaps();
-
- /* There aren't undefined characters between 128 and 255 */
+ setupmaps();
/* MSDOS Code Page 866 -> KOI8-R */
update_map("\200\304\201\263\202\332\203\277\204\300\205\331\206\303\207\264");
update_map("\370\234\371\233\372\207\373\230\374\235\375\231\376\227\377\232");
}
+
+/* Init for ROMAN-8 (HP-UX) */
+
+static void init_roman8(void) {
+
+ setupmaps();
+
+/* MSDOS Code Page 850 -> ROMAN8 */
+update_map("\240\377\241\267\242\266\243\324\244\322\245\323\246\327\247\330");
+update_map("\250\357\253\371\255\353\256\352\257\234");
+update_map("\260\356\261\355\262\354\263\370\264\200\265\207\266\245\267\244");
+update_map("\270\255\271\250\272\317\273\234\274\276\275\365\276\237\277\275");
+update_map("\300\203\301\210\302\223\303\226\304\240\305\202\306\242\307\243");
+update_map("\310\205\311\212\312\225\313\227\314\204\315\211\316\224\317\201");
+update_map("\320\217\321\214\322\235\323\222\324\206\325\241\326\233\327\221");
+update_map("\330\216\331\215\332\231\333\232\334\220\335\213\336\341\337\342");
+update_map("\340\265\341\307\342\306\343\321\344\320\345\326\346\336\347\340");
+update_map("\350\343\351\345\352\344\355\351\357\230");
+update_map("\360\350\361\347\362\372\363\346\364\364\365\363\366\360\367\254");
+update_map("\370\253\371\246\372\247\373\256\374\376\375\257\376\361");
+}
+
/*
* Convert unix to dos
*/
char *unix2dos_format(char *str,BOOL overwrite)
{
- char *p;
- char *dp;
-
- if (!mapsinited) initmaps();
-
- if (overwrite) {
- for (p = str; *p; p++) *p = unix2dos[(unsigned char)*p];
- return str;
- } else {
- for (p = str, dp = cvtbuf; *p; p++,dp++) *dp = unix2dos[(unsigned char)*p];
- *dp = 0;
- return cvtbuf;
- }
+ char *p;
+ char *dp;
+
+ if (!mapsinited)
+ initmaps();
+
+ if (overwrite) {
+ for (p = str; *p; p++)
+ *p = unix2dos[(unsigned char)*p];
+ return str;
+ } else {
+ for (p = str, dp = cvtbuf;*p && (dp - cvtbuf < sizeof(cvtbuf) - 1); p++,dp++)
+ *dp = unix2dos[(unsigned char)*p];
+ *dp = 0;
+ return cvtbuf;
+ }
}
/*
*/
char *dos2unix_format(char *str, BOOL overwrite)
{
- char *p;
- char *dp;
-
- if (!mapsinited) initmaps();
-
- if (overwrite) {
- for (p = str; *p; p++) *p = dos2unix[(unsigned char)*p];
- return str;
- } else {
- for (p = str, dp = cvtbuf; *p; p++,dp++) *dp = dos2unix[(unsigned char)*p];
- *dp = 0;
- return cvtbuf;
- }
+ char *p;
+ char *dp;
+
+ if (!mapsinited)
+ initmaps();
+
+ if (overwrite) {
+ for (p = str; *p; p++)
+ *p = dos2unix[(unsigned char)*p];
+ return str;
+ } else {
+ for (p = str, dp = cvtbuf;*p && (dp - cvtbuf < sizeof(cvtbuf) - 1); p++,dp++)
+ *dp = dos2unix[(unsigned char)*p];
+ *dp = 0;
+ return cvtbuf;
+ }
}
/*
* Interpret character set.
*/
-void interpret_character_set(char *str)
+void interpret_character_set(char *str, int codepage)
{
if (strequal (str, "iso8859-1")) {
- init_iso8859_1();
+ init_iso8859_1(codepage);
} else if (strequal (str, "iso8859-2")) {
init_iso8859_2();
} else if (strequal (str, "iso8859-5")) {
init_iso8859_5();
+ } else if (strequal (str, "iso8859-7")) {
+ init_iso8859_7();
} else if (strequal (str, "koi8-r")) {
init_koi8_r();
+ } else if (strequal (str, "roman8")) {
+ init_roman8();
} else {
DEBUG(0,("unrecognized character set %s\n", str));
}
+
+ load_unix_unicode_map(str);
}
add_dos_char(cp[i][0], (BOOL)cp[i][2], cp[i][1], (BOOL)cp[i][3]);
}
+ /* Try and load the unicode map. */
+ load_dos_unicode_map(client_codepage);
}
/*******************************************************************
}
else
{
+ POSIX_ID id;
+
switch (type)
{
case DOM_MAP_USER:
{
grp->type = SID_NAME_USER;
+ id.type = SURS_POSIX_UID_AS_USR;
break;
}
case DOM_MAP_DOMAIN:
{
grp->type = SID_NAME_DOM_GRP;
+ id.type = SURS_POSIX_GID_AS_GRP;
break;
}
case DOM_MAP_LOCAL:
{
grp->type = SID_NAME_ALIAS;
+ id.type = SURS_POSIX_GID_AS_ALS;
break;
}
}
- ret = surs_unixid_to_sam_sid(grp->unix_id, grp->type, &grp->sid, False);
+ id.id = grp->unix_id;
+ ret = surs_unixid_to_sam_sid(&id, &grp->sid, False);
}
sid_to_string(sid_str, &grp->sid);
static BOOL get_sid_and_type(const char *fullntname, uint32 expected_type,
DOM_NAME_MAP *gmep)
{
+ POSIX_ID id;
+
/*
* check with the PDC to see if it owns the name. if so,
* the SID is resolved with the PDC database.
{
return False;
}
- if (!surs_unixid_to_sam_sid(gmep->unix_id, gmep->type, &gmep->sid, False))
+
+ switch (gmep->type)
+ {
+ case SID_NAME_USER:
+ {
+ id.type = SURS_POSIX_UID_AS_USR;
+ break;
+ }
+ case SID_NAME_DOM_GRP:
+ {
+ id.type = SURS_POSIX_GID_AS_GRP;
+ break;
+ }
+ case SID_NAME_ALIAS:
+ {
+ id.type = SURS_POSIX_GID_AS_ALS;
+ break;
+ }
+ }
+
+ id.id = gmep->unix_id;
+
+ if (!surs_unixid_to_sam_sid(&id, &gmep->sid, False))
{
return False;
}
}
if (lp_server_role() != ROLE_DOMAIN_NONE)
{
+ POSIX_ID id;
static fstring nt_name;
static fstring unix_name;
static fstring nt_domain;
*/
gmep->nt_domain = global_sam_name;
- surs_unixid_to_sam_sid(gmep->unix_id, gmep->type, &gmep->sid, False);
+
+ switch (gmep->type)
+ {
+ case SID_NAME_USER:
+ {
+ id.type = SURS_POSIX_UID_AS_USR;
+ break;
+ }
+ case SID_NAME_DOM_GRP:
+ {
+ id.type = SURS_POSIX_GID_AS_GRP;
+ break;
+ }
+ case SID_NAME_ALIAS:
+ {
+ id.type = SURS_POSIX_GID_AS_ALS;
+ break;
+ }
+ }
+
+ id.id = gmep->unix_id;
+
+ surs_unixid_to_sam_sid(&id, &gmep->sid, False);
return True;
}
}
if (lp_server_role() != ROLE_DOMAIN_NONE)
{
+ POSIX_ID id;
static fstring nt_name;
static fstring unix_name;
static fstring nt_domain;
gmep->type = SID_NAME_USER;
sid_copy(&gmep->sid, sid);
- if (!surs_sam_sid_to_unixid(&gmep->sid, gmep->type, &gmep->unix_id, False))
+
+ if (!surs_sam_sid_to_unixid(&gmep->sid, &id, False))
{
return False;
}
+
+ gmep->unix_id = id.id;
+
+ switch (id.type)
+ {
+ case SURS_POSIX_UID_AS_USR:
+ {
+ gmep->type= SID_NAME_USER;
+ break;
+ }
+ case SURS_POSIX_GID_AS_GRP:
+ {
+ gmep->type= SID_NAME_DOM_GRP;
+ break;
+ }
+ case SURS_POSIX_GID_AS_ALS:
+ {
+ gmep->type= SID_NAME_ALIAS;
+ break;
+ }
+ }
+
fstrcpy(gmep->nt_name, uidtoname((uid_t)gmep->unix_id));
fstrcpy(gmep->unix_name, gmep->nt_name);
gmep->nt_domain = global_sam_name;
}
if (lp_server_role() != ROLE_DOMAIN_NONE)
{
+ POSIX_ID id;
static fstring nt_name;
static fstring unix_name;
static fstring nt_domain;
}
sid_copy(&gmep->sid, sid);
- if (!surs_sam_sid_to_unixid(&gmep->sid, gmep->type, &gmep->unix_id, False))
+ if (!surs_sam_sid_to_unixid(&gmep->sid, &id, False))
{
return False;
}
+
+ gmep->unix_id = id.id;
+
+ switch (id.type)
+ {
+ case SURS_POSIX_UID_AS_USR:
+ {
+ gmep->type= SID_NAME_USER;
+ break;
+ }
+ case SURS_POSIX_GID_AS_GRP:
+ {
+ gmep->type= SID_NAME_DOM_GRP;
+ break;
+ }
+ case SURS_POSIX_GID_AS_ALS:
+ {
+ gmep->type= SID_NAME_ALIAS;
+ break;
+ }
+ }
+
fstrcpy(gmep->nt_name, gidtoname((gid_t)gmep->unix_id));
fstrcpy(gmep->unix_name, gmep->nt_name);
gmep->nt_domain = global_sam_name;
}
#endif
+/*******************************************************************
+ A chown() wrapper that calls dos_to_unix.
+********************************************************************/
+
+int dos_chown(char *fname, uid_t uid, gid_t gid)
+{
+ return(sys_chown(dos_to_unix(fname,False),uid,gid));
+}
+
/*******************************************************************
A stat() wrapper that calls dos_to_unix.
********************************************************************/
}
/*******************************************************************
- Mkdir() that calls dos_to_unix. Don't use this call unless you
- really want to access a file on disk. Use the vfs_ops.mkdir()
- function instead.
+ Mkdir() that calls dos_to_unix.
+ Cope with UNIXes that don't allow high order mode bits on mkdir.
+ Patch from gcarter@lanier.com.
+ Don't use this call unless you really want to access a file on
+ disk. Use the vfs_ops.mkdir() function instead.
********************************************************************/
int dos_mkdir(char *dname,mode_t mode)
{
- return(mkdir(dos_to_unix(dname,False),mode));
+ int ret = mkdir(dos_to_unix(dname,False),mode);
+ if(!ret)
+ return(dos_chmod(dname,mode));
+ else
+ return ret;
}
/*******************************************************************
int dos_rename(char *from, char *to)
{
+ int rcode;
pstring zfrom, zto;
pstrcpy (zfrom, dos_to_unix (from, False));
pstrcpy (zto, dos_to_unix (to, False));
- return file_rename(zfrom, zto);
+ rcode = rename (zfrom, zto);
+
+ if (errno == EXDEV)
+ {
+ /* Rename across filesystems needed. */
+ rcode = copy_reg (zfrom, zto);
+ }
+ return rcode;
}
/*******************************************************************
SMB_OFF_T dos_file_size(char *file_name)
{
- return file_size(dos_to_unix(file_name, False));
+ return get_file_size(dos_to_unix(file_name, False));
}
/*******************************************************************
getwd_cache_init = True;
for (i=0;i<MAX_GETWDCACHE;i++)
{
- string_init(&ino_list[i].dos_path,"");
+ string_set(&ino_list[i].dos_path,"");
ino_list[i].valid = False;
}
}
if (sys_stat(".",&st) == -1)
{
- DEBUG(0,("Very strange, couldn't stat \".\"\n"));
+ DEBUG(0,("Very strange, couldn't stat \".\" path=%s\n", path));
return(dos_getwd(path));
}
DEBUG(0,("INTERNAL ERROR: Signal %d in pid %d (%s)",sig,(int)getpid(),VERSION));
DEBUG(0,("\nPlease read the file BUGS.txt in the distribution\n"));
DEBUG(0,("===============================================================\n"));
-
- sleep(10);
+
smb_panic("internal error");
if (cont_fn) {
#endif
#ifdef SIGBUS
CatchSignal(SIGBUS,SIGNAL_CAST SIG_DFL);
-#endif
-#ifdef SIGILL
- CatchSignal(SIGILL, SIGNAL_CAST SIG_DFL);
#endif
return; /* this should cause a core dump */
}
#ifdef SIGBUS
CatchSignal(SIGBUS,SIGNAL_CAST sig_fault);
#endif
-#ifdef SIGILL
- CatchSignal(SIGILL,SIGNAL_CAST sig_fault);
-#endif
}
{
DIR *dp = opendir(name);
pstring fullname;
- size_t len_left;
- size_t fullname_len;
+ int len_left;
+ int fullname_len;
char *pos;
pstrcpy(fullname, name);
/* add in the root encrypted password. On any system where security is taken
seriously this will be secret */
- pw = getpwnam("root");
+ pw = sys_getpwnam("root");
if (pw && pw->pw_passwd) {
int i;
unsigned char md4_tmp[16];
#endif /* KANJI */
+BOOL global_is_multibyte_codepage = False;
+
/* jis si/so sequence */
static char jis_kso = JIS_KSO;
static char jis_ksi = JIS_KSI;
********************************************************************/
/* convesion buffer */
-static char cvtbuf[1024];
+static char cvtbuf[2*sizeof(pstring)];
/*******************************************************************
EUC <-> SJIS
char *save;
save = (char *) from;
- for (out = cvtbuf; *from;) {
+ for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
if (is_shift_jis (*from)) {
int code = sjis2euc ((int) from[0] & 0xff, (int) from[1] & 0xff);
*out++ = (code >> 8) & 0xff;
char *save;
save = (char *) from;
- for (out = cvtbuf; *from; ) {
+ for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3); ) {
if (is_euc (*from)) {
int code = euc2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
*out++ = (code >> 8) & 0xff;
static char *jis8_to_sj(char *from, BOOL overwrite)
{
- char *out;
- int shifted;
- char *save;
+ char *out;
+ int shifted;
+ char *save;
- shifted = _KJ_ROMAN;
- save = (char *) from;
- for (out = cvtbuf; *from;) {
- if (is_esc (*from)) {
- if (is_so1 (from[1]) && is_so2 (from[2])) {
- shifted = _KJ_KANJI;
- from += 3;
- } else if (is_si1 (from[1]) && is_si2 (from[2])) {
- shifted = _KJ_ROMAN;
- from += 3;
- } else { /* sequence error */
- goto normal;
- }
- } else {
- normal:
- switch (shifted) {
- default:
- case _KJ_ROMAN:
- *out++ = *from++;
- break;
- case _KJ_KANJI:
- {
- int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
- *out++ = (code >> 8) & 0xff;
- *out++ = code;
- from += 2;
- }
- break;
- }
- }
- }
- *out = 0;
- if (overwrite) {
- pstrcpy (save, (char *) cvtbuf);
- return save;
+ shifted = _KJ_ROMAN;
+ save = (char *) from;
+ for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
+ if (is_esc (*from)) {
+ if (is_so1 (from[1]) && is_so2 (from[2])) {
+ shifted = _KJ_KANJI;
+ from += 3;
+ } else if (is_si1 (from[1]) && is_si2 (from[2])) {
+ shifted = _KJ_ROMAN;
+ from += 3;
+ } else { /* sequence error */
+ goto normal;
+ }
} else {
- return cvtbuf;
+
+normal:
+
+ switch (shifted) {
+ default:
+ case _KJ_ROMAN:
+ *out++ = *from++;
+ break;
+ case _KJ_KANJI:
+ {
+ int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
+ *out++ = (code >> 8) & 0xff;
+ *out++ = code;
+ from += 2;
+ break;
+ }
+ }
}
+ }
+
+ *out = 0;
+ if (overwrite) {
+ pstrcpy (save, (char *) cvtbuf);
+ return save;
+ } else {
+ return cvtbuf;
+ }
}
/*******************************************************************
static char *sj_to_jis8(char *from, BOOL overwrite)
{
- char *out;
- int shifted;
- char *save;
+ char *out;
+ int shifted;
+ char *save;
- shifted = _KJ_ROMAN;
- save = (char *) from;
- for (out = cvtbuf; *from; ) {
- if (is_shift_jis (*from)) {
- int code;
- switch (shifted) {
- case _KJ_ROMAN: /* to KANJI */
- *out++ = jis_esc;
- *out++ = jis_so1;
- *out++ = jis_kso;
- shifted = _KJ_KANJI;
- break;
- }
- code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
- *out++ = (code >> 8) & 0xff;
- *out++ = code;
- from += 2;
- } else {
- switch (shifted) {
- case _KJ_KANJI: /* to ROMAN/KANA */
- *out++ = jis_esc;
- *out++ = jis_si1;
- *out++ = jis_ksi;
- shifted = _KJ_ROMAN;
- break;
- }
- *out++ = *from++;
- }
- }
- switch (shifted) {
- case _KJ_KANJI: /* to ROMAN/KANA */
- *out++ = jis_esc;
- *out++ = jis_si1;
- *out++ = jis_ksi;
- shifted = _KJ_ROMAN;
- break;
- }
- *out = 0;
- if (overwrite) {
- pstrcpy (save, (char *) cvtbuf);
- return save;
+ shifted = _KJ_ROMAN;
+ save = (char *) from;
+ for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4); ) {
+ if (is_shift_jis (*from)) {
+ int code;
+ switch (shifted) {
+ case _KJ_ROMAN: /* to KANJI */
+ *out++ = jis_esc;
+ *out++ = jis_so1;
+ *out++ = jis_kso;
+ shifted = _KJ_KANJI;
+ break;
+ }
+ code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
+ *out++ = (code >> 8) & 0xff;
+ *out++ = code;
+ from += 2;
} else {
- return cvtbuf;
+ switch (shifted) {
+ case _KJ_KANJI: /* to ROMAN/KANA */
+ *out++ = jis_esc;
+ *out++ = jis_si1;
+ *out++ = jis_ksi;
+ shifted = _KJ_ROMAN;
+ break;
+ }
+ *out++ = *from++;
}
+ }
+
+ switch (shifted) {
+ case _KJ_KANJI: /* to ROMAN/KANA */
+ *out++ = jis_esc;
+ *out++ = jis_si1;
+ *out++ = jis_ksi;
+ shifted = _KJ_ROMAN;
+ break;
+ }
+ *out = 0;
+ if (overwrite) {
+ pstrcpy (save, (char *) cvtbuf);
+ return save;
+ } else {
+ return cvtbuf;
+ }
}
/*******************************************************************
shifted = _KJ_ROMAN;
save = (char *) from;
- for (out = cvtbuf; *from;) {
+ for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
if (is_esc (*from)) {
if (is_so1 (from[1]) && is_so2 (from[2])) {
shifted = _KJ_KANJI;
shifted = _KJ_ROMAN;
save = (char *) from;
- for (out = cvtbuf; *from; ) {
+ for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4); ) {
if (is_shift_jis (*from)) {
int code;
switch (shifted) {
Convert FROM contain 7 bits JIS(junet) codes to SHIFT JIS codes
return converted buffer
********************************************************************/
+
static char *junet_to_sj(char *from, BOOL overwrite)
{
char *out;
shifted = _KJ_ROMAN;
save = (char *) from;
- for (out = cvtbuf; *from;) {
+ for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
if (is_esc (*from)) {
if (is_so1 (from[1]) && is_so2 (from[2])) {
shifted = _KJ_KANJI;
shifted = _KJ_ROMAN;
save = (char *) from;
- for (out = cvtbuf; *from; ) {
+ for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4); ) {
if (is_shift_jis (*from)) {
int code;
switch (shifted) {
sp = (char *) from;
dp = cvtbuf;
- while (*sp) {
+ while (*sp && (dp - cvtbuf < sizeof(cvtbuf)-3)) {
if (*sp == hex_tag && isxdigit((int)sp[1]) && isxdigit((int)sp[2])) {
*dp++ = (hex2bin (sp[1])<<4) | (hex2bin (sp[2]));
sp += 3;
sp = (unsigned char*) from;
dp = (unsigned char*) cvtbuf;
- while (*sp) {
+ while (*sp && (((char *)dp)- cvtbuf < sizeof(cvtbuf)-7)) {
if (is_kana(*sp)) {
*dp++ = hex_tag;
*dp++ = bin2hex (((*sp)>>4)&0x0f);
sp = (char *) from;
dp = cvtbuf;
- while (*sp) {
+ while (*sp && (dp- cvtbuf < sizeof(cvtbuf)-2)) {
/*
* The only change between this and hex_to_sj is here. sj_to_cap only
* translates characters greater or equal to 0x80 - make sure that here
sp = (unsigned char*) from;
dp = (unsigned char*) cvtbuf;
- while (*sp) {
+ while (*sp && (((char *)dp) - cvtbuf < sizeof(cvtbuf)-4)) {
if (*sp >= 0x80) {
*dp++ = hex_tag;
*dp++ = bin2hex (((*sp)>>4)&0x0f);
return False;
}
-/*******************************************************************
- Function to determine if we are in a multibyte code page.
-*******************************************************************/
-
-static BOOL is_multibyte_codepage_val = False;
-
-BOOL is_multibyte_codepage(void)
-{
- return is_multibyte_codepage_val;
-}
-
/*******************************************************************
Setup the function pointers for the functions that are replaced
when multi-byte codepages are used.
multibyte_strtok = sj_strtok;
_skip_multibyte_char = skip_kanji_multibyte_char;
is_multibyte_char_1 = is_kanji_multibyte_char_1;
- is_multibyte_codepage_val = True;
+ global_is_multibyte_codepage = True;
break;
case HANGUL_CODEPAGE:
multibyte_strchr = generic_multibyte_strchr;
multibyte_strtok = generic_multibyte_strtok;
_skip_multibyte_char = skip_generic_multibyte_char;
is_multibyte_char_1 = hangul_is_multibyte_char_1;
- is_multibyte_codepage_val = True;
+ global_is_multibyte_codepage = True;
break;
case BIG5_CODEPAGE:
multibyte_strchr = generic_multibyte_strchr;
multibyte_strtok = generic_multibyte_strtok;
_skip_multibyte_char = skip_generic_multibyte_char;
is_multibyte_char_1 = big5_is_multibyte_char_1;
- is_multibyte_codepage_val = True;
+ global_is_multibyte_codepage = True;
break;
case SIMPLIFIED_CHINESE_CODEPAGE:
multibyte_strchr = generic_multibyte_strchr;
multibyte_strtok = generic_multibyte_strtok;
_skip_multibyte_char = skip_generic_multibyte_char;
is_multibyte_char_1 = simpch_is_multibyte_char_1;
- is_multibyte_codepage_val = True;
+ global_is_multibyte_codepage = True;
break;
/*
* Single char size code page.
multibyte_strtok = (char *(*)(char *, const char *)) strtok;
_skip_multibyte_char = skip_non_multibyte_char;
is_multibyte_char_1 = not_multibyte_char_1;
- is_multibyte_codepage_val = False;
+ global_is_multibyte_codepage = False;
break;
}
}
slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_lockdir(), name);
- fd = open(pidFile, O_NONBLOCK | O_RDWR);
+ fd = sys_open(pidFile, O_NONBLOCK | O_RDWR, 0644);
if (fd == -1) {
return 0;
}
ret = atoi(pidstr);
- if (!process_exists(ret)) {
+ if (!process_exists((pid_t)ret)) {
goto ok;
}
int fd;
char buf[20];
pstring pidFile;
- int pid;
+ pid_t pid;
slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_lockdir(), 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, pid));
+ name, pidFile, (int)pid));
exit(1);
}
}
/* Leave pid file open & locked for the duration... */
}
-
epoch = (t->tm_year - 70) * YEAR +
((n / 4 - n / 100 + n / 400) - (1969 / 4 - 1969 / 100 + 1969 / 400)) * DAY;
- y = t->tm_year;
+ y = t->tm_year + 1900;
m = 0;
for(i = 0; i < t->tm_mon; i++) {
/* yikes! no SETGROUPS or INITGROUPS? how can this work? */
return(0);
#else /* HAVE_SETGROUPS */
- gid_t grouplst[NGROUPS_MAX];
+ gid_t *grouplst = NULL;
+ int max_gr = groups_max();
+ int ret;
int i,j;
struct group *g;
char *gr;
- setgrent();
+ if((grouplst = (gid_t *)malloc(sizeof(gid_t) * max_gr)) == NULL) {
+ DEBUG(0,("initgroups: malloc fail !\n");
+ return -1;
+ }
+
grouplst[0] = id;
i = 1;
- while (i < NGROUPS_MAX &&
- ((g = (struct group *)getgrent()) != (struct group *)NULL)) {
+ while (i < max_gr && ((g = (struct group *)getgrent()) != (struct group *)NULL)) {
if (g->gr_gid == id)
continue;
j = 0;
}
}
endgrent();
- return(setgroups(i,grouplst));
+ ret = sys_setgroups(i,grouplst);
+ free((char *)grouplst);
+ return ret;
#endif /* HAVE_SETGROUPS */
}
#endif /* HAVE_INITGROUPS */
#include "includes.h"
+/* need to move this from here!! need some sleep ... */
struct current_user current_user;
extern int DEBUGLEVEL;
/*
Unix SMB/Netbios implementation.
- Version 1.9.
- Groupname handling
+ Version 2.0
+
+ SURS - SID to UID Resolution System.
Copyright (C) Luke Kenneth Casson Leighton 1996-2000.
This program is free software; you can redistribute it and/or modify
*/
#include "includes.h"
+#include "surs.h"
extern int DEBUGLEVEL;
/******************************************************************
- converts SID + SID_NAME_USE type to a UNIX id. the Domain SID is,
- and can only be, our own SID.
+ converts SID + SID_NAME_USE type to a UNIX id.
********************************************************************/
-BOOL surs_sam_sid_to_unixid(DOM_SID *sid, uint32 type, uint32 *id, BOOL create)
+BOOL surs_sam_sid_to_unixid(DOM_SID *sid, POSIX_ID *id, BOOL create)
{
+#if 0
#ifdef WITH_NT5LDAP
- return surs_nt5ldap_sam_sid_to_unixid(id, type, sid, create);
+ return surs_nt5ldap_sam_sid_to_unixid(id, sid, create);
#endif
#if WITH_SURSTDB
- return surs_tdb_sam_sid_to_unixid(id, type, sid, create);
+ return surs_tdb_sam_sid_to_unixid(id, sid, create);
+#endif
#endif
- return surs_algdomonly_sam_sid_to_unixid(sid, type, id, create);
+ return surs_algdomonly_sam_sid_to_unixid(sid, id, create);
}
/******************************************************************
- converts UNIX gid + SID_NAME_USE type to a SID. the Domain SID is,
- and can only be, our own SID.
+ converts UNIX id + type to a SID.
********************************************************************/
-BOOL surs_unixid_to_sam_sid(uint32 id, uint32 type, DOM_SID *sid, BOOL create)
+BOOL surs_unixid_to_sam_sid(POSIX_ID *id, DOM_SID *sid, BOOL create)
{
+#if 0
#ifdef WITH_NT5LDAP
- return surs_nt5ldap_unixid_to_sam_sid(id, type, sid, create);
+ return surs_nt5ldap_unixid_to_sam_sid(id, sid, create);
#endif
#if WITH_SURSTDB
- return surs_tdb_unixid_to_sam_sid(id, type, sid, create);
+ return surs_tdb_unixid_to_sam_sid(id, sid, create);
+#endif
#endif
- return surs_algdomonly_unixid_to_sam_sid(id, type, sid, create);
+ return surs_algdomonly_unixid_to_sam_sid(id, sid, create);
}
--- /dev/null
+#ifndef _SURS_H_
+#define _SURS_H_
+
+typedef enum
+{
+ SURS_POSIX_UID_AS_USR,
+ SURS_POSIX_GID_AS_GRP,
+ SURS_POSIX_GID_AS_ALS
+} posix_type;
+
+typedef struct _surs_posix_id
+{
+ uint32 id;
+ posix_type type;
+}
+POSIX_ID;
+
+#endif /* _SURS_H_ */
extern int DEBUGLEVEL;
-/*******************************************************************
- converts a RID to a UNIX ID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
- ********************************************************************/
-static BOOL sursalg_rid_to_unix_id(uint32 rid, uint32 *id, int type)
+static int sursalg_rid_posix_type(uint32 rid)
{
- if((id == NULL) || (rid < 1000))
- return False;
- rid -= 1000;
- if((rid % RID_MULTIPLIER) != type)
- return False;
- *id = rid / RID_MULTIPLIER;
- return True;
+ return ((rid-1000) % RID_MULTIPLIER);
}
-/*******************************************************************
- converts UNIX uid to an NT User RID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
- ********************************************************************/
-static BOOL sursalg_user_rid_to_uid(uint32 user_rid, uint32 *id)
+static uint32 sursalg_rid_posix_id(uint32 rid)
{
- return sursalg_rid_to_unix_id(user_rid, id, RID_TYPE_USER);
-}
-
-/*******************************************************************
- converts NT Group RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
- ********************************************************************/
-static BOOL sursalg_group_rid_to_gid(uint32 group_rid, uint32 *id)
-{
- return sursalg_rid_to_unix_id(group_rid, id, RID_TYPE_GROUP);
-}
-
-/*******************************************************************
- converts NT Alias RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
- ********************************************************************/
-static BOOL sursalg_alias_rid_to_gid(uint32 alias_rid, uint32 *id)
-{
- return sursalg_rid_to_unix_id(alias_rid, id, RID_TYPE_ALIAS);
+ return (rid-1000) / RID_MULTIPLIER;
}
/*******************************************************************
}
/******************************************************************
- converts SID + SID_NAME_USE type to a UNIX id. the Domain SID is,
+ converts SID to a UNIX id + type. the Domain SID is,
and can only be, our own SID.
********************************************************************/
-BOOL surs_algdomonly_sam_sid_to_unixid(DOM_SID *sid, uint32 type, uint32 *id,
+BOOL surs_algdomonly_sam_sid_to_unixid(DOM_SID *sid, POSIX_ID *id,
BOOL create)
{
DOM_SID tmp_sid;
uint32 rid;
+ int type;
sid_copy(&tmp_sid, sid);
sid_split_rid(&tmp_sid, &rid);
return False;
}
+ if((id == NULL) || (rid < 1000))
+ return False;
+
+ type = sursalg_rid_posix_type(rid);
+ id->id = sursalg_rid_posix_id(rid);
+
switch (type)
{
- case SID_NAME_USER:
+ case RID_TYPE_USER:
{
- return sursalg_user_rid_to_uid(rid, id);
+ id->type = SURS_POSIX_UID_AS_USR;
+ return True;
}
- case SID_NAME_ALIAS:
+ case RID_TYPE_ALIAS:
{
- return sursalg_alias_rid_to_gid(rid, id);
+ id->type = SURS_POSIX_GID_AS_ALS;
+ return True;
}
- case SID_NAME_DOM_GRP:
- case SID_NAME_WKN_GRP:
+ case RID_TYPE_GROUP:
{
- return sursalg_group_rid_to_gid(rid, id);
+ id->type = SURS_POSIX_GID_AS_GRP;
+ return True;
+ }
+ default:
+ {
+ break;
}
}
return False;
}
/******************************************************************
- converts UNIX gid + SID_NAME_USE type to a SID. the Domain SID is,
+ converts UNIX id + type to a SID. the Domain SID is,
and can only be, our own SID.
********************************************************************/
-BOOL surs_algdomonly_unixid_to_sam_sid(uint32 id, uint32 type, DOM_SID *sid,
+BOOL surs_algdomonly_unixid_to_sam_sid(POSIX_ID *id, DOM_SID *sid,
BOOL create)
{
sid_copy(sid, &global_sam_sid);
- switch (type)
+ switch (id->type)
{
- case SID_NAME_USER:
+ case SURS_POSIX_UID_AS_USR:
{
- sid_append_rid(sid, sursalg_uid_to_user_rid(id));
+ sid_append_rid(sid, sursalg_uid_to_user_rid(id->id));
return True;
}
- case SID_NAME_ALIAS:
+ case SURS_POSIX_GID_AS_ALS:
{
- sid_append_rid(sid, sursalg_gid_to_alias_rid(id));
+ sid_append_rid(sid, sursalg_gid_to_alias_rid(id->id));
return True;
}
- case SID_NAME_DOM_GRP:
- case SID_NAME_WKN_GRP:
+ case SURS_POSIX_GID_AS_GRP:
{
- sid_append_rid(sid, sursalg_gid_to_group_rid(id));
+ sid_append_rid(sid, sursalg_gid_to_group_rid(id->id));
return True;
}
}
switch (type)
{
- case SID_NAME_USER:
+ case RID_TYPE_USER:
{
attribute = "uidNumber";
break;
}
- case SID_NAME_ALIAS:
- case SID_NAME_DOM_GRP:
- case SID_NAME_WKN_GRP:
+ case RID_TYPE_GROUP:
+ case RID_TYPE_ALIAS:
{
attribute = "gidNumber";
break;
}
/******************************************************************
- converts SID + SID_NAME_USE type to a UNIX id.
+ converts SID + RID_TYPE_USE type to a UNIX id.
********************************************************************/
BOOL surs_tdb_sam_sid_to_unixid(DOM_SID * sid, uint32 type, uint32 * id,
BOOL create)
}
switch (type)
{
- case SID_NAME_USER:
+ case RID_TYPE_USER:
{
ret = tdb_lookup_sid(sid, id);
}
- case SID_NAME_ALIAS:
+ case RID_TYPE_ALIAS:
{
ret = tdb_lookup_sid(sid, id);
}
- case SID_NAME_DOM_GRP:
- case SID_NAME_WKN_GRP:
+ case RID_TYPE_GROUP:
{
ret = tdb_lookup_sid(sid, id);
}
switch (type)
{
- case SID_NAME_USER:
+ case RID_TYPE_USER:
{
ret = tdb_store_uid(*id, sid)
&& tdb_store_sid(sid, *id);
}
- case SID_NAME_ALIAS:
- case SID_NAME_DOM_GRP:
- case SID_NAME_WKN_GRP:
+ case RID_TYPE_ALIAS:
+ case RID_TYPE_GROUP:
{
ret = tdb_store_gid(*id, sid)
&& tdb_store_sid(sid, *id);
}
/******************************************************************
- converts UNIX gid + SID_NAME_USE type to a SID.
+ converts UNIX gid + RID_TYPE_USE type to a SID.
********************************************************************/
BOOL surs_tdb_unixid_to_sam_sid(uint32 id, uint32 type, DOM_SID * sid,
BOOL create)
}
switch (type)
{
- case SID_NAME_USER:
+ case RID_TYPE_USER:
{
ret = tdb_lookup_uid(id, sid);
}
- case SID_NAME_ALIAS:
- case SID_NAME_DOM_GRP:
- case SID_NAME_WKN_GRP:
+ case RID_TYPE_ALIAS:
+ case RID_TYPE_GROUP:
{
ret = tdb_lookup_gid(id, sid);
}
switch (type)
{
- case SID_NAME_USER:
+ case RID_TYPE_USER:
{
ret = tdb_store_uid(id, sid)
&& tdb_store_sid(sid, id);
}
- case SID_NAME_ALIAS:
- case SID_NAME_DOM_GRP:
- case SID_NAME_WKN_GRP:
+ case RID_TYPE_ALIAS:
+ case RID_TYPE_GROUP:
{
ret = tdb_store_gid(id, sid)
&& tdb_store_sid(sid, id);
int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf)
{
-#if defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
- return stat64(fname, sbuf);
+ int ret;
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
+ ret = stat64(fname, sbuf);
#else
- return stat(fname, sbuf);
+ ret = stat(fname, sbuf);
#endif
+ /* we always want directories to appear zero size */
+ if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
+ return ret;
}
/*******************************************************************
int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf)
{
-#if defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
- return fstat64(fd, sbuf);
+ int ret;
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
+ ret = fstat64(fd, sbuf);
#else
- return fstat(fd, sbuf);
+ ret = fstat(fd, sbuf);
#endif
+ /* we always want directories to appear zero size */
+ if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
+ return ret;
}
/*******************************************************************
int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf)
{
-#if defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
- return lstat64(fname, sbuf);
+ int ret;
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
+ ret = lstat64(fname, sbuf);
#else
- return lstat(fname, sbuf);
+ ret = lstat(fname, sbuf);
#endif
+ /* we always want directories to appear zero size */
+ if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
+ return ret;
}
/*******************************************************************
int sys_ftruncate(int fd, SMB_OFF_T offset)
{
-#if defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
return ftruncate64(fd, offset);
#else
return ftruncate(fd, offset);
SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence)
{
-#if defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
return lseek64(fd, offset, whence);
#else
return lseek(fd, offset, whence);
int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence)
{
-#if defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
return fseek64(fp, offset, whence);
+#elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEKO64)
+ return fseeko64(fp, offset, whence);
#else
return fseek(fp, offset, whence);
#endif
SMB_OFF_T sys_ftell(FILE *fp)
{
-#if defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
return (SMB_OFF_T)ftell64(fp);
+#elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELLO64)
+ return (SMB_OFF_T)ftello64(fp);
#else
return (SMB_OFF_T)ftell(fp);
#endif
#endif
}
+#if defined(HAVE_MMAP)
+
/*******************************************************************
An mmap() wrapper that will deal with 64 bit filesizes.
********************************************************************/
void *sys_mmap(void *addr, size_t len, int prot, int flags, int fd, SMB_OFF_T offset)
{
-#if defined(LARGE_SMB_OFF_T) && defined(HAVE_MMAP64)
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_MMAP64)
return mmap64(addr, len, prot, flags, fd, offset);
#else
return mmap(addr, len, prot, flags, fd, offset);
#endif
}
+#endif /* HAVE_MMAP */
+
+/*******************************************************************
+ A readdir wrapper that will deal with 64 bit filesizes.
+********************************************************************/
+
+SMB_STRUCT_DIRENT *sys_readdir(DIR *dirp)
+{
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
+ return readdir64(dirp);
+#else
+ return readdir(dirp);
+#endif
+}
+
/*******************************************************************
The wait() calls vary between systems
********************************************************************/
********************************************************************/
char *sys_getwd(char *s)
{
- char *wd;
+ char *wd;
#ifdef HAVE_GETCWD
- wd = (char *)getcwd(s, sizeof (pstring));
+ wd = (char *)getcwd(s, sizeof (pstring));
#else
- wd = (char *)getwd(s);
+ wd = (char *)getwd(s);
#endif
- return wd;
+ return wd;
}
/*******************************************************************
chown isn't used much but OS/2 doesn't have it
********************************************************************/
+
int sys_chown(const char *fname,uid_t uid,gid_t gid)
{
#ifndef HAVE_CHOWN
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"));
}
#endif
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"));
}
#endif
#endif
}
+/**************************************************************************
+ Returns equivalent to NGROUPS_MAX - using sysconf if needed.
+****************************************************************************/
+
+int groups_max(void)
+{
+#if defined(SYSCONF_SC_NGROUPS_MAX)
+ int ret = sysconf(_SC_NGROUPS_MAX);
+ return (ret == -1) ? NGROUPS_MAX : ret;
+#else
+ return NGROUPS_MAX;
+#endif
+}
+
/**************************************************************************
Wrapper for getgroups. Deals with broken (int) case.
****************************************************************************/
return -1;
}
- if (setlen == 0) setlen = 1;
+ if (setlen == 0)
+ setlen = groups_max();
if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
DEBUG(0,("sys_getgroups: Malloc fail.\n"));
#endif /* HAVE_BROKEN_GETGROUPS */
}
+#ifdef HAVE_SETGROUPS
+
+/**************************************************************************
+ Wrapper for setgroups. Deals with broken (int) case. Automatically used
+ if we have broken getgroups.
+****************************************************************************/
+
+int sys_setgroups(int setlen, gid_t *gidset)
+{
+#if !defined(HAVE_BROKEN_GETGROUPS)
+ return setgroups(setlen, gidset);
+#else
+
+ GID_T *group_list;
+ int i ;
+
+ if (setlen == 0)
+ return 0 ;
+
+ if (setlen < 0 || setlen > groups_max()) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /*
+ * Broken case. We need to allocate a
+ * GID_T array of size setlen.
+ */
+
+ if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
+ DEBUG(0,("sys_setgroups: Malloc fail.\n"));
+ return -1;
+ }
+
+ for(i = 0; i < setlen; i++)
+ group_list[i] = (GID_T) gidset[i];
+
+ if(setgroups(setlen, group_list) != 0) {
+ int saved_errno = errno;
+ free((char *)group_list);
+ errno = saved_errno;
+ return -1;
+ }
+
+ free((char *)group_list);
+ return 0 ;
+#endif /* HAVE_BROKEN_GETGROUPS */
+}
+
+#endif /* HAVE_SETGROUPS */
+
/*
* We only wrap pw_name and pw_passwd for now as these
* are the only potentially modified fields.
Helper function for getpwnam/getpwuid wrappers.
****************************************************************************/
-struct passwd *copy_passwd_struct(struct passwd *pass)
+static struct passwd *setup_pwret(struct passwd *pass)
{
static pstring pw_name;
static pstring pw_passwd;
return NULL;
}
- if (pass == &pw_ret)
- {
- /* catch silly error where buffer was already copied */
- DEBUG(0,("copy_passwd_struct: can't copy internal buffer!\n"));
- return NULL;
- }
-
memcpy((char *)&pw_ret, pass, sizeof(struct passwd));
if (pass->pw_name)
{
- pw_name[0] = '\0';
pw_ret.pw_name = pw_name;
pstrcpy(pw_ret.pw_name, pass->pw_name);
}
if (pass->pw_passwd)
{
- pw_passwd[0] = '\0';
pw_ret.pw_passwd = pw_passwd;
pstrcpy(pw_ret.pw_passwd, pass->pw_passwd);
}
struct passwd *sys_getpwnam(const char *name)
{
- return copy_passwd_struct(getpwnam(name));
+ return setup_pwret(getpwnam(name));
}
/**************************************************************************
struct passwd *sys_getpwuid(uid_t uid)
{
- return copy_passwd_struct(getpwuid(uid));
+ return setup_pwret(getpwuid(uid));
+}
+
+/**************************************************************************
+ The following are the UNICODE versions of *all* system interface functions
+ called within Samba. Ok, ok, the exceptions are the gethostbyXX calls,
+ which currently are left as ascii as they are not used other than in name
+ resolution.
+****************************************************************************/
+
+/**************************************************************************
+ Wide stat. Just narrow and call sys_xxx.
+****************************************************************************/
+
+int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
+{
+ pstring fname;
+ return sys_stat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
+}
+
+/**************************************************************************
+ Wide lstat. Just narrow and call sys_xxx.
+****************************************************************************/
+
+int wsys_lstat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
+{
+ pstring fname;
+ return sys_lstat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
+}
+
+/**************************************************************************
+ Wide creat. Just narrow and call sys_xxx.
+****************************************************************************/
+
+int wsys_creat(const smb_ucs2_t *wfname, mode_t mode)
+{
+ pstring fname;
+ return sys_creat(unicode_to_unix(fname,wfname,sizeof(fname)), mode);
+}
+
+/**************************************************************************
+ Wide open. Just narrow and call sys_xxx.
+****************************************************************************/
+
+int wsys_open(const smb_ucs2_t *wfname, int oflag, mode_t mode)
+{
+ pstring fname;
+ return sys_open(unicode_to_unix(fname,wfname,sizeof(fname)), oflag, mode);
+}
+
+/**************************************************************************
+ Wide fopen. Just narrow and call sys_xxx.
+****************************************************************************/
+
+FILE *wsys_fopen(const smb_ucs2_t *wfname, const char *type)
+{
+ pstring fname;
+ return sys_fopen(unicode_to_unix(fname,wfname,sizeof(fname)), type);
+}
+
+/**************************************************************************
+ Wide opendir. Just narrow and call sys_xxx.
+****************************************************************************/
+
+DIR *wsys_opendir(const smb_ucs2_t *wfname)
+{
+ pstring fname;
+ return opendir(unicode_to_unix(fname,wfname,sizeof(fname)));
+}
+
+/**************************************************************************
+ Wide readdir. Return a structure pointer containing a wide filename.
+****************************************************************************/
+
+SMB_STRUCT_WDIRENT *wsys_readdir(DIR *dirp)
+{
+ static SMB_STRUCT_WDIRENT retval;
+ SMB_STRUCT_DIRENT *dirval = sys_readdir(dirp);
+
+ if(!dirval)
+ return NULL;
+
+ /*
+ * The only POSIX defined member of this struct is d_name.
+ */
+
+ unix_to_unicode(retval.d_name,dirval->d_name,sizeof(retval.d_name));
+
+ return &retval;
+}
+
+/**************************************************************************
+ Wide getwd. Call sys_xxx and widen. Assumes s points to a wpstring.
+****************************************************************************/
+
+smb_ucs2_t *wsys_getwd(smb_ucs2_t *s)
+{
+ pstring fname;
+ char *p = sys_getwd(fname);
+
+ if(!p)
+ return NULL;
+
+ return unix_to_unicode(s, p, sizeof(wpstring));
+}
+
+/**************************************************************************
+ Wide chown. Just narrow and call sys_xxx.
+****************************************************************************/
+
+int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid)
+{
+ pstring fname;
+ return chown(unicode_to_unix(fname,wfname,sizeof(fname)), uid, gid);
+}
+
+/**************************************************************************
+ Wide chroot. Just narrow and call sys_xxx.
+****************************************************************************/
+
+int wsys_chroot(const smb_ucs2_t *wfname)
+{
+ pstring fname;
+ return chroot(unicode_to_unix(fname,wfname,sizeof(fname)));
+}
+
+/**************************************************************************
+ Wide getpwnam. Return a structure pointer containing wide names.
+****************************************************************************/
+
+SMB_STRUCT_WPASSWD *wsys_getpwnam(const smb_ucs2_t *wname)
+{
+ static SMB_STRUCT_WPASSWD retval;
+ fstring name;
+ struct passwd *pwret = sys_getpwnam(unicode_to_unix(name,wname,sizeof(name)));
+
+ if(!pwret)
+ return NULL;
+
+ unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
+ retval.pw_passwd = pwret->pw_passwd;
+ retval.pw_uid = pwret->pw_uid;
+ retval.pw_gid = pwret->pw_gid;
+ unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
+ unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
+ unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
+
+ return &retval;
+}
+
+/**************************************************************************
+ Wide getpwuid. Return a structure pointer containing wide names.
+****************************************************************************/
+
+SMB_STRUCT_WPASSWD *wsys_getpwuid(uid_t uid)
+{
+ static SMB_STRUCT_WPASSWD retval;
+ struct passwd *pwret = sys_getpwuid(uid);
+
+ if(!pwret)
+ return NULL;
+
+ unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
+ retval.pw_passwd = pwret->pw_passwd;
+ retval.pw_uid = pwret->pw_uid;
+ retval.pw_gid = pwret->pw_gid;
+ unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
+ unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
+ unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
+
+ return &retval;
}
/**************************************************************************
StrnCpy(valid, lp_valid_users(snum), sizeof(pstring));
StrnCpy(invalid, lp_invalid_users(snum), sizeof(pstring));
- string_sub(valid,"%S",lp_servicename(snum));
- string_sub(invalid,"%S",lp_servicename(snum));
+ pstring_sub(valid,"%S",lp_servicename(snum));
+ pstring_sub(invalid,"%S",lp_servicename(snum));
ret = !user_in_list(user,invalid);
if (ret && lp_onlyuser(snum)) {
char *user_list = lp_username(snum);
- string_sub(user_list,"%S",lp_servicename(snum));
+ pstring_sub(user_list,"%S",lp_servicename(snum));
ret = user_in_list(user,user_list);
}
if (strnequal(tmp, "0x", 2))
{
ret = strtoul(tmp, (char **)NULL, 16);
- DEBUG(10,("get_number: %s -> 0x%x\n", tmp, ret));
+ DEBUG(10, ("get_number: %s -> 0x%x\n", tmp, ret));
}
else
{
ret = strtoul(tmp, (char **)NULL, 10);
- DEBUG(10,("get_number: %s -> %d\n", tmp, ret));
+ DEBUG(10, ("get_number: %s -> %d\n", tmp, ret));
}
return ret;
}
return p;
}
-uint32 *add_num_to_list(uint32 ** num, int *count, int val)
+uint32 *add_num_to_list(uint32 **num, int *count, int val)
{
(*num) = Realloc((*num), ((*count) + 1) * sizeof(uint32));
if ((*num) == NULL)
/*************************************************************************
reads a list of numbers
*************************************************************************/
-char *get_numlist(char *p, uint32 ** num, int *count)
+char *get_numlist(char *p, uint32 **num, int *count)
{
int val;
return p;
}
-/*******************************************************************
-copy an IP address from one buffer to another
-********************************************************************/
-void putip(void *dest, void *src)
-{
- memcpy(dest, src, 4);
-}
-
/*******************************************************************
check if a file exists
********************************************************************/
return (attrstr);
}
-/****************************************************************************
- make a file into unix format
-****************************************************************************/
-void unix_format(char *fname)
-{
- string_replace(fname, '\\', '/');
-}
-
-/****************************************************************************
- make a file into dos format
-****************************************************************************/
-void dos_format(char *fname)
-{
- string_replace(fname, '/', '\\');
-}
-
/*******************************************************************
show a smb message structure
********************************************************************/
dump_data(10, smb_buf(buf), bcc);
}
-/*******************************************************************
- return the length of an smb packet
-********************************************************************/
-int smb_len(char *buf)
-{
- return (PVAL(buf, 3) | (PVAL(buf, 2) << 8) |
- ((PVAL(buf, 1) & 1) << 16));
-}
-
-/*******************************************************************
- set the length of an smb packet
-********************************************************************/
-void _smb_setlen(char *buf, int len)
-{
- buf[0] = 0;
- buf[1] = (len & 0x10000) >> 16;
- buf[2] = (len & 0xFF00) >> 8;
- buf[3] = len & 0xFF;
-}
-
/*******************************************************************
set the length and marker of an smb packet
********************************************************************/
int set_message(char *buf, int num_words, int num_bytes, BOOL zero)
{
if (zero)
- memset(buf + smb_size, 0, num_words * 2 + num_bytes);
+ memset(buf + smb_size, 0, num_words * 2 + num_bytes);
CVAL(buf, smb_wct) = num_words;
SSVAL(buf, smb_vwv + num_words * SIZEOFWORD, num_bytes);
smb_setlen(buf, smb_size + num_words * 2 + num_bytes - 4);
return (smb_size + num_words * 2 + num_bytes);
}
-/*******************************************************************
-return the number of smb words
-********************************************************************/
-static int smb_numwords(char *buf)
-{
- return (CVAL(buf, smb_wct));
-}
-/*******************************************************************
-return the size of the smb_buf region of a message
-********************************************************************/
-int smb_buflen(char *buf)
-{
- return (SVAL(buf, smb_vwv0 + smb_numwords(buf) * 2));
-}
/*******************************************************************
- return a pointer to the smb_buf data area
+reduce a file name, removing .. elements.
********************************************************************/
-static int smb_buf_ofs(char *buf)
+void dos_clean_name(char *s)
{
- return (smb_size + CVAL(buf, smb_wct) * 2);
-}
+ char *p = NULL;
-/*******************************************************************
- return a pointer to the smb_buf data area
-********************************************************************/
-char *smb_buf(char *buf)
-{
- return (buf + smb_buf_ofs(buf));
-}
+ DEBUG(3, ("dos_clean_name [%s]\n", s));
-/*******************************************************************
-return the SMB offset into an SMB buffer
-********************************************************************/
-int smb_offset(char *p, char *buf)
-{
- return (PTR_DIFF(p, buf + 4) + chain_size);
-}
+ /* remove any double slashes */
+ all_string_sub(s, "\\\\", "\\", 0);
+ while ((p = strstr(s, "\\..\\")) != NULL)
+ {
+ pstring s1;
+
+ *p = 0;
+ pstrcpy(s1, p + 3);
+
+ if ((p = strrchr(s, '\\')) != NULL)
+ *p = 0;
+ else
+ *s = 0;
+ pstrcat(s, s1);
+ }
+
+ trim_string(s, NULL, "\\..");
+ all_string_sub(s, "\\.\\", "\\", 0);
+}
/*******************************************************************
-reduce a file name, removing .. elements.
+reduce a file name, removing .. elements.
********************************************************************/
-void dos_clean_name(char *s)
+void unix_clean_name(char *s)
{
char *p = NULL;
- DEBUG(3, ("dos_clean_name [%s]\n", s));
+ DEBUG(3, ("unix_clean_name [%s]\n", s));
/* remove any double slashes */
- string_sub(s, "\\\\", "\\");
+ all_string_sub(s, "//", "/", 0);
- while ((p = strstr(s, "\\..\\")) != NULL)
+ /* Remove leading ./ characters */
+ if (strncmp(s, "./", 2) == 0)
+ {
+ trim_string(s, "./", NULL);
+ if (*s == 0)
+ pstrcpy(s, "./");
+ }
+
+ while ((p = strstr(s, "/../")) != NULL)
{
pstring s1;
*p = 0;
pstrcpy(s1, p + 3);
- if ((p = strrchr(s, '\\')) != NULL)
+ if ((p = strrchr(s, '/')) != NULL)
*p = 0;
else
*s = 0;
pstrcat(s, s1);
}
- trim_string(s, NULL, "\\..");
+ trim_string(s, NULL, "/..");
+}
+
+/*******************************************************************
+reduce a file name, removing .. elements and checking that
+it is below dir in the heirachy. This uses dos_GetWd() and so must be run
+on the system that has the referenced file system.
+
+widelinks are allowed if widelinks is true
+********************************************************************/
+
+BOOL reduce_name(char *s, char *dir, BOOL widelinks)
+{
+#ifndef REDUCE_PATHS
+ return True;
+#else
+ pstring dir2;
+ pstring wd;
+ pstring base_name;
+ pstring newname;
+ char *p = NULL;
+ BOOL relative = (*s != '/');
+
+ *dir2 = *wd = *base_name = *newname = 0;
+
+ if (widelinks)
+ {
+ unix_clean_name(s);
+ /* can't have a leading .. */
+ if (strncmp(s, "..", 2) == 0 && (s[2] == 0 || s[2] == '/'))
+ {
+ DEBUG(3, ("Illegal file name? (%s)\n", s));
+ return (False);
+ }
+
+ if (strlen(s) == 0)
+ pstrcpy(s, "./");
+
+ return (True);
+ }
+
+ DEBUG(3, ("reduce_name [%s] [%s]\n", s, dir));
+
+ /* remove any double slashes */
+ all_string_sub(s, "//", "/", 0);
- string_sub(s, "\\.\\", "\\");
+ pstrcpy(base_name, s);
+ p = strrchr(base_name, '/');
+
+ if (!p)
+ return (True);
+
+ if (!dos_GetWd(wd))
+ {
+ DEBUG(0, ("couldn't getwd for %s %s\n", s, dir));
+ return (False);
+ }
+
+ if (dos_ChDir(dir) != 0)
+ {
+ DEBUG(0, ("couldn't chdir to %s\n", dir));
+ return (False);
+ }
+
+ if (!dos_GetWd(dir2))
+ {
+ DEBUG(0, ("couldn't getwd for %s\n", dir));
+ dos_ChDir(wd);
+ return (False);
+ }
+
+ if (p && (p != base_name))
+ {
+ *p = 0;
+ if (strcmp(p + 1, ".") == 0)
+ p[1] = 0;
+ if (strcmp(p + 1, "..") == 0)
+ *p = '/';
+ }
+
+ if (dos_ChDir(base_name) != 0)
+ {
+ dos_ChDir(wd);
+ DEBUG(3,
+ ("couldn't chdir for %s %s basename=%s\n", s, dir,
+ base_name));
+ return (False);
+ }
+
+ if (!dos_GetWd(newname))
+ {
+ dos_ChDir(wd);
+ DEBUG(2, ("couldn't get wd for %s %s\n", s, dir2));
+ return (False);
+ }
+
+ if (p && (p != base_name))
+ {
+ pstrcat(newname, "/");
+ pstrcat(newname, p + 1);
+ }
+
+ {
+ size_t l = strlen(dir2);
+ if (dir2[l - 1] == '/')
+ l--;
+
+ if (strncmp(newname, dir2, l) != 0)
+ {
+ dos_ChDir(wd);
+ DEBUG(2,
+ ("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",
+ s, dir2, newname, (int)l));
+ return (False);
+ }
+
+ if (relative)
+ {
+ if (newname[l] == '/')
+ pstrcpy(s, newname + l + 1);
+ else
+ pstrcpy(s, newname + l);
+ }
+ else
+ pstrcpy(s, newname);
+ }
+
+ dos_ChDir(wd);
+
+ if (strlen(s) == 0)
+ pstrcpy(s, "./");
+
+ DEBUG(3, ("reduced to %s\n", s));
+ return (True);
+#endif
+}
+
+/****************************************************************************
+expand some *s
+****************************************************************************/
+static void expand_one(char *Mask, int len)
+{
+ char *p1;
+ while ((p1 = strchr(Mask, '*')) != NULL)
+ {
+ int lfill = (len + 1) - strlen(Mask);
+ int l1 = (p1 - Mask);
+ pstring tmp;
+ pstrcpy(tmp, Mask);
+ memset(tmp + l1, '?', lfill);
+ pstrcpy(tmp + l1 + lfill, Mask + l1 + 1);
+ pstrcpy(Mask, tmp);
+ }
+}
+
+/****************************************************************************
+parse out a filename from a path name. Assumes dos style filenames.
+****************************************************************************/
+static char *filename_dos(char *path, char *buf)
+{
+ char *p = strrchr(path, '\\');
+
+ if (!p)
+ pstrcpy(buf, path);
+ else
+ pstrcpy(buf, p + 1);
+
+ return (buf);
+}
+
+
+/****************************************************************************
+expand a wildcard expression, replacing *s with ?s
+****************************************************************************/
+void expand_mask(char *Mask, BOOL doext)
+{
+ pstring mbeg, mext;
+ pstring dirpart;
+ pstring filepart;
+ BOOL hasdot = False;
+ char *p1;
+ BOOL absolute = (*Mask == '\\');
+
+ *mbeg = *mext = *dirpart = *filepart = 0;
+
+ /* parse the directory and filename */
+ if (strchr(Mask, '\\'))
+ split_at_last_component(Mask, dirpart, '\\', NULL);
+
+ filename_dos(Mask, filepart);
+
+ pstrcpy(mbeg, filepart);
+ if ((p1 = strchr(mbeg, '.')) != NULL)
+ {
+ hasdot = True;
+ *p1 = 0;
+ p1++;
+ pstrcpy(mext, p1);
+ }
+ else
+ {
+ pstrcpy(mext, "");
+ if (strlen(mbeg) > 8)
+ {
+ pstrcpy(mext, mbeg + 8);
+ mbeg[8] = 0;
+ }
+ }
+
+ if (*mbeg == 0)
+ pstrcpy(mbeg, "????????");
+ if ((*mext == 0) && doext && !hasdot)
+ pstrcpy(mext, "???");
+
+ if (strequal(mbeg, "*") && *mext == 0)
+ pstrcpy(mext, "*");
+
+ /* expand *'s */
+ expand_one(mbeg, 8);
+ if (*mext)
+ expand_one(mext, 3);
+
+ pstrcpy(Mask, dirpart);
+ if (*dirpart || absolute)
+ pstrcat(Mask, "\\");
+ pstrcat(Mask, mbeg);
+ pstrcat(Mask, ".");
+ pstrcat(Mask, mext);
+
+ DEBUG(6, ("Mask expanded to [%s]\n", Mask));
}
else
memcpy(buf + 1, mask2, MIN(strlen(mask2), 11));
- memset(buf + 21, 0, DIR_STRUCT_SIZE - 21);
+ memset(buf + 21, '\0', DIR_STRUCT_SIZE - 21);
CVAL(buf, 21) = mode;
put_dos_date(buf, 22, date);
SSVAL(buf, 26, size & 0xFFFF);
#undef FLAG_TO_SET
}
-
-/*******************************************************************
-find the difference in milliseconds between two struct timeval
-values
-********************************************************************/
-int TvalDiff(struct timeval *tvalold, struct timeval *tvalnew)
-{
- return ((tvalnew->tv_sec - tvalold->tv_sec) * 1000 +
- ((int)tvalnew->tv_usec - (int)tvalold->tv_usec) / 1000);
-}
-
-
-
/****************************************************************************
transfer some data between two fd's
****************************************************************************/
}
}
-/****************************************************************************
-open the directory and look-up the matching names
-****************************************************************************/
-BOOL get_file_match(const char *dirname, const char *regexp,
- uint32 * total, char ***list)
-{
- DIR *dirp;
- char *dpname;
-
- dirp = opendir(dirname);
-
- if (dirp == NULL)
- {
- DEBUG(2, ("Error opening directory [%s]\n", dirname));
- return False;
- }
-
- DEBUG(5, ("get_dir_match: %s with %s\n", dirname, regexp));
-
- while ((dpname = readdirname(dirp)) != NULL)
- {
- if (do_match(dpname, regexp, False))
- {
- DEBUGADD(7, ("Found: [%s]\n", dpname));
-
- add_chars_to_array(total, list, dpname);
- DEBUGADD(6, ("Added: [%s]\n", dpname));
- }
- }
-
- closedir(dirp);
-
- return True;
-}
/*********************************************************
* Recursive routine that is called by unix_mask_match.
* Does the actual matching. This is the 'original code'
* used by the unix matcher.
*********************************************************/
-static BOOL unix_do_match(char *str, char *regexp, int case_sig)
+
+BOOL unix_do_match(char *str, char *regexp, BOOL case_sig)
{
char *p;
break;
case '*':
- /* Look for a character matching
- the one after the '*' */
+ /*
+ * Look for a character matching
+ * the one after the '*'.
+ */
p++;
if (!*p)
return True; /* Automatic match */
: (toupper(*p) !=
toupper(*str))))
str++;
+
+ /*
+ * Patch from weidel@multichart.de. In the case of the regexp
+ * '*XX*' we want to ensure there are at least 2 'X' characters
+ * in the filename after the '*' for a match to be made.
+ */
+
+ {
+ int matchcount = 0;
+
+ /*
+ * Eat all the characters that match, but count how many there were.
+ */
+
+ while (*str
+ && (case_sig
+ ? (*p ==
+ *str)
+ : (toupper(*p) ==
+ toupper(*str))))
+ {
+ str++;
+ matchcount++;
+ }
+
+ /*
+ * Now check that if the regexp had n identical characters that
+ * matchcount had at least that many matches.
+ */
+
+ while (
+ (*(p + 1)
+ && (case_sig
+ ? (*(p + 1) ==
+ *p)
+ : (toupper
+ (*(p + 1)) ==
+ toupper(*p)))))
+ {
+ p++;
+ matchcount--;
+ }
+ if (matchcount <= 0)
+ {
+ return False;
+ }
+ }
+ str--; /* We've eaten the match char after the '*' */
if (unix_do_match(str, p, case_sig))
return True;
if (!*str)
* This is the 'original code' used by the unix matcher.
*********************************************************/
-static BOOL unix_mask_match(char *str, char *regexp, int case_sig,
- BOOL trans2)
+static BOOL unix_mask_match(char *str, char *regexp, BOOL case_sig)
{
char *p;
pstring p1, p2;
- fstring ebase, eext, sbase, sext;
-
+ fstring ebase, sbase;
BOOL matched;
/* Make local copies of str and regexp */
StrnCpy(p1, regexp, sizeof(pstring) - 1);
StrnCpy(p2, str, sizeof(pstring) - 1);
- if (!strchr(p2, '.'))
- {
- pstrcat(p2, ".");
- }
-
/* Remove any *? and ** as they are meaningless */
for (p = p1; *p; p++)
while (*p == '*' && (p[1] == '?' || p[1] == '*'))
("unix_mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2,
p1, case_sig));
- if (trans2)
- {
- fstrcpy(ebase, p1);
- fstrcpy(sbase, p2);
- }
- else
- {
- if ((p = strrchr(p1, '.')))
- {
- *p = 0;
- fstrcpy(ebase, p1);
- fstrcpy(eext, p + 1);
- }
- else
- {
- fstrcpy(ebase, p1);
- eext[0] = 0;
- }
-
- if (!strequal(p2, ".") && !strequal(p2, "..")
- && (p = strrchr(p2, '.')))
- {
- *p = 0;
- fstrcpy(sbase, p2);
- fstrcpy(sext, p + 1);
- }
- else
- {
- fstrcpy(sbase, p2);
- fstrcpy(sext, "");
- }
- }
+ fstrcpy(ebase, p1);
+ fstrcpy(sbase, p2);
- matched = unix_do_match(sbase, ebase, case_sig) &&
- (trans2 || unix_do_match(sext, eext, case_sig));
+ matched = unix_do_match(sbase, ebase, case_sig);
DEBUG(8, ("unix_mask_match returning %d\n", matched));
* Recursive routine that is called by mask_match.
* Does the actual matching. Returns True if matched,
* False if failed. This is the 'new' NT style matcher.
+* The win9x_semantics parameter is needed as Win9x matching
+* is *actually different*. In Win9x, trailing '?' characters
+* will only match the *exact* number of characters. Under
+* DOS and NT they match any number. This makes no
+* sense.....
*********************************************************/
-BOOL do_match(char *str, const char *regexp, int case_sig)
+static BOOL do_match(char *str, char *regexp, int case_sig,
+ BOOL win9x_semantics)
{
- const char *p;
+ char *p;
for (p = regexp; *p && *str;)
{
: (toupper(*p) !=
toupper(*str))))
str++;
- /* Now eat all characters that match, as
- we want the *last* character to match. */
- while (*str
- && (case_sig ? (*p == *str)
- : (toupper(*p) ==
- toupper(*str))))
- str++;
+
+ /*
+ * Patch from weidel@multichart.de. In the case of the regexp
+ * '*XX*' we want to ensure there are at least 2 'X' characters
+ * in the filename after the '*' for a match to be made.
+ */
+
+ {
+ int matchcount = 0;
+
+ /*
+ * Eat all the characters that match, but count how many there were.
+ */
+
+ while (*str
+ && (case_sig
+ ? (*p ==
+ *str)
+ : (toupper(*p) ==
+ toupper(*str))))
+ {
+ str++;
+ matchcount++;
+ }
+
+ /*
+ * Now check that if the regexp had n identical characters that
+ * matchcount had at least that many matches.
+ */
+
+ while (
+ (*(p + 1)
+ && (case_sig
+ ? (*(p + 1) ==
+ *p)
+ : (toupper
+ (*(p + 1)) ==
+ toupper(*p)))))
+ {
+ p++;
+ matchcount--;
+ }
+ if (matchcount <= 0)
+ {
+ return False;
+ }
+ }
str--; /* We've eaten the match char after the '*' */
- if (do_match(str, p, case_sig))
+ if (do_match
+ (str, p, case_sig,
+ win9x_semantics))
{
return True;
}
return (True);
}
- if (!*str && *p == '?')
+ if (!win9x_semantics)
{
- while (*p == '?')
- p++;
- return (!*p);
+ if (!*str && *p == '?')
+ {
+ while (*p == '?')
+ p++;
+ return (!*p);
+ }
}
if (!*str && (*p == '*' && p[1] == '\0'))
* This is the new 'NT style' matcher.
*********************************************************/
-BOOL mask_match(char *str, char *regexp, int case_sig, BOOL trans2)
+BOOL mask_match(char *str, char *regexp, BOOL case_sig, BOOL trans2)
{
char *p;
pstring t_pattern, t_filename, te_pattern, te_filename;
fstring ebase, eext, sbase, sext;
BOOL matched = False;
+ BOOL win9x_semantics = (get_remote_arch() == RA_WIN95) && trans2;
+
+ /* special case - if it is exactly the same then it always matches! */
+ if (exact_match(str, regexp, case_sig))
+ return True;
/* Make local copies of str and regexp */
pstrcpy(t_pattern, regexp);
pstrcpy(t_filename, str);
+ if (trans2)
+ {
+
+ /* a special case for 16 bit apps */
+ if (strequal(t_pattern, "????????.???"))
+ pstrcpy(t_pattern, "*");
+
+#if 0
+ /*
+ * Handle broken clients that send us old 8.3 format.
+ */
+ pstring_sub(t_pattern, "????????", "*");
+ pstring_sub(t_pattern, ".???", ".*");
+#endif
+ }
+
#if 0
/*
* Not sure if this is a good idea. JRA.
#endif
/* Remove any *? and ** as they are meaningless */
- string_sub(t_pattern, "*?", "*");
- string_sub(t_pattern, "**", "*");
+ for (p = t_pattern; *p; p++)
+ while (*p == '*' && (p[1] == '?' || p[1] == '*'))
+ (void)pstrcpy(&p[1], &p[2]);
if (strequal(t_pattern, "*"))
return (True);
/*
* Remove multiple "*." patterns.
*/
- string_sub(te_pattern, "*.*.", "*.");
+ pstring_sub(te_pattern, "*.*.", "*.");
num_regexp_components = count_chars(te_pattern, '.');
num_path_components = count_chars(te_filename, '.');
* Check for special 'hack' case of "DIR a*z". - needs to match a.b.c...z
*/
if (num_regexp_components == 0)
- matched = do_match(te_filename, te_pattern, case_sig);
+ matched =
+ do_match(te_filename, te_pattern, case_sig,
+ win9x_semantics);
else
{
for (cp1 = te_pattern, cp2 = te_filename; cp1;)
if (rp)
*rp = '\0';
- if (cp1[strlen(cp1) - 1] == '*')
+ if (cp1[0] && cp1[strlen(cp1) - 1] == '*')
last_wcard_was_star = True;
else
last_wcard_was_star = False;
- if (!do_match(cp2, cp1, case_sig))
+ if (!do_match
+ (cp2, cp1, case_sig, win9x_semantics))
break;
+ /*
+ * Ugly ! Special case for Win9x *only*. If filename is XXXX and pattern extension
+ * is '*' or all '?' then disallow match.
+ */
+
+ if (win9x_semantics)
+ {
+ if (*cp2 == '\0'
+ && str_is_all(cp1, '?'))
+ break;
+ }
+
cp1 = rp ? rp + 1 : NULL;
cp2 = fp ? fp + 1 : "";
if ((cp1 != NULL)
&& do_match(cp2, cp1,
- case_sig))
+ case_sig,
+ win9x_semantics))
{
cp2 =
fp ? fp +
if (strequal(t_filename, "."))
{
/*
- * Patterns: *.* *. ?. ? are valid
+ * Patterns: *.* *. ?. ? ????????.??? are valid.
*
*/
if (strequal(t_pattern, "*.*")
|| strequal(t_pattern, "*.")
+ || strequal(t_pattern, "????????.???")
|| strequal(t_pattern, "?.")
|| strequal(t_pattern, "?"))
matched = True;
else if (strequal(t_filename, ".."))
{
/*
- * Patterns: *.* *. ?. ? *.? are valid
+ * Patterns: *.* *. ?. ? *.? ????????.??? are valid.
*
*/
if (strequal(t_pattern, "*.*")
|| strequal(t_pattern, "*.")
|| strequal(t_pattern, "?.")
|| strequal(t_pattern, "?")
+ || strequal(t_pattern, "????????.???")
|| strequal(t_pattern, "*.?")
|| strequal(t_pattern, "?.*"))
matched = True;
{
matched =
do_match(sbase, ebase,
- case_sig)
+ case_sig, False)
&& do_match(sext, eext,
- case_sig);
+ case_sig, False);
}
else
{
/* pattern has no extension */
/* Really: match complete filename with pattern ??? means exactly 3 chars */
matched =
- do_match(str, ebase,
- case_sig);
+ do_match(str, ebase, case_sig,
+ False);
}
}
else
/* pattern has extension */
matched =
do_match(sbase, ebase,
- case_sig)
+ case_sig, False)
&& do_match(sext, eext,
- case_sig);
+ case_sig, False);
+
}
else
{
matched =
do_match(sbase, ebase,
- case_sig);
+ case_sig, False);
#ifdef EMULATE_WEIRD_W95_MATCHING
/*
* Even Microsoft has some problems
fstrcat(sbase, ".");
matched =
do_match(sbase, ebase,
- case_sig);
+ case_sig,
+ False);
}
#endif
}
#endif
+/****************************************************************************
+ copies or initialises to zeros. checks NULL pointers, basically.
+ returns True on an actual memcpy.
+ ****************************************************************************/
+BOOL Memcpy(void *to, const void *from, size_t size)
+{
+ if (to == NULL)
+ {
+ return False;
+ }
+ if (from == NULL)
+ {
+ memset(to, 0, size);
+ return False;
+ }
+
+ memcpy(to, from, size);
+ return True;
+}
/****************************************************************************
expand a pointer to be a particular size
else
ret = (void *)realloc(p, size);
-#ifdef MEM_MAN
- {
- extern FILE *dbf;
- smb_mem_write_info(ret, dbf);
- }
-#endif
-
if (!ret)
DEBUG(0,
("Memory allocation error: failed to expand to %d bytes\n",
- size));
+ (int)size));
return (ret);
}
return (True);
}
-
-/****************************************************************************
-true if two IP addresses are equal
-****************************************************************************/
-BOOL ip_equal(struct in_addr ip1, struct in_addr ip2)
-{
- uint32 a1, a2;
- a1 = ntohl(ip1.s_addr);
- a2 = ntohl(ip2.s_addr);
- return (a1 == a2);
-}
-
-
/****************************************************************************
interpret a protocol description string, with a default
****************************************************************************/
putip((char *)&res, (char *)hp->h_addr);
}
- if (res == (uint32) - 1)
+ if (res == (uint32)-1)
return (0);
return (res);
if (object->zo_data.zo_type == ENTRY_OBJ)
{
entry =
- &object->zo_data.
- objdata_u.en_data;
+ &object->zo_data.objdata_u.
+ en_data;
DEBUG(5,
("NIS+ entry type: %s\n",
entry->en_type));
DEBUG(3,
("NIS+ result: %s\n",
- entry->en_cols.
- en_cols_val[1].ec_value.
- ec_value_val));
+ entry->en_cols.en_cols_val[1].
+ ec_value.ec_value_val));
pstrcpy(last_value,
entry->en_cols.
en_cols_val[1].ec_value.
ec_value_val);
- string_sub(last_value, "&",
- user_name);
+ pstring_sub(last_value, "&",
+ user_name);
fstrcpy(last_key, user_name);
}
}
switch (*(p + 1))
{
case 'I':
- string_sub(p, "%I", client_connection_addr());
+ pstring_sub(p, "%I",
+ client_connection_addr());
break;
case 'L':
- string_sub(p, "%L", local_machine);
+ pstring_sub(p, "%L", local_machine);
break;
case 'M':
- string_sub(p, "%M", client_connection_name());
+ pstring_sub(p, "%M",
+ client_connection_name());
break;
case 'R':
- string_sub(p, "%R", remote_proto);
+ pstring_sub(p, "%R", remote_proto);
break;
case 'T':
- string_sub(p, "%T", timestring(False));
+ pstring_sub(p, "%T", timestring(False));
break;
case 'a':
- string_sub(p, "%a", remote_arch);
+ pstring_sub(p, "%a", remote_arch);
break;
case 'd':
{
slprintf(pidstr, sizeof(pidstr) - 1, "%d",
(int)getpid());
- string_sub(p, "%d", pidstr);
+ pstring_sub(p, "%d", pidstr);
break;
}
case 'h':
- string_sub(p, "%h", myhostname());
+ pstring_sub(p, "%h", myhostname());
break;
case 'm':
- string_sub(p, "%m", remote_machine);
+ pstring_sub(p, "%m", remote_machine);
break;
case 'v':
- string_sub(p, "%v", VERSION);
+ pstring_sub(p, "%v", VERSION);
break;
case '$': /* Expand environment variables */
{
(sizeof(envname) - 1));
strncpy(envname, p, copylen);
envname[copylen] = '\0';
- string_sub(p, envname, envval);
+ pstring_sub(p, envname, envval);
break;
}
case '\0':
if ((pass = Get_Pwnam(vuser->name, False)) !=
NULL)
{
- string_sub(p, "%G",
- gidtoname(pass->pw_gid));
+ pstring_sub(p, "%G",
+ gidtoname(pass->pw_gid));
}
else
{
break;
}
case 'N':
- string_sub(p, "%N",
- automount_server(vuser->name));
+ pstring_sub(p, "%N",
+ automount_server(vuser->name));
break;
case 'U':
- string_sub(p, "%U", vuser->requested_name);
+ pstring_sub(p, "%U", vuser->requested_name);
break;
case '\0':
p++;
if ((home = get_unixhome_dir(conn->user)) !=
NULL)
{
- string_sub(p, "%H", home);
+ pstring_sub(p, "%H", home);
}
else
{
* "path =" string in [homes] and so needs the
* service name, not the username. */
case 'p':
- string_sub(p, "%p",
- automount_path(lp_servicename
- (SNUM(conn))));
+ pstring_sub(p, "%p",
+ automount_path(lp_servicename
+ (SNUM(conn))));
break;
case 'P':
- string_sub(p, "%P", conn->connectpath);
+ pstring_sub(p, "%P", conn->connectpath);
break;
case 'S':
- string_sub(p, "%S",
- lp_servicename(SNUM(conn))); break;
+ pstring_sub(p, "%S",
+ lp_servicename(SNUM(conn)));
+ break;
case 'g':
- string_sub(p, "%g", gidtoname(conn->gid));
+ pstring_sub(p, "%g", gidtoname(conn->gid));
break;
case 'u':
- string_sub(p, "%u", conn->user);
+ pstring_sub(p, "%u", conn->user);
break;
case '\0':
********************************************************************/
char *readdirname(DIR * p)
{
- struct dirent *ptr;
+ SMB_STRUCT_DIRENT *ptr;
char *dname;
if (!p)
return (NULL);
- ptr = (struct dirent *)readdir(p);
+ ptr = (SMB_STRUCT_DIRENT *) sys_readdir(p);
if (!ptr)
return (NULL);
* 'unix style' mask match, rather than the
* new NT one.
*/
- if (unix_mask_match(last_component, namelist->name,
- case_sensitive, False))
+ if (unix_mask_match
+ (last_component, namelist->name, case_sensitive))
{
DEBUG(8,
("is_in_path: mask match succeeded\n"));
int mod = PTR_DIFF(q, base) & 3;
if (mod != 0)
{
- q += 4-mod;
+ q += 4 - mod;
}
return q;
}
{
#if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
struct rlimit rlp;
- getrlimit(RLIMIT_NOFILE, &rlp);
- /* Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
- * account for the extra fd we need
- * as well as the log files and standard
- * handles etc. */
- rlp.rlim_cur = MIN(requested_max, rlp.rlim_max);
- setrlimit(RLIMIT_NOFILE, &rlp);
- getrlimit(RLIMIT_NOFILE, &rlp);
+ int saved_current_limit;
+
+ if (getrlimit(RLIMIT_NOFILE, &rlp))
+ {
+ DEBUG(0,
+ ("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
+ strerror(errno)));
+ /* just guess... */
+ return requested_max;
+ }
+
+ /*
+ * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
+ * account for the extra fd we need
+ * as well as the log files and standard
+ * handles etc. Save the limit we want to set in case
+ * we are running on an OS that doesn't support this limit (AIX)
+ * which always returns RLIM_INFINITY for rlp.rlim_max.
+ */
+
+ saved_current_limit = rlp.rlim_cur = MIN(requested_max, rlp.rlim_max);
+
+ if (setrlimit(RLIMIT_NOFILE, &rlp))
+ {
+ DEBUG(0,
+ ("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
+ (int)rlp.rlim_cur, strerror(errno)));
+ /* just guess... */
+ return saved_current_limit;
+ }
+
+ if (getrlimit(RLIMIT_NOFILE, &rlp))
+ {
+ DEBUG(0,
+ ("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
+ strerror(errno)));
+ /* just guess... */
+ return saved_current_limit;
+ }
+
+#if defined(RLIM_INFINITY)
+ if (rlp.rlim_cur == RLIM_INFINITY)
+ return saved_current_limit;
+#endif
+
+ if ((int)rlp.rlim_cur > saved_current_limit)
+ return saved_current_limit;
+
return rlp.rlim_cur;
-#else
+#else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
/*
* No way to know - just guess...
*/
/*****************************************************************
splits out the start of the key (HKLM or HKU) and the rest of the key
*****************************************************************/
-BOOL reg_split_key(const char *full_keyname, uint32 * reg_type,
- char *key_name)
+BOOL reg_split_key(const char *full_keyname, uint32 *reg_type, char *key_name)
{
pstring tmp;
********************************************************************/
static void set_time_in_string(char *p, int max_len, char *type, time_t t)
{
- slprintf(p, max_len, ":%s-%08X", type, (uint32) t);
+ slprintf(p, max_len, ":%s-%08X", type, (uint32)t);
}
/*******************************************************************
Routine to get the 32 hex characters and turn them
into a 16 byte array.
**************************************************************/
-BOOL pwdb_gethexpwd(const char *p, char *pwd, uint32 * acct_ctrl)
+BOOL pwdb_gethexpwd(const char *p, char *pwd, uint32 *acct_ctrl)
{
if (strnequal(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 32))
{
}
}
+/*****************************************************************
+like mktemp() but make sure that no % characters are used
+% characters are bad for us because of the macro subs
+ *****************************************************************/
+char *smbd_mktemp(char *template)
+{
+ char *p = mktemp(template);
+ char *p2;
+ SMB_STRUCT_STAT st;
+
+ if (!p)
+ return NULL;
+
+ while ((p2 = strchr(p, '%')))
+ {
+ p2[0] = 'A';
+ while (sys_stat(p, &st) == 0 && p2[0] < 'Z')
+ {
+ /* damn, it exists */
+ p2[0]++;
+ }
+ if (p2[0] == 'Z')
+ {
+ /* oh well ... better return something */
+ p2[0] = '%';
+ return p;
+ }
+ }
+
+ return p;
+}
+
/*****************************************************************
like strdup but for memory
*****************************************************************/
/*****************************************************************
get local hostname and cache result
- *****************************************************************/
+ *****************************************************************/
char *myhostname(void)
{
static pstring ret;
- if (ret[0] == 0) {
+ if (ret[0] == 0)
+ {
get_myname(ret, NULL);
}
return ret;
return fname;
}
+/*******************************************************************
+ Given a filename - get its directory name
+ NB: Returned in static storage. Caveats:
+ o Not safe in thread environment.
+ o Caller must not free.
+ o If caller wishes to preserve, they should copy.
+********************************************************************/
+
+char *parent_dirname(const char *path)
+{
+ static pstring dirpath;
+ char *p;
+
+ if (!path)
+ return (NULL);
+
+ pstrcpy(dirpath, path);
+ p = strrchr(dirpath, '/'); /* Find final '/', if any */
+ if (!p)
+ {
+ pstrcpy(dirpath, "."); /* No final "/", so dir is "." */
+ }
+ else
+ {
+ if (p == dirpath)
+ ++p; /* For root "/", leave "/" in place */
+ *p = '\0';
+ }
+ return dirpath;
+}
+
struct field_info sid_name_info[] = {
{SID_NAME_UNKNOWN, "UNKNOWN"}, /* default */
{SID_NAME_USER, "User"},
{
return enum_field_to_str(sid_name_use, sid_name_info, True);
}
-
/****************************************************************************
routine to do file locking
****************************************************************************/
+
BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
{
#if HAVE_FCNTL_LOCK
- SMB_STRUCT_FLOCK lock;
- int ret;
-
- if(lp_ole_locking_compat()) {
- SMB_OFF_T mask2= ((SMB_OFF_T)0x3) << (SMB_OFF_T_BITS-4);
- SMB_OFF_T mask = (mask2<<2);
-
- /* make sure the count is reasonable, we might kill the lockd otherwise */
- count &= ~mask;
-
- /* the offset is often strange - remove 2 of its bits if either of
- the top two bits are set. Shift the top ones by two bits. This
- still allows OLE2 apps to operate, but should stop lockd from
- dieing */
- if ((offset & mask) != 0)
- offset = (offset & ~mask) | (((offset & mask) >> 2) & mask2);
- } else {
- SMB_OFF_T mask2 = ((SMB_OFF_T)0x4) << (SMB_OFF_T_BITS-4);
- SMB_OFF_T mask = (mask2<<1);
- SMB_OFF_T neg_mask = ~mask;
-
- /* interpret negative counts as large numbers */
- if (count < 0)
- count &= ~mask;
-
- /* no negative offsets */
- if(offset < 0)
- offset &= ~mask;
-
- /* count + offset must be in range */
- while ((offset < 0 || (offset + count < 0)) && mask)
- {
- offset &= ~mask;
- mask = ((mask >> 1) & neg_mask);
- }
- }
+ SMB_STRUCT_FLOCK lock;
+ int ret;
+#if defined(LARGE_SMB_OFF_T)
+ /*
+ * In the 64 bit locking case we store the original
+ * values in case we have to map to a 32 bit lock on
+ * a filesystem that doesn't support 64 bit locks.
+ */
+ SMB_OFF_T orig_offset = offset;
+ SMB_OFF_T orig_count = count;
+#endif /* LARGE_SMB_OFF_T */
- DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type));
+ if (lp_ole_locking_compat())
+ {
+ SMB_OFF_T mask2 = ((SMB_OFF_T) 0x3) << (SMB_OFF_T_BITS - 4);
+ SMB_OFF_T mask = (mask2 << 2);
+
+ /* make sure the count is reasonable, we might kill the lockd otherwise */
+ count &= ~mask;
+
+ /* the offset is often strange - remove 2 of its bits if either of
+ the top two bits are set. Shift the top ones by two bits. This
+ still allows OLE2 apps to operate, but should stop lockd from
+ dieing */
+ if ((offset & mask) != 0)
+ offset =
+ (offset & ~mask) | (((offset & mask) >> 2) &
+ mask2);
+ }
+ else
+ {
+ SMB_OFF_T mask2 = ((SMB_OFF_T) 0x4) << (SMB_OFF_T_BITS - 4);
+ SMB_OFF_T mask = (mask2 << 1);
+ SMB_OFF_T neg_mask = ~mask;
- lock.l_type = type;
- lock.l_whence = SEEK_SET;
- lock.l_start = offset;
- lock.l_len = count;
- lock.l_pid = 0;
+ /* interpret negative counts as large numbers */
+ if (count < 0)
+ count &= ~mask;
- errno = 0;
+ /* no negative offsets */
+ if (offset < 0)
+ offset &= ~mask;
- ret = fcntl(fd,op,&lock);
- if (errno == EFBIG)
- {
- if( DEBUGLVL( 0 ))
- {
- dbgtext("fcntl_lock: WARNING: lock request at offset %.0f, length %.0f returned\n", (double)offset,(double)count);
- dbgtext("a 'file too large' error. This can happen when using 64 bit lock offsets\n");
- dbgtext("on 32 bit NFS mounted file systems. Retrying with 32 bit truncated length.\n");
- }
- /* 32 bit NFS file system, retry with smaller offset */
- errno = 0;
- lock.l_len = count & 0xffffffff;
- ret = fcntl(fd,op,&lock);
- }
+ /* count + offset must be in range */
+ while ((offset < 0 || (offset + count < 0)) && mask)
+ {
+ offset &= ~mask;
+ mask = ((mask >> 1) & neg_mask);
+ }
+ }
- if (errno != 0)
- DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
+ DEBUG(8,
+ ("fcntl_lock %d %d %.0f %.0f %d\n", fd, op, (double)offset,
+ (double)count, type));
- /* a lock query */
- if (op == SMB_F_GETLK)
- {
- if ((ret != -1) &&
- (lock.l_type != F_UNLCK) &&
- (lock.l_pid != 0) &&
- (lock.l_pid != getpid()))
- {
- DEBUG(3,("fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
- return(True);
- }
+ lock.l_type = type;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = offset;
+ lock.l_len = count;
+ lock.l_pid = 0;
- /* it must be not locked or locked by me */
- return(False);
- }
+ errno = 0;
- /* a lock set or unset */
- if (ret == -1)
- {
- DEBUG(3,("lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
- (double)offset,(double)count,op,type,strerror(errno)));
+ ret = fcntl(fd, op, &lock);
+ if (errno == EFBIG)
+ {
+ if (DEBUGLVL(0))
+ {
+ dbgtext
+ ("fcntl_lock: WARNING: lock request at offset %.0f, length %.0f returned\n",
+ (double)offset, (double)count);
+ dbgtext
+ ("a 'file too large' error. This can happen when using 64 bit lock offsets\n");
+ dbgtext
+ ("on 32 bit NFS mounted file systems. Retrying with 32 bit truncated length.\n");
+ }
+ /* 32 bit NFS file system, retry with smaller offset */
+ errno = 0;
+ lock.l_len = count & 0x7fffffff;
+ ret = fcntl(fd, op, &lock);
+ }
- /* perhaps it doesn't support this sort of locking?? */
- if (errno == EINVAL)
- {
- DEBUG(3,("locking not supported? returning True\n"));
- return(True);
- }
+ if (errno != 0)
+ DEBUG(3,
+ ("fcntl lock gave errno %d (%s)\n", errno,
+ strerror(errno)));
- return(False);
- }
+ /* a lock query */
+ if (op == SMB_F_GETLK)
+ {
+ if ((ret != -1) &&
+ (lock.l_type != F_UNLCK) &&
+ (lock.l_pid != 0) && (lock.l_pid != getpid()))
+ {
+ DEBUG(3,
+ ("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,
+ ("lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
+ (double)offset, (double)count, op, type,
+ strerror(errno)));
+
+ /* perhaps it doesn't support this sort of locking?? */
+ if (errno == EINVAL)
+ {
- /* everything went OK */
- DEBUG(8,("Lock call successful\n"));
+#if defined(LARGE_SMB_OFF_T)
+ {
+ /*
+ * Ok - if we get here then we have a 64 bit lock request
+ * that has returned EINVAL. Try and map to 31 bits for offset
+ * and length and try again. This may happen if a filesystem
+ * doesn't support 64 bit offsets (efs/ufs) although the underlying
+ * OS does.
+ */
+ uint32 off_low = (orig_offset & 0xFFFFFFFF);
+ uint32 off_high =
+ ((orig_offset >> 32) & 0xFFFFFFFF);
+
+ lock.l_len = (orig_count & 0x7FFFFFFF);
+ lock.l_start =
+ (SMB_OFF_T) map_lock_offset(off_high,
+ off_low);
+ ret = fcntl(fd, op, &lock);
+ if (ret == -1)
+ {
+ if (errno == EINVAL)
+ {
+ DEBUG(3,
+ ("locking not supported? returning True\n"));
+ return (True);
+ }
+ return False;
+ }
+ DEBUG(3,
+ ("64 -> 32 bit modified lock call successful\n"));
+ return True;
+ }
+#else /* LARGE_SMB_OFF_T */
+ DEBUG(3, ("locking not supported? returning True\n"));
+ return (True);
+#endif /* LARGE_SMB_OFF_T */
+ }
- return(True);
+ return (False);
+ }
+
+ /* everything went OK */
+ DEBUG(8, ("Lock call successful\n"));
+
+ return (True);
#else
- return(False);
+ return (False);
#endif
}
+
/***************************************************************
locks a file for enumeration / modification.
update to be set = True if modification is required.
return (void *)f;
}
+/*******************************************************************
+returns the size in bytes of the named file
+********************************************************************/
+SMB_OFF_T get_file_size(char *file_name)
+{
+ SMB_STRUCT_STAT buf;
+ buf.st_size = 0;
+ if (sys_stat(file_name, &buf) != 0)
+ return (SMB_OFF_T) - 1;
+ return (buf.st_size);
+}
+
#endif
#include <stdlib.h>
#include <stdio.h>
+#include <sys/types.h>
+#include <errno.h>
#ifdef HAVE_SYS_PRIV_H
#include <sys/priv.h>
****************************************************************************/
static void assert_uid(uid_t ruid, uid_t euid)
{
-#ifdef AUTOCONF_TEST
-#if (defined(USE_SETRESUID) || defined(USE_SETREUID) || \
- defined(USE_SETEUID) || defined(USE_SETUIDX))
- if ((euid != (uid_t) (-1) && geteuid() != euid) ||
- (ruid != (uid_t) (-1) && getuid() != ruid))
- {
- DEBUG(0,
- ("Failed to set uid privileges to (%d,%d) now set to (%d,%d)\n",
- (int)ruid, (int)euid, (int)getuid(), (int)geteuid()));
+ if ((euid != (uid_t)-1 && geteuid() != euid) ||
+ (ruid != (uid_t)-1 && getuid() != ruid)) {
+ DEBUG(0,("Failed to set uid privileges to (%d,%d) now set to (%d,%d)\n",
+ (int)ruid, (int)euid,
+ (int)getuid(), (int)geteuid()));
smb_panic("failed to set uid\n");
exit(1);
}
-#endif
-#endif
}
/****************************************************************************
****************************************************************************/
static void assert_gid(gid_t rgid, gid_t egid)
{
-#ifdef AUTOCONF_TEST
-#if (defined(USE_SETRESGID) || defined(USE_SETREGID) || \
- defined(USE_SETEGID) || defined(USE_SETGIDX))
- if ((egid != (gid_t) (-1) && getegid() != egid) ||
- (rgid != (gid_t) (-1) && getgid() != rgid))
- {
- DEBUG(0,
- ("Failed to set gid privileges to (%d,%d) now set to (%d,%d) uid=(%d,%d)\n",
- (int)rgid, (int)egid, (int)getgid(), (int)getegid(),
- (int)getuid(), (int)geteuid()));
+ if ((egid != (gid_t)-1 && getegid() != egid) ||
+ (rgid != (gid_t)-1 && getgid() != rgid)) {
+ DEBUG(0,("Failed to set gid privileges to (%d,%d) now set to (%d,%d) uid=(%d,%d)\n",
+ (int)rgid, (int)egid,
+ (int)getgid(), (int)getegid(),
+ (int)getuid(), (int)geteuid()));
smb_panic("failed to set gid\n");
exit(1);
}
-#endif
-#endif
}
/****************************************************************************
We want to end up with ruid==euid==0
****************************************************************************/
void gain_root_privilege(void)
-{
-#ifdef USE_SETRESUID
- setresuid(0, 0, 0);
+{
+#if USE_SETRESUID
+ setresuid(0,0,0);
#endif
-
-#ifdef USE_SETEUID
+
+#if USE_SETEUID
seteuid(0);
#endif
-#ifdef USE_SETREUID
+#if USE_SETREUID
setreuid(0, 0);
#endif
-#ifdef USE_SETUIDX
+#if USE_SETUIDX
setuidx(ID_EFFECTIVE, 0);
setuidx(ID_REAL, 0);
#endif
****************************************************************************/
void gain_root_group_privilege(void)
{
-#ifdef USE_SETRESGID
- setresgid(0, 0, 0);
+#if USE_SETRESUID
+ setresgid(0,0,0);
#endif
-#ifdef USE_SETREGID
- setregid(0, 0);
+#if USE_SETREUID
+ setregid(0,0);
#endif
-#ifdef USE_SETEGID
+#if USE_SETEUID
setegid(0);
#endif
-#ifdef USE_SETGIDX
+#if USE_SETUIDX
setgidx(ID_EFFECTIVE, 0);
setgidx(ID_REAL, 0);
#endif
****************************************************************************/
void set_effective_uid(uid_t uid)
{
-#ifdef USE_SETRESUID
- setresuid(-1, uid, -1);
+#if USE_SETRESUID
+ setresuid(-1,uid,-1);
#endif
-#ifdef USE_SETREUID
- setreuid(-1, uid);
+#if USE_SETREUID
+ setreuid(-1,uid);
#endif
-#ifdef USE_SETEUID
+#if USE_SETEUID
seteuid(uid);
#endif
-#ifdef USE_SETUIDX
+#if USE_SETUIDX
setuidx(ID_EFFECTIVE, uid);
#endif
****************************************************************************/
void set_effective_gid(gid_t gid)
{
-#ifdef USE_SETRESGID
- setresgid(-1, gid, -1);
+#if USE_SETRESUID
+ setresgid(-1,gid,-1);
#endif
-#ifdef USE_SETREGID
- setregid(-1, gid);
+#if USE_SETREUID
+ setregid(-1,gid);
#endif
-#ifdef USE_SETEGID
+#if USE_SETEUID
setegid(gid);
#endif
-#ifdef USE_SETGIDX
+#if USE_SETUIDX
setgidx(ID_EFFECTIVE, gid);
#endif
void restore_re_uid(void)
{
set_effective_uid(0);
+
+#if USE_SETRESUID
+ setresuid(saved_ruid, saved_euid, -1);
+#elif USE_SETREUID
+ setreuid(saved_ruid, -1);
+ setreuid(-1,saved_euid);
+#elif USE_SETUIDX
+ setuidx(ID_REAL, saved_ruid);
+ setuidx(ID_EFFECTIVE, saved_euid);
+#else
set_effective_uid(saved_euid);
if (getuid() != saved_ruid)
setuid(saved_ruid);
set_effective_uid(saved_euid);
+#endif
assert_uid(saved_ruid, saved_euid);
}
{
uid_t uid = geteuid();
-#ifdef USE_SETRESUID
+#if USE_SETRESUID
setresuid(geteuid(), -1, -1);
#endif
-#ifdef USE_SETREUID
+#if USE_SETREUID
setreuid(0, 0);
setreuid(uid, -1);
setreuid(-1, uid);
#endif
-#ifdef USE_SETEUID
+#if USE_SETEUID
/* can't be done */
return -1;
#endif
-#ifdef USE_SETUIDX
+#if USE_SETUIDX
/* can't be done */
return -1;
#endif
gain_root_privilege();
gain_root_group_privilege();
-#ifdef USE_SETRESGID
- setresgid(gid, gid, gid);
+#if USE_SETRESUID
+ setresgid(gid,gid,gid);
setgid(gid);
+ setresuid(uid,uid,uid);
+ setuid(uid);
#endif
-#ifdef USE_SETREGID
- setregid(gid, gid);
+#if USE_SETREUID
+ setregid(gid,gid);
setgid(gid);
+ setreuid(uid,uid);
+ setuid(uid);
#endif
-#ifdef USE_SETEGID
+#if USE_SETEUID
setegid(gid);
setgid(gid);
+ setuid(uid);
+ seteuid(uid);
+ setuid(uid);
#endif
-#ifdef USE_SETGIDX
+#if USE_SETUIDX
setgidx(ID_REAL, gid);
setgidx(ID_EFFECTIVE, gid);
setgid(gid);
+ setuidx(ID_REAL, uid);
+ setuidx(ID_EFFECTIVE, uid);
+ setuid(uid);
#endif
+
+ assert_uid(uid, uid);
+ assert_gid(gid, gid);
+}
-#ifdef USE_SETRESUID
- setresuid(uid, uid, uid);
- setuid(uid);
+
+#ifdef AUTOCONF_TEST
+/****************************************************************************
+this function just checks that we don't get ENOSYS back
+****************************************************************************/
+static int have_syscall(void)
+{
+ errno = 0;
+
+#if USE_SETRESUID
+ setresuid(-1,-1,-1);
#endif
-#ifdef USE_SETREUID
- setreuid(uid, uid);
- setuid(uid);
+#if USE_SETREUID
+ setreuid(-1,-1);
#endif
-#ifdef USE_SETEUID
- setuid(uid);
- seteuid(uid);
- setuid(uid);
+#if USE_SETEUID
+ seteuid(-1);
#endif
-#ifdef USE_SETUIDX
- setuidx(ID_REAL, uid);
- setuidx(ID_EFFECTIVE, uid);
- setuid(uid);
+#if USE_SETUIDX
+ setuidx(ID_EFFECTIVE, -1);
#endif
- assert_uid(uid, uid);
- assert_gid(gid, gid);
+ if (errno == ENOSYS) return -1;
+
+ return 0;
}
-#ifdef AUTOCONF_TEST
main()
{
- if (getuid() != 0)
- {
+ if (getuid() != 0) {
#if (defined(AIX) && defined(USE_SETREUID))
/* setreuid is badly broken on AIX 4.1, we avoid it completely */
- fprintf(stderr, "avoiding possibly broken setreuid\n");
+ fprintf(stderr,"avoiding possibly broken setreuid\n");
exit(1);
#endif
- /* assume that if we have the functions then they work */
- fprintf(stderr, "not running as root: assuming OK\n");
- exit(0);
+ /* if not running as root then at least check to see if we get ENOSYS - this
+ handles Linux 2.0.x with glibc 2.1 */
+ fprintf(stderr,"not running as root: checking for ENOSYS\n");
+ exit(have_syscall());
}
gain_root_privilege();
gain_root_group_privilege();
set_effective_gid(1);
set_effective_uid(1);
+ save_re_uid();
+ restore_re_uid();
gain_root_privilege();
gain_root_group_privilege();
become_user_permanently(1, 1);
-#if (defined(USE_SETRESUID) || defined(USE_SETREUID) || \
- defined(USE_SETEUID) || defined(USE_SETUIDX))
setuid(0);
- if (getuid() == 0)
- {
- fprintf(stderr, "uid not set permanently\n");
+ if (getuid() == 0) {
+ fprintf(stderr,"uid not set permanently\n");
exit(1);
}
-#endif
-
-#if (defined(USE_SETRESGID) || defined(USE_SETREGID) || \
- defined(USE_SETEGID) || defined(USE_SETGIDX))
- setgid(0);
- if (getgid() == 0)
- {
- fprintf(stderr, "gid not set permanently\n");
- exit(1);
- }
-#endif
printf("OK\n");
int option;
int value;
int opttype;
-}
-socket_options[] =
+} socket_options[] =
{
{
"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL}
int on = socket_options[i].value;
ret =
setsockopt(fd,
- socket_options[i].
- level,
- socket_options[i].
- option,
+ socket_options
+ [i].level,
+ socket_options
+ [i].option,
(char *)&on,
sizeof(int));
}
int socklen;
socklen = sizeof(sock);
- memset((char *)&sock, 0, socklen);
+ memset((char *)&sock, 0, socklen);
ZERO_STRUCT(lastip);
ret =
(ssize_t) recvfrom(fd, buf, len, 0, (struct sockaddr *)&sock,
smb_read_error = 0;
- memset(buffer, 0, smb_size + 100);
+ memset(buffer, 0, smb_size + 100);
len = read_smb_length_return_keepalive(fd, buffer, timeout);
if (len < 0)
if (getpeername(fd, &sa, &length) < 0)
{
- DEBUG(0,
- ("getpeername failed. Error was %s\n",
- strerror(errno)));
+ DEBUG(0, ("getpeername failed. Error was %s\n",
+ strerror(errno)));
return client_addr_buf;
}
if (connect(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0)
{
- DEBUG(1, ("socket connect to %s failed: %s\n",
+ DEBUG(2, ("socket connect to %s failed: %s\n",
sa.sun_path, strerror(errno)));
close(sock);
return -1;
else
#endif /* KANJI_WIN95_COMPATIBILITY */
{
- size_t skip = skip_multibyte_char( *s );
+ size_t skip = get_character_len( *s );
if( skip != 0 )
s += skip;
else
else
#endif /* KANJI_WIN95_COMPATIBILITY */
{
- size_t skip = skip_multibyte_char( *s );
+ size_t skip = get_character_len( *s );
if( skip != 0 )
s += skip;
else
void string_replace(char *s,char oldc,char newc)
{
size_t skip;
+
+ /*
+ * sbcs optimization.
+ */
+ if(!global_is_multibyte_codepage) {
+ while (*s) {
+ if (oldc == *s)
+ *s = newc;
+ s++;
+ }
+ } else {
while (*s)
{
- skip = skip_multibyte_char( *s );
+ skip = get_character_len( *s );
if( skip != 0 )
s += skip;
else
}
}
}
+}
/*******************************************************************
{
while (n--)
buf += strlen(buf) + 1;
- return buf;
+ return(buf);
}
/*******************************************************************
{
size_t len = 0;
+ /*
+ * sbcs optimization.
+ */
+ if(!global_is_multibyte_codepage) {
+ return strlen(s);
+ } else {
while (*s != '\0') {
- int skip = skip_multibyte_char(*s);
+ int skip = get_character_len(*s);
s += (skip ? skip : 1);
len++;
}
+ }
return len;
}
if(back_len)
{
- if(!is_multibyte_codepage())
+ if(!global_is_multibyte_codepage)
{
s_len = strlen(s);
while ((s_len >= back_len) &&
size_t charcount = 0;
char *mbp = s;
- while(charcount < (mb_s_len - mb_back_len))
- {
+ /*
+ * sbcs optimization.
+ */
+ if(!global_is_multibyte_codepage) {
+ while(charcount < (mb_s_len - mb_back_len)) {
+ mbp += 1;
+ charcount++;
+ }
+ } else {
+ while(charcount < (mb_s_len - mb_back_len)) {
size_t skip = skip_multibyte_char(*mbp);
mbp += (skip ? skip : 1);
charcount++;
}
+ }
/*
* mbp now points at mb_back_len multibyte
else
#endif /* KANJI_WIN95_COMPATIBILITY */
{
- size_t skip = skip_multibyte_char( *s );
+ size_t skip = get_character_len( *s );
if( skip != 0 )
s += skip;
else {
else
#endif /* KANJI_WIN95_COMPATIBILITY */
{
- size_t skip = skip_multibyte_char( *s );
+ size_t skip = get_character_len( *s );
if( skip != 0 )
s += skip;
else {
{
while (*s)
{
- size_t skip = skip_multibyte_char( *s );
+ size_t skip = get_character_len( *s );
if( skip != 0 )
s += skip;
else {
return(count);
}
+/*******************************************************************
+Return True if a string consists only of one particular character.
+********************************************************************/
+
+BOOL str_is_all(const char *s,char c)
+{
+ if(s == NULL)
+ return False;
+ if(!*s)
+ return False;
+
+#if !defined(KANJI_WIN95_COMPATIBILITY)
+ /*
+ * For completeness we should put in equivalent code for code pages
+ * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+ * doubt anyone wants Samba to behave differently from Win95 and WinNT
+ * here. They both treat full width ascii characters as case senstive
+ * filenames (ie. they don't do the work we do here).
+ * JRA.
+ */
+ if(lp_client_code_page() == KANJI_CODEPAGE)
+ {
+ /* Win95 treats full width ascii characters as case sensitive. */
+ while (*s)
+ {
+ if (is_shift_jis (*s))
+ s += 2;
+ else
+ {
+ if (*s != c)
+ return False;
+ s++;
+ }
+ }
+ }
+ else
+#endif /* KANJI_WIN95_COMPATIBILITY */
+ {
+ while (*s)
+ {
+ size_t skip = get_character_len( *s );
+ if( skip != 0 )
+ s += skip;
+ else {
+ if (*s != c)
+ return False;
+ s++;
+ }
+ }
+ }
+ return True;
+}
/*******************************************************************
safe string copy into a known length string. maxlength does not
{
size_t len;
- if (maxlength == 0)
- {
- return dest;
- }
-
if (!dest) {
DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
return NULL;
if (len > maxlength) {
DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
- len-maxlength, src));
+ (int)(len-maxlength), src));
len = maxlength;
}
if (src_len + dest_len > maxlength) {
DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
- src_len + dest_len - maxlength, src));
+ (int)(src_len + dest_len - maxlength), src));
src_len = maxlength - dest_len;
}
return dest;
}
-/****************************************************************************
-this is a safer strcpy(), meant to prevent core dumps when nasty things happen
-****************************************************************************/
-char *StrCpy(char *dest,const char *src)
+/*******************************************************************
+ Paranoid strcpy into a buffer of given length (includes terminating
+ zero. Strips out all but 'a-Z0-9' and replaces with '_'. Deliberately
+ does *NOT* check for multibyte characters. Don't change it !
+********************************************************************/
+
+char *alpha_strcpy(char *dest, const char *src, size_t maxlength)
{
- char *d = dest;
+ size_t len, i;
- /* I don't want to get lazy with these ... */
- SMB_ASSERT(dest && src);
+ if (!dest) {
+ DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
+ return NULL;
+ }
- if (!dest) return(NULL);
if (!src) {
*dest = 0;
- return(dest);
+ return dest;
}
- while ((*d++ = *src++)) ;
- return(dest);
+
+ len = strlen(src);
+ if (len >= maxlength)
+ len = maxlength - 1;
+
+ for(i = 0; i < len; i++) {
+ int val = (src[i] & 0xff);
+ if(isupper(val) ||islower(val) || isdigit(val))
+ dest[i] = src[i];
+ else
+ dest[i] = '_';
+ }
+
+ dest[i] = '\0';
+
+ return dest;
}
/****************************************************************************
-like strncpy but always null terminates. Make sure there is room!
+ 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)
{
like strncpy but copies up to the character marker. always null terminates.
returns a pointer to the character marker in the source string (src).
****************************************************************************/
-char *strncpyn(char *dest, char *src,size_t n, char c)
+char *strncpyn(char *dest, const char *src,size_t n, char c)
{
char *p;
size_t str_len;
/****************************************************************************
set a string value, allocing the space for the string
****************************************************************************/
-BOOL string_init(char **dest,const char *src)
+static BOOL string_init(char **dest,const char *src)
{
size_t l;
if (!src)
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 _
+any of " ; ' $ or ` in the insert string are replaced with _
+if len==0 then no length check is performed
****************************************************************************/
-void string_sub(char *s,const char *pattern,const char *insert)
+void string_sub(char *s,const char *pattern,const char *insert, size_t len)
{
char *p;
- size_t ls,lp,li, i;
+ ssize_t ls,lp,li, i;
if (!insert || !pattern || !s) return;
- ls = strlen(s);
- lp = strlen(pattern);
- li = strlen(insert);
+ ls = (ssize_t)strlen(s);
+ lp = (ssize_t)strlen(pattern);
+ li = (ssize_t)strlen(insert);
if (!*pattern) return;
while (lp <= ls && (p = strstr(s,pattern))) {
- memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
+ if (len && (ls + (li-lp) >= len)) {
+ DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
+ (int)(ls + (li-lp) - len),
+ pattern, (int)len));
+ break;
+ }
+ if (li != lp) {
+ memmove(p+li,p+lp,strlen(p+lp)+1);
+ }
for (i=0;i<li;i++) {
switch (insert[i]) {
case '`':
case '"':
case '\'':
case ';':
+ case '$':
+ case '%':
+ case '\r':
+ case '\n':
p[i] = '_';
break;
default:
}
}
+void fstring_sub(char *s,const char *pattern,const char *insert)
+{
+ string_sub(s, pattern, insert, sizeof(fstring));
+}
+
+void pstring_sub(char *s,const char *pattern,const char *insert)
+{
+ string_sub(s, pattern, insert, sizeof(pstring));
+}
/****************************************************************************
similar to string_sub() but allows for any character to be substituted.
return NULL;
}
+/****************************************************************************
+write an octal as a string
+****************************************************************************/
+char *octal_string(int i)
+{
+ static char ret[64];
+ if (i == -1) {
+ return "-1";
+ }
+ slprintf(ret, sizeof(ret), "0%o", i);
+ return ret;
+}
+
+
/****************************************************************************
truncate a string at a specified length
****************************************************************************/
extern int DEBUGLEVEL;
-/*******************************************************************
- Write a string in (little-endian) unicode format. src is in
- the current DOS codepage. len is the length in bytes of the
- string pointed to by dst.
-
- the return value is the length of the string *without* the trailing
- two bytes of zero
-********************************************************************/
-
-int dos_PutUniCode(char *dst,const char *src, ssize_t len, BOOL null_terminate)
-{
- char *end = ascii_to_unibuf(dst, src, len);
- return PTR_DIFF(end, dst) - (null_terminate ? 0 : 2);
-}
-
/*******************************************************************
Put an ASCII string into a UNICODE buffer (little endian).
********************************************************************/
/*******************************************************************
Convert a UNISTR2 structure to an ASCII string
********************************************************************/
-
char *unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
{
char *destend;
--- /dev/null
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Samba utility functions
+ 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"
+
+extern int DEBUGLEVEL;
+
+ smb_ucs2_t wchar_list_sep[] = { (smb_ucs2_t)' ', (smb_ucs2_t)'\t', (smb_ucs2_t)',',
+ (smb_ucs2_t)';', (smb_ucs2_t)':', (smb_ucs2_t)'\n',
+ (smb_ucs2_t)'\r', 0 };
+/*
+ * The following are the codepage to ucs2 and vica versa maps.
+ * These are dynamically loaded from a unicode translation file.
+ */
+
+static smb_ucs2_t *doscp_to_ucs2;
+static uint16 *ucs2_to_doscp;
+
+static smb_ucs2_t *unixcp_to_ucs2;
+static uint16 *ucs2_to_unixcp;
+
+/*******************************************************************
+ Write a string in (little-endian) unicode format. src is in
+ the current DOS codepage. len is the length in bytes of the
+ string pointed to by dst.
+
+ if null_terminate is True then null terminate the packet (adds 2 bytes)
+
+ the return value is the length consumed by the string, including the
+ null termination if applied
+********************************************************************/
+
+int dos_PutUniCode(char *dst,const char *src, ssize_t len, BOOL null_terminate)
+{
+ int ret = 0;
+ while (*src && (len > 2)) {
+ size_t skip = get_character_len(*src);
+ smb_ucs2_t val = (*src & 0xff);
+
+ /*
+ * If this is a multibyte character (and all DOS/Windows
+ * codepages have at maximum 2 byte multibyte characters)
+ * then work out the index value for the unicode conversion.
+ */
+
+ if (skip == 2)
+ val = ((val << 8) | (src[1] & 0xff));
+
+ SSVAL(dst,ret,doscp_to_ucs2[val]);
+ ret += 2;
+ len -= 2;
+ if (skip)
+ src += skip;
+ else
+ src++;
+ }
+ if (null_terminate) {
+ SSVAL(dst,ret,0);
+ ret += 2;
+ }
+ return(ret);
+}
+
+#ifndef MAXUNI
+#define MAXUNI 1024
+#endif
+
+/*******************************************************************
+ Return a DOS codepage version of a little-endian unicode string.
+ len is the filename length (ignoring any terminating zero) in uin16
+ units. Always null terminates.
+ Hack alert: uses fixed buffer(s).
+********************************************************************/
+
+char *dos_unistrn2(uint16 *src, int len)
+{
+ static char lbufs[8][MAXUNI];
+ static int nexti;
+ char *lbuf = lbufs[nexti];
+ char *p;
+
+ nexti = (nexti+1)%8;
+
+ for (p = lbuf; (len > 0) && (p-lbuf < MAXUNI-3) && *src; len--, src++) {
+ uint16 ucs2_val = SVAL(src,0);
+ uint16 cp_val = ucs2_to_doscp[ucs2_val];
+
+ if (cp_val < 256)
+ *p++ = (char)cp_val;
+ else {
+ *p++ = (cp_val >> 8) & 0xff;
+ *p++ = (cp_val & 0xff);
+ }
+ }
+
+ *p = 0;
+ return lbuf;
+}
+
+static char lbufs[8][MAXUNI];
+static int nexti;
+
+/*******************************************************************
+ Return a DOS codepage version of a little-endian unicode string.
+ Hack alert: uses fixed buffer(s).
+********************************************************************/
+
+char *dos_unistr2(uint16 *src)
+{
+ char *lbuf = lbufs[nexti];
+ char *p;
+
+ nexti = (nexti+1)%8;
+
+ for (p = lbuf; *src && (p-lbuf < MAXUNI-3); src++) {
+ uint16 ucs2_val = SVAL(src,0);
+ uint16 cp_val = ucs2_to_doscp[ucs2_val];
+
+ if (cp_val < 256)
+ *p++ = (char)cp_val;
+ else {
+ *p++ = (cp_val >> 8) & 0xff;
+ *p++ = (cp_val & 0xff);
+ }
+ }
+
+ *p = 0;
+ return lbuf;
+}
+
+/*******************************************************************
+Return a DOS codepage version of a little-endian unicode string
+********************************************************************/
+
+char *dos_unistr2_to_str(UNISTR2 *str)
+{
+ char *lbuf = lbufs[nexti];
+ char *p;
+ uint16 *src = str->buffer;
+ int max_size = MIN(sizeof(str->buffer)-3, str->uni_str_len);
+
+ nexti = (nexti+1)%8;
+
+ for (p = lbuf; *src && p-lbuf < max_size; src++) {
+ uint16 ucs2_val = SVAL(src,0);
+ uint16 cp_val = ucs2_to_doscp[ucs2_val];
+
+ if (cp_val < 256)
+ *p++ = (char)cp_val;
+ else {
+ *p++ = (cp_val >> 8) & 0xff;
+ *p++ = (cp_val & 0xff);
+ }
+ }
+
+ *p = 0;
+ return lbuf;
+}
+
+/*******************************************************************
+ Convert a UNISTR2 structure to an ASCII string
+ Warning: this version does DOS codepage.
+********************************************************************/
+#if 0
+ void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
+{
+ char *destend;
+ const uint16 *src;
+ size_t len;
+ register uint16 c;
+
+ src = str->buffer;
+ len = MIN(str->uni_str_len, maxlen);
+ destend = dest + len;
+
+ while (dest < destend)
+ {
+ uint16 ucs2_val;
+ uint16 cp_val;
+
+ c = *src;
+ if (c == 0)
+ {
+ break;
+ }
+
+ ucs2_val = SVAL(src++,0);
+ cp_val = ucs2_to_doscp[ucs2_val];
+
+ if (cp_val < 256)
+ *(dest++) = (char)cp_val;
+ else {
+ *dest= (cp_val >> 8) & 0xff;
+ *(dest++) = (cp_val & 0xff);
+ }
+ }
+
+ *dest = 0;
+}
+#endif
+/*******************************************************************
+Return a DOS codepage version of a NOTunicode string
+********************************************************************/
+
+char *dos_buffer2_to_str(BUFFER2 *str)
+{
+ char *lbuf = lbufs[nexti];
+ char *p;
+ uint16 *src = str->buffer;
+ int max_size = MIN(sizeof(str->buffer)-3, str->buf_len/2);
+
+ nexti = (nexti+1)%8;
+
+ for (p = lbuf; *src && p-lbuf < max_size; src++) {
+ uint16 ucs2_val = SVAL(src,0);
+ uint16 cp_val = ucs2_to_doscp[ucs2_val];
+
+ if (cp_val < 256)
+ *p++ = (char)cp_val;
+ else {
+ *p++ = (cp_val >> 8) & 0xff;
+ *p++ = (cp_val & 0xff);
+ }
+ }
+
+ *p = 0;
+ return lbuf;
+}
+
+/*******************************************************************
+ Return a dos codepage version of a NOTunicode string
+********************************************************************/
+
+char *dos_buffer2_to_multistr(BUFFER2 *str)
+{
+ char *lbuf = lbufs[nexti];
+ char *p;
+ uint16 *src = str->buffer;
+ int max_size = MIN(sizeof(str->buffer)-3, str->buf_len/2);
+
+ nexti = (nexti+1)%8;
+
+ for (p = lbuf; p-lbuf < max_size; src++) {
+ if (*src == 0) {
+ *p++ = ' ';
+ } else {
+ uint16 ucs2_val = SVAL(src,0);
+ uint16 cp_val = ucs2_to_doscp[ucs2_val];
+
+ if (cp_val < 256)
+ *p++ = (char)cp_val;
+ else {
+ *p++ = (cp_val >> 8) & 0xff;
+ *p++ = (cp_val & 0xff);
+ }
+ }
+ }
+
+ *p = 0;
+ return lbuf;
+}
+
+/*******************************************************************
+ Create a null-terminated unicode string from a null-terminated DOS
+ codepage string.
+ Return number of unicode chars copied, excluding the null character.
+ Unicode strings created are in little-endian format.
+********************************************************************/
+
+size_t dos_struni2(char *dst, const char *src, size_t max_len)
+{
+ size_t len = 0;
+
+ if (dst == NULL)
+ return 0;
+
+ if (src != NULL) {
+ for (; *src && len < max_len-2; len++, dst +=2) {
+ size_t skip = get_character_len(*src);
+ smb_ucs2_t val = (*src & 0xff);
+
+ /*
+ * If this is a multibyte character (and all DOS/Windows
+ * codepages have at maximum 2 byte multibyte characters)
+ * then work out the index value for the unicode conversion.
+ */
+
+ if (skip == 2)
+ val = ((val << 8) | (src[1] & 0xff));
+
+ SSVAL(dst,0,doscp_to_ucs2[val]);
+ if (skip)
+ src += skip;
+ else
+ src++;
+ }
+ }
+
+ SSVAL(dst,0,0);
+
+ return len;
+}
+
+/*******************************************************************
+ Return a DOS codepage version of a little-endian unicode string.
+ Hack alert: uses fixed buffer(s).
+********************************************************************/
+
+char *dos_unistr(char *buf)
+{
+ char *lbuf = lbufs[nexti];
+ uint16 *src = (uint16 *)buf;
+ char *p;
+
+ nexti = (nexti+1)%8;
+
+ for (p = lbuf; *src && p-lbuf < MAXUNI-3; src++) {
+ uint16 ucs2_val = SVAL(src,0);
+ uint16 cp_val = ucs2_to_doscp[ucs2_val];
+
+ if (cp_val < 256)
+ *p++ = (char)cp_val;
+ else {
+ *p++ = (cp_val >> 8) & 0xff;
+ *p++ = (cp_val & 0xff);
+ }
+ }
+
+ *p = 0;
+ return lbuf;
+}
+
+/*******************************************************************
+ Free any existing maps.
+********************************************************************/
+
+static void free_maps(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
+{
+ /* this handles identity mappings where we share the pointer */
+ if (*pp_ucs2_to_cp == *pp_cp_to_ucs2) {
+ *pp_ucs2_to_cp = NULL;
+ }
+
+ if (*pp_cp_to_ucs2) {
+ free(*pp_cp_to_ucs2);
+ *pp_cp_to_ucs2 = NULL;
+ }
+
+ if (*pp_ucs2_to_cp) {
+ free(*pp_ucs2_to_cp);
+ *pp_ucs2_to_cp = NULL;
+ }
+}
+
+
+/*******************************************************************
+ Build a default (null) codepage to unicode map.
+********************************************************************/
+
+void default_unicode_map(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
+{
+ int i;
+
+ free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
+
+ if ((*pp_ucs2_to_cp = (uint16 *)malloc(2*65536)) == NULL) {
+ DEBUG(0,("default_unicode_map: malloc fail for ucs2_to_cp size %u.\n", 2*65536));
+ abort();
+ }
+
+ *pp_cp_to_ucs2 = *pp_ucs2_to_cp; /* Default map is an identity. */
+ for (i = 0; i < 65536; i++)
+ (*pp_cp_to_ucs2)[i] = i;
+}
+
+/*******************************************************************
+ Load a codepage to unicode and vica-versa map.
+********************************************************************/
+
+BOOL load_unicode_map(const char *codepage, smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
+{
+ pstring unicode_map_file_name;
+ FILE *fp = NULL;
+ SMB_STRUCT_STAT st;
+ smb_ucs2_t *cp_to_ucs2 = *pp_cp_to_ucs2;
+ uint16 *ucs2_to_cp = *pp_ucs2_to_cp;
+ size_t cp_to_ucs2_size;
+ size_t ucs2_to_cp_size;
+ size_t i;
+ size_t size;
+ char buf[UNICODE_MAP_HEADER_SIZE];
+
+ DEBUG(5, ("load_unicode_map: loading unicode map for codepage %s.\n", codepage));
+
+ if (*codepage == '\0')
+ goto clean_and_exit;
+
+ if(strlen(CODEPAGEDIR) + 13 + strlen(codepage) > sizeof(unicode_map_file_name)) {
+ DEBUG(0,("load_unicode_map: filename too long to load\n"));
+ goto clean_and_exit;
+ }
+
+ pstrcpy(unicode_map_file_name, CODEPAGEDIR);
+ pstrcat(unicode_map_file_name, "/");
+ pstrcat(unicode_map_file_name, "unicode_map.");
+ pstrcat(unicode_map_file_name, codepage);
+
+ if(sys_stat(unicode_map_file_name,&st)!=0) {
+ DEBUG(0,("load_unicode_map: filename %s does not exist.\n",
+ unicode_map_file_name));
+ goto clean_and_exit;
+ }
+
+ size = st.st_size;
+
+ if ((size != UNICODE_MAP_HEADER_SIZE + 4*65536) && (size != UNICODE_MAP_HEADER_SIZE +(2*256 + 2*65536))) {
+ DEBUG(0,("load_unicode_map: file %s is an incorrect size for a \
+unicode map file (size=%d).\n", unicode_map_file_name, (int)size));
+ goto clean_and_exit;
+ }
+
+ if((fp = sys_fopen( unicode_map_file_name, "r")) == NULL) {
+ DEBUG(0,("load_unicode_map: cannot open file %s. Error was %s\n",
+ unicode_map_file_name, strerror(errno)));
+ goto clean_and_exit;
+ }
+
+ if(fread( buf, 1, UNICODE_MAP_HEADER_SIZE, fp)!=UNICODE_MAP_HEADER_SIZE) {
+ DEBUG(0,("load_unicode_map: cannot read header from file %s. Error was %s\n",
+ unicode_map_file_name, strerror(errno)));
+ goto clean_and_exit;
+ }
+
+ /* Check the version value */
+ if(SVAL(buf,UNICODE_MAP_VERSION_OFFSET) != UNICODE_MAP_FILE_VERSION_ID) {
+ DEBUG(0,("load_unicode_map: filename %s has incorrect version id. \
+Needed %hu, got %hu.\n",
+ unicode_map_file_name, (uint16)UNICODE_MAP_FILE_VERSION_ID,
+ SVAL(buf,UNICODE_MAP_VERSION_OFFSET)));
+ goto clean_and_exit;
+ }
+
+ /* Check the codepage value */
+ if(!strequal(&buf[UNICODE_MAP_CLIENT_CODEPAGE_OFFSET], codepage)) {
+ DEBUG(0,("load_unicode_map: codepage %s in file %s is not the same as that \
+requested (%s).\n", &buf[UNICODE_MAP_CLIENT_CODEPAGE_OFFSET], unicode_map_file_name, codepage ));
+ goto clean_and_exit;
+ }
+
+ ucs2_to_cp_size = 2*65536;
+ if (size == UNICODE_MAP_HEADER_SIZE + 4*65536) {
+ /*
+ * This is a multibyte code page.
+ */
+ cp_to_ucs2_size = 2*65536;
+ } else {
+ /*
+ * Single byte code page.
+ */
+ cp_to_ucs2_size = 2*256;
+ }
+
+ /*
+ * Free any old translation tables.
+ */
+
+ free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
+
+ if ((cp_to_ucs2 = (smb_ucs2_t *)malloc(cp_to_ucs2_size)) == NULL) {
+ DEBUG(0,("load_unicode_map: malloc fail for cp_to_ucs2 size %u.\n", cp_to_ucs2_size ));
+ goto clean_and_exit;
+ }
+
+ if ((ucs2_to_cp = (uint16 *)malloc(ucs2_to_cp_size)) == NULL) {
+ DEBUG(0,("load_unicode_map: malloc fail for ucs2_to_cp size %u.\n", ucs2_to_cp_size ));
+ goto clean_and_exit;
+ }
+
+ if(fread( (char *)cp_to_ucs2, 1, cp_to_ucs2_size, fp)!=cp_to_ucs2_size) {
+ DEBUG(0,("load_unicode_map: cannot read cp_to_ucs2 from file %s. Error was %s\n",
+ unicode_map_file_name, strerror(errno)));
+ goto clean_and_exit;
+ }
+
+ if(fread( (char *)ucs2_to_cp, 1, ucs2_to_cp_size, fp)!=ucs2_to_cp_size) {
+ DEBUG(0,("load_unicode_map: cannot read ucs2_to_cp from file %s. Error was %s\n",
+ unicode_map_file_name, strerror(errno)));
+ goto clean_and_exit;
+ }
+
+ /*
+ * Now ensure the 16 bit values are in the correct endianness.
+ */
+
+ for (i = 0; i < cp_to_ucs2_size/2; i++)
+ cp_to_ucs2[i] = SVAL(cp_to_ucs2,i*2);
+
+ for (i = 0; i < ucs2_to_cp_size/2; i++)
+ ucs2_to_cp[i] = SVAL(ucs2_to_cp,i*2);
+
+ fclose(fp);
+
+ *pp_cp_to_ucs2 = cp_to_ucs2;
+ *pp_ucs2_to_cp = ucs2_to_cp;
+
+ return True;
+
+clean_and_exit:
+
+ /* pseudo destructor :-) */
+
+ if(fp != NULL)
+ fclose(fp);
+
+ free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
+
+ default_unicode_map(pp_cp_to_ucs2, pp_ucs2_to_cp);
+
+ return False;
+}
+
+/*******************************************************************
+ Load a dos codepage to unicode and vica-versa map.
+********************************************************************/
+
+BOOL load_dos_unicode_map(int codepage)
+{
+ fstring codepage_str;
+
+ slprintf(codepage_str, sizeof(fstring)-1, "%03d", codepage);
+ return load_unicode_map(codepage_str, &doscp_to_ucs2, &ucs2_to_doscp);
+}
+
+/*******************************************************************
+ Load a UNIX codepage to unicode and vica-versa map.
+********************************************************************/
+
+BOOL load_unix_unicode_map(const char *unix_char_set)
+{
+ fstring upper_unix_char_set;
+
+ fstrcpy(upper_unix_char_set, unix_char_set);
+ strupper(upper_unix_char_set);
+ return load_unicode_map(upper_unix_char_set, &unixcp_to_ucs2, &ucs2_to_unixcp);
+}
+
+/*******************************************************************
+ The following functions reproduce many of the non-UNICODE standard
+ string functions in Samba.
+********************************************************************/
+
+/*******************************************************************
+ Convert a UNICODE string to multibyte format. Note that the 'src' is in
+ native byte order, not little endian. Always zero terminates.
+ dst_len is in bytes.
+********************************************************************/
+
+static char *unicode_to_multibyte(char *dst, const smb_ucs2_t *src,
+ size_t dst_len, const uint16 *ucs2_to_cp)
+{
+ size_t dst_pos;
+
+ for(dst_pos = 0; *src && (dst_pos < dst_len - 1);) {
+ smb_ucs2_t val = ucs2_to_cp[*src++];
+ if(val < 256) {
+ dst[dst_pos++] = (char)val;
+ } else {
+
+ if(dst_pos >= dst_len - 2)
+ break;
+
+ /*
+ * A 2 byte value is always written as
+ * high/low into the buffer stream.
+ */
+
+ dst[dst_pos++] = (char)((val >> 8) & 0xff);
+ dst[dst_pos++] = (char)(val & 0xff);
+ }
+ }
+
+ dst[dst_pos] = '\0';
+
+ return dst;
+}
+
+/*******************************************************************
+ Convert a multibyte string to UNICODE format. Note that the 'dst' is in
+ native byte order, not little endian. Always zero terminates.
+ dst_len is in bytes.
+********************************************************************/
+
+smb_ucs2_t *multibyte_to_unicode(smb_ucs2_t *dst, const char *src,
+ size_t dst_len, smb_ucs2_t *cp_to_ucs2)
+{
+ size_t i;
+
+ dst_len /= sizeof(smb_ucs2_t); /* Convert to smb_ucs2_t units. */
+
+ for(i = 0; (i < (dst_len - 1)) && src[i];) {
+ size_t skip = skip_multibyte_char(*src);
+ smb_ucs2_t val = (*src & 0xff);
+
+ /*
+ * If this is a multibyte character
+ * then work out the index value for the unicode conversion.
+ */
+
+ if (skip == 2)
+ val = ((val << 8) | (src[1] & 0xff));
+
+ dst[i++] = cp_to_ucs2[val];
+ if (skip)
+ src += skip;
+ else
+ src++;
+ }
+
+ dst[i] = 0;
+
+ return dst;
+}
+
+/*******************************************************************
+ Convert a UNICODE string to multibyte format. Note that the 'src' is in
+ native byte order, not little endian. Always zero terminates.
+ This function may be replaced if the MB codepage format is an
+ encoded one (ie. utf8, hex). See the code in lib/kanji.c
+ for details. dst_len is in bytes.
+********************************************************************/
+
+char *unicode_to_unix(char *dst, const smb_ucs2_t *src, size_t dst_len)
+{
+ return unicode_to_multibyte(dst, src, dst_len, ucs2_to_unixcp);
+}
+
+/*******************************************************************
+ Convert a UNIX string to UNICODE format. Note that the 'dst' is in
+ native byte order, not little endian. Always zero terminates.
+ This function may be replaced if the UNIX codepage format is a
+ multi-byte one (ie. JIS, SJIS or utf8). See the code in lib/kanji.c
+ for details. dst_len is in bytes, not ucs2 units.
+********************************************************************/
+
+smb_ucs2_t *unix_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len)
+{
+ return multibyte_to_unicode(dst, src, dst_len, unixcp_to_ucs2);
+}
+
+/*******************************************************************
+ Convert a UNICODE string to DOS format. Note that the 'src' is in
+ native byte order, not little endian. Always zero terminates.
+ dst_len is in bytes.
+********************************************************************/
+
+char *unicode_to_dos(char *dst, const smb_ucs2_t *src, size_t dst_len)
+{
+ return unicode_to_multibyte(dst, src, dst_len, ucs2_to_doscp);
+}
+
+/*******************************************************************
+ Convert a DOS string to UNICODE format. Note that the 'dst' is in
+ native byte order, not little endian. Always zero terminates.
+ This function may be replaced if the DOS codepage format is a
+ multi-byte one (ie. JIS, SJIS or utf8). See the code in lib/kanji.c
+ for details. dst_len is in bytes, not ucs2 units.
+********************************************************************/
+
+smb_ucs2_t *dos_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len)
+{
+ return multibyte_to_unicode(dst, src, dst_len, doscp_to_ucs2);
+}
+
+/*******************************************************************
+ Count the number of characters in a smb_ucs2_t string.
+********************************************************************/
+
+size_t strlen_w(const smb_ucs2_t *src)
+{
+ size_t len;
+
+ for(len = 0; *src; len++)
+ ;
+
+ return len;
+}
+
+/*******************************************************************
+ Safe wstring copy into a known length string. maxlength includes
+ the terminating zero. maxlength is in ucs2 units.
+********************************************************************/
+
+smb_ucs2_t *safe_strcpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src, size_t maxlength)
+{
+ size_t ucs2_len;
+
+ if (!dest) {
+ DEBUG(0,("ERROR: NULL dest in safe_strcpy_w\n"));
+ return NULL;
+ }
+
+ if (!src) {
+ *dest = 0;
+ return dest;
+ }
+
+ maxlength /= sizeof(smb_ucs2_t);
+
+ ucs2_len = strlen_w(src);
+
+ if (ucs2_len >= maxlength) {
+ fstring out;
+ DEBUG(0,("ERROR: string overflow by %u bytes in safe_strcpy_w [%.50s]\n",
+ (unsigned int)((ucs2_len-maxlength)*sizeof(smb_ucs2_t)),
+ unicode_to_unix(out,src,sizeof(out))) );
+ ucs2_len = maxlength - 1;
+ }
+
+ memcpy(dest, src, ucs2_len*sizeof(smb_ucs2_t));
+ dest[ucs2_len] = 0;
+ return dest;
+}
+
+/*******************************************************************
+ Safe string cat into a string. maxlength includes the terminating zero.
+ maxlength is in ucs2 units.
+********************************************************************/
+
+smb_ucs2_t *safe_strcat_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength)
+{
+ size_t ucs2_src_len, ucs2_dest_len;
+
+ if (!dest) {
+ DEBUG(0,("ERROR: NULL dest in safe_strcat_w\n"));
+ return NULL;
+ }
+
+ if (!src)
+ return dest;
+
+ ucs2_src_len = strlen_w(src);
+ ucs2_dest_len = strlen_w(dest);
+
+ if (ucs2_src_len + ucs2_dest_len >= maxlength) {
+ fstring out;
+ int new_len = maxlength - ucs2_dest_len - 1;
+ DEBUG(0,("ERROR: string overflow by %u characters in safe_strcat_w [%.50s]\n",
+ (unsigned int)(sizeof(smb_ucs2_t)*(ucs2_src_len + ucs2_dest_len - maxlength)),
+ unicode_to_unix(out,src,sizeof(out))) );
+ ucs2_src_len = (size_t)(new_len > 0 ? new_len : 0);
+ }
+
+ memcpy(&dest[ucs2_dest_len], src, ucs2_src_len*sizeof(smb_ucs2_t));
+ dest[ucs2_dest_len + ucs2_src_len] = 0;
+ return dest;
+}
+
+/*******************************************************************
+ Compare the two strings s1 and s2.
+********************************************************************/
+
+int strcmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
+{
+ smb_ucs2_t c1, c2;
+
+ for (;;) {
+ c1 = *s1++;
+ c2 = *s2++;
+
+ if (c1 != c2)
+ return c1 - c2;
+
+ if (c1 == 0)
+ return 0;
+ }
+ return 0;
+}
+
+/*******************************************************************
+ Compare the first n characters of s1 to s2. len is in ucs2 units.
+********************************************************************/
+
+int strncmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2, size_t len)
+{
+ smb_ucs2_t c1, c2;
+
+ for (; len != 0; --len) {
+ c1 = *s1++;
+ c2 = *s2++;
+
+ if (c1 != c2)
+ return c1 - c2;
+
+ if (c1 == 0)
+ return 0;
+
+ }
+ return 0;
+}
+
+/*******************************************************************
+ Search string s2 from s1.
+********************************************************************/
+
+smb_ucs2_t *strstr_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
+{
+ size_t len = strlen_w(s2);
+
+ if (!*s2)
+ return (smb_ucs2_t *)s1;
+
+ for(;*s1; s1++) {
+ if (*s1 == *s2) {
+ if (strncmp_w(s1, s2, len) == 0)
+ return (smb_ucs2_t *)s1;
+ }
+ }
+ return NULL;
+}
+
+/*******************************************************************
+ Search for ucs2 char c from the beginning of s.
+********************************************************************/
+
+smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
+{
+ do {
+ if (*s == c)
+ return (smb_ucs2_t *)s;
+ } while (*s++);
+
+ return NULL;
+}
+
+/*******************************************************************
+ Search for ucs2 char c from the end of s.
+********************************************************************/
+
+smb_ucs2_t *strrchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
+{
+ smb_ucs2_t *retval = 0;
+
+ do {
+ if (*s == c)
+ retval = (smb_ucs2_t *)s;
+ } while (*s++);
+
+ return retval;
+}
+
+/*******************************************************************
+ Search token from s1 separated by any ucs2 char of s2.
+********************************************************************/
+
+smb_ucs2_t *strtok_w(smb_ucs2_t *s1, const smb_ucs2_t *s2)
+{
+ static smb_ucs2_t *s = NULL;
+ smb_ucs2_t *q;
+
+ if (!s1) {
+ if (!s)
+ return NULL;
+ s1 = s;
+ }
+
+ for (q = s1; *s1; s1++) {
+ smb_ucs2_t *p = strchr_w(s2, *s1);
+ if (p) {
+ if (s1 != q) {
+ s = s1 + 1;
+ *s1 = '\0';
+ return q;
+ }
+ q = s1 + 1;
+ }
+ }
+
+ s = NULL;
+ if (*q)
+ return q;
+
+ return NULL;
+}
+
+/*******************************************************************
+ Duplicate a ucs2 string.
+********************************************************************/
+
+smb_ucs2_t *strdup_w(const smb_ucs2_t *s)
+{
+ size_t newlen = (strlen_w(s)+1)*sizeof(smb_ucs2_t);
+ smb_ucs2_t *newstr = (smb_ucs2_t *)malloc(newlen);
+ if (newstr == NULL)
+ return NULL;
+ safe_strcpy_w(newstr, s, newlen);
+ return newstr;
+}
+
+/*******************************************************************
+ Mapping tables for UNICODE character. Allows toupper/tolower and
+ isXXX functions to work.
+********************************************************************/
+
+typedef struct {
+ smb_ucs2_t lower;
+ smb_ucs2_t upper;
+ unsigned char flags;
+} smb_unicode_table_t;
+
+static smb_unicode_table_t map_table[] = {
+#include "unicode_map_table.h"
+};
+
+/*******************************************************************
+ Is an upper case wchar.
+********************************************************************/
+
+int isupper_w( smb_ucs2_t val)
+{
+ return (map_table[val].flags & UNI_UPPER);
+}
+
+/*******************************************************************
+ Is a lower case wchar.
+********************************************************************/
+
+int islower_w( smb_ucs2_t val)
+{
+ return (map_table[val].flags & UNI_LOWER);
+}
+
+/*******************************************************************
+ Is a digit wchar.
+********************************************************************/
+
+int isdigit_w( smb_ucs2_t val)
+{
+ return (map_table[val].flags & UNI_DIGIT);
+}
+
+/*******************************************************************
+ Is a hex digit wchar.
+********************************************************************/
+
+int isxdigit_w( smb_ucs2_t val)
+{
+ return (map_table[val].flags & UNI_XDIGIT);
+}
+
+/*******************************************************************
+ Is a space wchar.
+********************************************************************/
+
+int isspace_w( smb_ucs2_t val)
+{
+ return (map_table[val].flags & UNI_SPACE);
+}
+
+/*******************************************************************
+ Convert a wchar to upper case.
+********************************************************************/
+
+smb_ucs2_t toupper_w( smb_ucs2_t val )
+{
+ return map_table[val].upper;
+}
+
+/*******************************************************************
+ Convert a wchar to lower case.
+********************************************************************/
+
+smb_ucs2_t tolower_w( smb_ucs2_t val )
+{
+ return map_table[val].lower;
+}
+
+static smb_ucs2_t *last_ptr = NULL;
+
+void set_first_token_w(smb_ucs2_t *ptr)
+{
+ last_ptr = ptr;
+}
+
+/****************************************************************************
+ 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
+ bufsize is in bytes.
+****************************************************************************/
+
+static smb_ucs2_t sep_list[] = { (smb_ucs2_t)' ', (smb_ucs2_t)'\t', (smb_ucs2_t)'\n', (smb_ucs2_t)'\r', 0};
+static smb_ucs2_t quotechar = (smb_ucs2_t)'\"';
+
+BOOL next_token_w(smb_ucs2_t **ptr, smb_ucs2_t *buff, smb_ucs2_t *sep, size_t bufsize)
+{
+ smb_ucs2_t *s;
+ BOOL quoted;
+ size_t len=1;
+
+ /*
+ * Convert bufsize to smb_ucs2_t units.
+ */
+
+ bufsize /= sizeof(smb_ucs2_t);
+
+ if (!ptr)
+ ptr = &last_ptr;
+ if (!ptr)
+ return(False);
+
+ s = *ptr;
+
+ /*
+ * Default to simple separators.
+ */
+
+ if (!sep)
+ sep = sep_list;
+
+ /*
+ * Find the first non sep char.
+ */
+
+ while(*s && strchr_w(sep,*s))
+ s++;
+
+ /*
+ * Nothing left ?
+ */
+
+ if (!*s)
+ return(False);
+
+ /*
+ * Copy over the token.
+ */
+
+ for (quoted = False; len < bufsize && *s && (quoted || !strchr_w(sep,*s)); s++) {
+ if (*s == quotechar) {
+ quoted = !quoted;
+ } else {
+ len++;
+ *buff++ = *s;
+ }
+ }
+
+ *ptr = (*s) ? s+1 : s;
+ *buff = 0;
+ last_ptr = *ptr;
+
+ return(True);
+}
+
+/****************************************************************************
+ Convert list of tokens to array; dependent on above routine.
+ Uses last_ptr from above - bit of a hack.
+****************************************************************************/
+
+smb_ucs2_t **toktocliplist_w(int *ctok, smb_ucs2_t *sep)
+{
+ smb_ucs2_t *s=last_ptr;
+ int ictok=0;
+ smb_ucs2_t **ret, **iret;
+
+ if (!sep)
+ sep = sep_list;
+
+ while(*s && strchr_w(sep,*s))
+ s++;
+
+ /*
+ * Nothing left ?
+ */
+
+ if (!*s)
+ return(NULL);
+
+ do {
+ ictok++;
+ while(*s && (!strchr_w(sep,*s)))
+ s++;
+ while(*s && strchr_w(sep,*s))
+ *s++=0;
+ } while(*s);
+
+ *ctok = ictok;
+ s = last_ptr;
+
+ if (!(ret=iret=malloc(ictok*sizeof(smb_ucs2_t *))))
+ return NULL;
+
+ while(ictok--) {
+ *iret++=s;
+ while(*s++)
+ ;
+ while(!*s)
+ s++;
+ }
+
+ return ret;
+}
+
+/*******************************************************************
+ Case insensitive string compararison.
+********************************************************************/
+
+int StrCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t)
+{
+ /*
+ * Compare until we run out of string, either t or s, or find a difference.
+ */
+
+ while (*s && *t && toupper_w(*s) == toupper_w(*t)) {
+ s++;
+ t++;
+ }
+
+ return(toupper_w(*s) - toupper_w(*t));
+}
+
+/*******************************************************************
+ Case insensitive string compararison, length limited.
+ n is in ucs2 units.
+********************************************************************/
+
+int StrnCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t, size_t n)
+{
+ /*
+ * Compare until we run out of string, either t or s, or chars.
+ */
+
+ while (n && *s && *t && toupper_w(*s) == toupper_w(*t)) {
+ s++;
+ t++;
+ n--;
+ }
+
+ /*
+ * Not run out of chars - strings are different lengths.
+ */
+
+ if (n)
+ return(toupper_w(*s) - toupper_w(*t));
+
+ /*
+ * Identical up to where we run out of chars,
+ * and strings are same length.
+ */
+
+ return(0);
+}
+
+/*******************************************************************
+ Compare 2 strings.
+********************************************************************/
+
+BOOL strequal_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
+{
+ if (s1 == s2)
+ return(True);
+ if (!s1 || !s2)
+ return(False);
+
+ return(StrCaseCmp_w(s1,s2)==0);
+}
+
+/*******************************************************************
+ Compare 2 strings up to and including the nth char. n is in ucs2
+ units.
+******************************************************************/
+
+BOOL strnequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2,size_t n)
+{
+ if (s1 == s2)
+ return(True);
+ if (!s1 || !s2 || !n)
+ return(False);
+
+ return(StrnCaseCmp_w(s1,s2,n)==0);
+}
+
+/*******************************************************************
+ Compare 2 strings (case sensitive).
+********************************************************************/
+
+BOOL strcsequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2)
+{
+ if (s1 == s2)
+ return(True);
+ if (!s1 || !s2)
+ return(False);
+
+ return(strcmp_w(s1,s2)==0);
+}
+
+/*******************************************************************
+ Convert a string to lower case.
+********************************************************************/
+
+void strlower_w(smb_ucs2_t *s)
+{
+ while (*s) {
+ if (isupper_w(*s))
+ *s = tolower_w(*s);
+ s++;
+ }
+}
+
+/*******************************************************************
+ Convert a string to upper case.
+********************************************************************/
+
+void strupper_w(smb_ucs2_t *s)
+{
+ while (*s) {
+ if (islower_w(*s))
+ *s = toupper_w(*s);
+ s++;
+ }
+}
+
+/*******************************************************************
+ Convert a string to "normal" form.
+********************************************************************/
+
+void strnorm_w(smb_ucs2_t *s)
+{
+ extern int case_default;
+ if (case_default == CASE_UPPER)
+ strupper_w(s);
+ else
+ strlower_w(s);
+}
+
+/*******************************************************************
+ Check if a string is in "normal" case.
+********************************************************************/
+
+BOOL strisnormal_w(smb_ucs2_t *s)
+{
+ extern int case_default;
+ if (case_default == CASE_UPPER)
+ return(!strhaslower_w(s));
+
+ return(!strhasupper_w(s));
+}
+
+/****************************************************************************
+ String replace.
+****************************************************************************/
+
+void string_replace_w(smb_ucs2_t *s, smb_ucs2_t oldc, smb_ucs2_t newc)
+{
+ while (*s) {
+ if (oldc == *s)
+ *s = newc;
+ s++;
+ }
+}
+
+/*******************************************************************
+ Skip past some strings in a buffer. n is in bytes.
+********************************************************************/
+
+smb_ucs2_t *skip_string_w(smb_ucs2_t *buf,size_t n)
+{
+ while (n--)
+ buf += (strlen_w(buf)*sizeof(smb_ucs2_t)) + 1;
+ return(buf);
+}
+
+/*******************************************************************
+ Count the number of characters in a string. Same as strlen_w in
+ smb_ucs2_t string units.
+********************************************************************/
+
+size_t str_charnum_w(const smb_ucs2_t *s)
+{
+ return strlen_w(s);
+}
+
+/*******************************************************************
+ Trim the specified elements off the front and back of a string.
+********************************************************************/
+
+BOOL trim_string_w(smb_ucs2_t *s,const smb_ucs2_t *front,const smb_ucs2_t *back)
+{
+ BOOL ret = False;
+ size_t front_len = (front && *front) ? strlen_w(front) : 0;
+ size_t back_len = (back && *back) ? strlen_w(back) : 0;
+ size_t s_len;
+
+ while (front_len && strncmp_w(s, front, front_len) == 0) {
+ smb_ucs2_t *p = s;
+ ret = True;
+
+ while (1) {
+ if (!(*p = p[front_len]))
+ break;
+ p++;
+ }
+ }
+
+ if(back_len) {
+ s_len = strlen_w(s);
+ while ((s_len >= back_len) &&
+ (strncmp_w(s + s_len - back_len, back, back_len)==0)) {
+ ret = True;
+ s[s_len - back_len] = 0;
+ s_len = strlen_w(s);
+ }
+ }
+
+ return(ret);
+}
+
+/****************************************************************************
+ Does a string have any uppercase chars in it ?
+****************************************************************************/
+
+BOOL strhasupper_w(const smb_ucs2_t *s)
+{
+ while (*s) {
+ if (isupper_w(*s))
+ return(True);
+ s++;
+ }
+ return(False);
+}
+
+/****************************************************************************
+ Does a string have any lowercase chars in it ?
+****************************************************************************/
+
+BOOL strhaslower_w(const smb_ucs2_t *s)
+{
+ while (*s) {
+ if (islower(*s))
+ return(True);
+ s++;
+ }
+ return(False);
+}
+
+/****************************************************************************
+ Find the number of 'c' chars in a string.
+****************************************************************************/
+
+size_t count_chars_w(const smb_ucs2_t *s,smb_ucs2_t c)
+{
+ size_t count=0;
+
+ while (*s) {
+ if (*s == c)
+ count++;
+ s++;
+ }
+ return(count);
+}
+
+/*******************************************************************
+ Return True if a string consists only of one particular character.
+********************************************************************/
+
+BOOL str_is_all_w(const smb_ucs2_t *s,smb_ucs2_t c)
+{
+ if(s == NULL)
+ return False;
+ if(!*s)
+ return False;
+
+ while (*s) {
+ if (*s != c)
+ return False;
+ s++;
+ }
+ return True;
+}
+
+/*******************************************************************
+ Paranoid strcpy into a buffer of given length (includes terminating
+ zero. Strips out all but 'a-Z0-9' and replaces with '_'. Deliberately
+ does *NOT* check for multibyte characters. Don't change it !
+ maxlength is in ucs2 units.
+********************************************************************/
+
+smb_ucs2_t *alpha_strcpy_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength)
+{
+ size_t len, i;
+
+ if (!dest) {
+ DEBUG(0,("ERROR: NULL dest in alpha_strcpy_w\n"));
+ return NULL;
+ }
+
+ if (!src) {
+ *dest = 0;
+ return dest;
+ }
+
+ len = strlen_w(src);
+ if (len >= maxlength)
+ len = maxlength - 1;
+
+ for(i = 0; i < len; i++) {
+ smb_ucs2_t val = src[i];
+ if(isupper_w(val) ||islower_w(val) || isdigit_w(val))
+ dest[i] = src[i];
+ else
+ dest[i] = (smb_ucs2_t)'_';
+ }
+
+ 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 and is in
+ ucs2 units.
+****************************************************************************/
+
+smb_ucs2_t *StrnCpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src,size_t n)
+{
+ smb_ucs2_t *d = dest;
+ if (!dest)
+ return(NULL);
+ if (!src) {
+ *dest = 0;
+ return(dest);
+ }
+
+ while (n-- && (*d++ = *src++))
+ ;
+ *d = 0;
+ return(dest);
+}
+
+/****************************************************************************
+ Like strncpy but copies up to the character marker. Always null terminates.
+ returns a pointer to the character marker in the source string (src).
+ n is in ucs2 units.
+****************************************************************************/
+
+smb_ucs2_t *strncpyn_w(smb_ucs2_t *dest, const smb_ucs2_t *src,size_t n, smb_ucs2_t c)
+{
+ smb_ucs2_t *p;
+ size_t str_len;
+
+ p = strchr_w(src, c);
+ if (p == NULL) {
+ fstring cval;
+ smb_ucs2_t mbcval[2];
+ mbcval[0] = c;
+ mbcval[1] = 0;
+ DEBUG(5, ("strncpyn_w: separator character (%s) not found\n",
+ unicode_to_unix(cval,mbcval,sizeof(cval)) ));
+ return NULL;
+ }
+
+ str_len = PTR_DIFF(p, src) + 1;
+ safe_strcpy_w(dest, src, MIN(n, str_len));
+
+ return p;
+}
+
+/*************************************************************
+ 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. len is in bytes.
+ Valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
+**************************************************************/
+
+static smb_ucs2_t hexprefix[] = { (smb_ucs2_t)'0', (smb_ucs2_t)'x', 0 };
+static smb_ucs2_t hexchars[] = { (smb_ucs2_t)'0', (smb_ucs2_t)'1', (smb_ucs2_t)'2', (smb_ucs2_t)'3',
+ (smb_ucs2_t)'4', (smb_ucs2_t)'5', (smb_ucs2_t)'6', (smb_ucs2_t)'7',
+ (smb_ucs2_t)'8', (smb_ucs2_t)'9', (smb_ucs2_t)'A', (smb_ucs2_t)'B',
+ (smb_ucs2_t)'C', (smb_ucs2_t)'D', (smb_ucs2_t)'E', (smb_ucs2_t)'F', 0 };
+
+size_t strhex_to_str_w(char *p, size_t len, const smb_ucs2_t *strhex)
+{
+ size_t i;
+ size_t num_chars = 0;
+ unsigned char lonybble, hinybble;
+ smb_ucs2_t *p1 = NULL, *p2 = NULL;
+
+ /*
+ * Convert to smb_ucs2_t units.
+ */
+
+ len /= sizeof(smb_ucs2_t);
+
+ for (i = 0; i < len && strhex[i] != 0; i++) {
+ if (strnequal_w(hexchars, hexprefix, 2)) {
+ i++; /* skip two chars */
+ continue;
+ }
+
+ if (!(p1 = strchr_w(hexchars, toupper_w(strhex[i]))))
+ break;
+
+ i++; /* next hex digit */
+
+ if (!(p2 = strchr_w(hexchars, toupper_w(strhex[i]))))
+ break;
+
+ /* get the two nybbles */
+ hinybble = (PTR_DIFF(p1, hexchars)/sizeof(smb_ucs2_t));
+ lonybble = (PTR_DIFF(p2, hexchars)/sizeof(smb_ucs2_t));
+
+ p[num_chars] = (hinybble << 4) | lonybble;
+ num_chars++;
+
+ p1 = NULL;
+ p2 = NULL;
+ }
+ return num_chars;
+}
+
+/****************************************************************************
+ Check if a string is part of a list.
+****************************************************************************/
+
+BOOL in_list_w(smb_ucs2_t *s,smb_ucs2_t *list,BOOL casesensitive)
+{
+ wpstring tok;
+ smb_ucs2_t *p=list;
+
+ if (!list)
+ return(False);
+
+ while (next_token_w(&p,tok,LIST_SEP_W,sizeof(tok))) {
+ if (casesensitive) {
+ if (strcmp_w(tok,s) == 0)
+ return(True);
+ } else {
+ if (StrCaseCmp_w(tok,s) == 0)
+ return(True);
+ }
+ }
+ return(False);
+}
+
+/* This is used to prevent lots of mallocs of size 2 */
+static smb_ucs2_t *null_string = NULL;
+
+/****************************************************************************
+ Set a string value, allocing the space for the string.
+****************************************************************************/
+
+BOOL string_init_w(smb_ucs2_t **dest,const smb_ucs2_t *src)
+{
+ size_t l;
+
+ if (!null_string) {
+ if((null_string = (smb_ucs2_t *)malloc(sizeof(smb_ucs2_t))) == NULL) {
+ DEBUG(0,("string_init_w: malloc fail for null_string.\n"));
+ return False;
+ }
+ *null_string = 0;
+ }
+
+ if (!src)
+ src = null_string;
+
+ l = strlen_w(src);
+
+ if (l == 0)
+ *dest = null_string;
+ else {
+ (*dest) = (smb_ucs2_t *)malloc(sizeof(smb_ucs2_t)*(l+1));
+ if ((*dest) == NULL) {
+ DEBUG(0,("Out of memory in string_init_w\n"));
+ return False;
+ }
+
+ wpstrcpy(*dest,src);
+ }
+ return(True);
+}
+
+/****************************************************************************
+ Free a string value.
+****************************************************************************/
+
+void string_free_w(smb_ucs2_t **s)
+{
+ if (!s || !(*s))
+ return;
+ if (*s == null_string)
+ *s = NULL;
+ if (*s)
+ free((char *)*s);
+ *s = NULL;
+}
+
+/****************************************************************************
+ Set a string value, allocing the space for the string, and deallocating any
+ existing space.
+****************************************************************************/
+
+BOOL string_set_w(smb_ucs2_t **dest,const smb_ucs2_t *src)
+{
+ string_free_w(dest);
+
+ return(string_init_w(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 no length check is performed
+ len is in ucs2 units.
+****************************************************************************/
+
+void string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len)
+{
+ smb_ucs2_t *p;
+ ssize_t ls,lp,li, i;
+
+ if (!insert || !pattern || !s)
+ return;
+
+ ls = (ssize_t)strlen_w(s);
+ lp = (ssize_t)strlen_w(pattern);
+ li = (ssize_t)strlen_w(insert);
+
+ if (!*pattern)
+ return;
+
+ while (lp <= ls && (p = strstr_w(s,pattern))) {
+ if (len && (ls + (li-lp) >= len)) {
+ fstring out;
+ DEBUG(0,("ERROR: string overflow by %d in string_sub_w(%.50s, %d)\n",
+ (int)(sizeof(smb_ucs2_t)*(ls + (li-lp) - len)),
+ unicode_to_unix(out,pattern,sizeof(out)), (int)len*sizeof(smb_ucs2_t)));
+ break;
+ }
+ if (li != lp)
+ memmove(p+li,p+lp,sizeof(smb_ucs2_t)*(strlen_w(p+lp)+1));
+
+ for (i=0;i<li;i++) {
+ switch (insert[i]) {
+ case (smb_ucs2_t)'`':
+ case (smb_ucs2_t)'"':
+ case (smb_ucs2_t)'\'':
+ case (smb_ucs2_t)';':
+ case (smb_ucs2_t)'$':
+ case (smb_ucs2_t)'%':
+ case (smb_ucs2_t)'\r':
+ case (smb_ucs2_t)'\n':
+ p[i] = (smb_ucs2_t)'_';
+ break;
+ default:
+ p[i] = insert[i];
+ }
+ }
+ s = p + li;
+ ls += (li-lp);
+ }
+}
+
+void fstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert)
+{
+ string_sub_w(s, pattern, insert, sizeof(wfstring));
+}
+
+void pstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,smb_ucs2_t *insert)
+{
+ string_sub_w(s, pattern, insert, sizeof(wpstring));
+}
+
+/****************************************************************************
+ Similar to string_sub() but allows for any character to be substituted.
+ Use with caution !
+ if len==0 then no length check is performed.
+****************************************************************************/
+
+void all_string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len)
+{
+ smb_ucs2_t *p;
+ ssize_t ls,lp,li;
+
+ if (!insert || !pattern || !s)
+ return;
+
+ ls = (ssize_t)strlen_w(s);
+ lp = (ssize_t)strlen_w(pattern);
+ li = (ssize_t)strlen_w(insert);
+
+ if (!*pattern)
+ return;
+
+ while (lp <= ls && (p = strstr_w(s,pattern))) {
+ if (len && (ls + (li-lp) >= len)) {
+ fstring out;
+ DEBUG(0,("ERROR: string overflow by %d in all_string_sub_w(%.50s, %d)\n",
+ (int)(sizeof(smb_ucs2_t)*(ls + (li-lp) - len)),
+ unicode_to_unix(out,pattern,sizeof(out)), (int)len*sizeof(smb_ucs2_t)));
+ break;
+ }
+ if (li != lp)
+ memmove(p+li,p+lp,sizeof(smb_ucs2_t)*(strlen_w(p+lp)+1));
+
+ memcpy(p, insert, li*sizeof(smb_ucs2_t));
+ s = p + li;
+ ls += (li-lp);
+ }
+}
+
+/****************************************************************************
+ Splits out the front and back at a separator.
+****************************************************************************/
+
+void split_at_last_component_w(smb_ucs2_t *path, smb_ucs2_t *front, smb_ucs2_t sep, smb_ucs2_t *back)
+{
+ smb_ucs2_t *p = strrchr_w(path, sep);
+
+ if (p != NULL)
+ *p = 0;
+
+ if (front != NULL)
+ wpstrcpy(front, path);
+
+ if (p != NULL) {
+ if (back != NULL)
+ wpstrcpy(back, p+1);
+ *p = (smb_ucs2_t)'\\';
+ } else {
+ if (back != NULL)
+ back[0] = 0;
+ }
+}
+
+
+/****************************************************************************
+ Write an octal as a string.
+****************************************************************************/
+
+smb_ucs2_t *octal_string_w(int i)
+{
+ static smb_ucs2_t wret[64];
+ char ret[64];
+
+ if (i == -1)
+ slprintf(ret, sizeof(ret), "-1");
+ else
+ slprintf(ret, sizeof(ret), "0%o", i);
+ return unix_to_unicode(wret, ret, sizeof(wret));
+}
+
+
+/****************************************************************************
+ Truncate a string at a specified length.
+ length is in ucs2 units.
+****************************************************************************/
+
+smb_ucs2_t *string_truncate_w(smb_ucs2_t *s, size_t length)
+{
+ if (s && strlen_w(s) > length)
+ s[length] = 0;
+
+ return s;
+}
timeout.tv_sec = t/1000;
timeout.tv_usec = 1000*(t%1000);
- sys_select(fd+1,&fds,&fds,&timeout);
+ sys_select(fd+1,&fds,NULL,&timeout);
if (FD_ISSET(fd,&fds))
return(read_packet(fd,type));
****************************************************************************/
void pwd_init(struct pwd_info *pwd)
{
- ZERO_STRUCT(pwd->password );
+ ZERO_STRUCT(pwd->password);
ZERO_STRUCT(pwd->smb_lm_pwd);
ZERO_STRUCT(pwd->smb_nt_pwd);
ZERO_STRUCT(pwd->smb_lm_owf);
ZERO_STRUCT(pwd->smb_nt_owf);
pwd->nt_owf_len = 0;
- pwd->null_pwd = True; /* safest option... */
+ pwd->null_pwd = True; /* safest option... */
pwd->cleartext = False;
- pwd->crypted = False;
+ pwd->crypted = False;
}
/****************************************************************************
{
if (pwd1->crypted || pwd2->crypted)
{
- DEBUG(0,("pwd_compare: cannot compare crypted passwords\n"));
+ DEBUG(0, ("pwd_compare: cannot compare crypted passwords\n"));
return True;
}
{
if (strequal(pwd1->password, pwd2->password))
{
- ZERO_STRUCT(pwd1);
- ZERO_STRUCT(pwd2);
-
return True;
}
}
if (pwd1->null_pwd && pwd2->null_pwd)
{
- ZERO_STRUCT(pwd1);
- ZERO_STRUCT(pwd2);
-
return True;
}
- if (!pwd1->null_pwd && !pwd2->null_pwd &&
+ if (!pwd1->null_pwd && !pwd2->null_pwd &&
!pwd1->cleartext && !pwd2->cleartext)
{
dump_data_pw("pwd compare: nt#1\n", pwd1->smb_nt_pwd, 16);
if (memcmp(pwd1->smb_nt_pwd, pwd2->smb_nt_pwd, 16) == 0 &&
memcmp(pwd1->smb_lm_pwd, pwd2->smb_lm_pwd, 16) == 0)
{
- ZERO_STRUCT(pwd1);
- ZERO_STRUCT(pwd2);
-
return True;
}
}
- ZERO_STRUCT(pwd1);
- ZERO_STRUCT(pwd2);
-
return False;
}
pwd_init(pwd);
- user_pass = (char*)getpass(passwd_report);
+ user_pass = (char *)getpass(passwd_report);
if (user_pass == NULL || user_pass[0] == 0)
{
pwd_init(pwd);
pwd->cleartext = False;
- pwd->null_pwd = True;
- pwd->crypted = False;
+ pwd->null_pwd = True;
+ pwd->crypted = False;
}
/****************************************************************************
pwd_init(pwd);
fstrcpy(pwd->password, clr);
pwd->cleartext = True;
- pwd->null_pwd = False;
- pwd->crypted = False;
+ pwd->null_pwd = False;
+ pwd->crypted = False;
}
stores lm and nt hashed passwords
****************************************************************************/
void pwd_set_lm_nt_16(struct pwd_info *pwd,
- const uchar lm_pwd[16],
- const uchar nt_pwd[16])
+ const uchar lm_pwd[16], const uchar nt_pwd[16])
{
pwd_init(pwd);
- if (lm_pwd)
- {
- memcpy(pwd->smb_lm_pwd, lm_pwd, 16);
- }
- else
- {
- memset(pwd->smb_lm_pwd, 0, 16);
- }
+ Memcpy(pwd->smb_lm_pwd, lm_pwd, 16);
+ Memcpy(pwd->smb_nt_pwd, nt_pwd, 16);
- if (nt_pwd)
- {
- memcpy(pwd->smb_nt_pwd, nt_pwd, 16);
- }
- else
- {
- memset(pwd->smb_nt_pwd, 0, 16);
- }
-
- pwd->null_pwd = False;
+ pwd->null_pwd = False;
pwd->cleartext = False;
- pwd->crypted = False;
+ pwd->crypted = False;
}
/****************************************************************************
gets lm and nt hashed passwords
****************************************************************************/
-void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
+void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16],
+ uchar nt_pwd[16])
{
- if (lm_pwd != NULL)
- {
- memcpy(lm_pwd, pwd->smb_lm_pwd, 16);
- }
- if (nt_pwd != NULL)
- {
- memcpy(nt_pwd, pwd->smb_nt_pwd, 16);
- }
+ Memcpy(lm_pwd, pwd->smb_lm_pwd, 16);
+ Memcpy(nt_pwd, pwd->smb_nt_pwd, 16);
}
/****************************************************************************
pwd_init(pwd);
nt_lm_owf_gen(clr, pwd->smb_nt_pwd, pwd->smb_lm_pwd);
- pwd->null_pwd = False;
+ pwd->null_pwd = False;
pwd->cleartext = False;
pwd->crypted = False;
makes lm and nt OWF crypts
****************************************************************************/
void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8],
- const char *user, const char *server, const char *domain,
- uchar sess_key[16])
+ const char *user, const char *server,
+ const char *domain, uchar sess_key[16])
{
uchar kr[16];
- DEBUG(10,("pwd_make_lm_nt_owf2: user %s, srv %s, dom %s\n",
- user, server, domain));
+ DEBUG(10, ("pwd_make_lm_nt_owf2: user %s, srv %s, dom %s\n",
+ user, server, domain));
SMBgenclientchals(pwd->lm_cli_chal,
pwd->nt_cli_chal,
- &pwd->nt_cli_chal_len,
- server, domain);
-
+ &pwd->nt_cli_chal_len, server, domain);
+
ntv2_owf_gen(pwd->smb_nt_pwd, user, domain, kr);
/* lm # */
SMBOWFencrypt_ntv2(kr,
- srv_key, 8,
- pwd->lm_cli_chal, 8,
- pwd->smb_lm_owf);
+ srv_key, 8, pwd->lm_cli_chal, 8, pwd->smb_lm_owf);
memcpy(&pwd->smb_lm_owf[16], pwd->lm_cli_chal, 8);
/* nt # */
SMBOWFencrypt_ntv2(kr,
- srv_key, 8,
- pwd->nt_cli_chal, pwd->nt_cli_chal_len,
- pwd->smb_nt_owf);
+ srv_key, 8,
+ pwd->nt_cli_chal, pwd->nt_cli_chal_len,
+ pwd->smb_nt_owf);
memcpy(&pwd->smb_nt_owf[16], pwd->nt_cli_chal, pwd->nt_cli_chal_len);
pwd->nt_owf_len = pwd->nt_cli_chal_len + 16;
#endif
#ifdef DEBUG_PASSWORD
- DEBUG(100,("server cryptkey: "));
+ DEBUG(100, ("server cryptkey: "));
dump_data(100, srv_key, 8);
- DEBUG(100,("client lmv2 cryptkey: "));
+ DEBUG(100, ("client lmv2 cryptkey: "));
dump_data(100, pwd->lm_cli_chal, 8);
- DEBUG(100,("client ntv2 cryptkey: "));
+ DEBUG(100, ("client ntv2 cryptkey: "));
dump_data(100, pwd->nt_cli_chal, pwd->nt_cli_chal_len);
- DEBUG(100,("ntv2_owf_passwd: "));
+ DEBUG(100, ("ntv2_owf_passwd: "));
dump_data(100, pwd->smb_nt_owf, pwd->nt_owf_len);
- DEBUG(100,("nt_sess_pwd: "));
+ DEBUG(100, ("nt_sess_pwd: "));
dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
- DEBUG(100,("lmv2_owf_passwd: "));
+ DEBUG(100, ("lmv2_owf_passwd: "));
dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
- DEBUG(100,("lm_sess_pwd: "));
+ DEBUG(100, ("lm_sess_pwd: "));
dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
- DEBUG(100,("session key:\n"));
+ DEBUG(100, ("session key:\n"));
dump_data(100, sess_key, 16);
#endif
pwd->crypted = True;
makes lm and nt OWF crypts
****************************************************************************/
void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8],
- uchar sess_key[16])
+ uchar sess_key[16])
{
if (pwd->null_pwd)
{
#ifdef DEBUG_PASSWORD
- DEBUG(100,("pwd_make_lm_nt_owf: NULL password\n"));
+ DEBUG(100, ("pwd_make_lm_nt_owf: NULL password\n"));
#endif
pwd->nt_owf_len = 0;
return;
SMBsesskeygen_ntv1(pwd->smb_nt_pwd, pwd->smb_nt_owf, sess_key);
#ifdef DEBUG_PASSWORD
- DEBUG(100,("client cryptkey: "));
+ DEBUG(100, ("client cryptkey: "));
dump_data(100, cryptkey, 8);
- DEBUG(100,("nt_owf_passwd: "));
+ DEBUG(100, ("nt_owf_passwd: "));
dump_data(100, pwd->smb_nt_owf, pwd->nt_owf_len);
- DEBUG(100,("nt_sess_pwd: "));
+ DEBUG(100, ("nt_sess_pwd: "));
dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
- DEBUG(100,("lm_owf_passwd: "));
+ DEBUG(100, ("lm_owf_passwd: "));
dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
- DEBUG(100,("lm_sess_pwd: "));
+ DEBUG(100, ("lm_sess_pwd: "));
dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
- DEBUG(100,("session key:\n"));
+ DEBUG(100, ("session key:\n"));
dump_data(100, sess_key, 16);
#endif
gets lm and nt crypts
****************************************************************************/
void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24],
- uchar *nt_owf, size_t *nt_owf_len)
+ uchar * nt_owf, size_t * nt_owf_len)
{
if (pwd->null_pwd)
{
#ifdef DEBUG_PASSWORD
- DEBUG(100,("pwd_get_lm_nt_owf: NULL password\n"));
+ DEBUG(100, ("pwd_get_lm_nt_owf: NULL password\n"));
#endif
if (nt_owf_len != NULL)
{
}
return;
}
-
- if (lm_owf != NULL)
- {
- memcpy(lm_owf, pwd->smb_lm_owf, 24);
- }
- if (nt_owf != NULL)
- {
- memcpy(nt_owf, pwd->smb_nt_owf, pwd->nt_owf_len);
- }
+
+ Memcpy(lm_owf, pwd->smb_lm_owf, 24);
+ Memcpy(nt_owf, pwd->smb_nt_owf, pwd->nt_owf_len);
+
if (nt_owf_len != NULL)
{
*nt_owf_len = pwd->nt_owf_len;
}
}
-
#endif
}
+BOOL make_oem_passwd_hash(uchar data[516],
+ const char *pwrd, int new_pw_len,
+ const uchar old_pw_hash[16], BOOL unicode)
+{
+ if (new_pw_len == 0)
+ {
+ new_pw_len = strlen(pwrd) * (unicode ? 2 : 1);
+ }
+
+ if (new_pw_len > 512)
+ {
+ DEBUG(0,
+ ("make_oem_passwd_hash: new password is too long.\n"));
+ return False;
+ }
+
+ /*
+ * Now setup the data area.
+ * We need to generate a random fill
+ * for this area to make it harder to
+ * decrypt. JRA.
+ */
+ generate_random_buffer(data, 516, False);
+ if (unicode)
+ {
+ ascii_to_unibuf(&data[512 - new_pw_len], pwrd, new_pw_len);
+ }
+ else
+ {
+ fstrcpy(&data[512 - new_pw_len], pwrd);
+ }
+ SIVAL(data, 512, new_pw_len);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100, ("make_oem_passwd_hash\n"));
+ dump_data(100, data, 516);
+#endif
+ if (old_pw_hash != NULL)
+ {
+ SamOEMhash(data, old_pw_hash, True);
+ }
+
+ return True;
+}
+
void SMBOWFencrypt_ntv2(const uchar kr[16],
const uchar * srv_chal, int srv_chal_len,
const uchar * cli_chal, int cli_chal_len,
lm_owf_genW(pwd, lm_p16);
}
-BOOL make_oem_passwd_hash(uchar data[516],
- const char *pwrd, int new_pw_len,
- const uchar old_pw_hash[16], BOOL unicode)
-{
- if (new_pw_len == 0)
- {
- new_pw_len = strlen(pwrd) * (unicode ? 2 : 1);
- }
-
- if (new_pw_len > 512)
- {
- DEBUG(0,
- ("make_oem_passwd_hash: new password is too long.\n"));
- return False;
- }
-
- /*
- * Now setup the data area.
- * We need to generate a random fill
- * for this area to make it harder to
- * decrypt. JRA.
- */
- generate_random_buffer(data, 516, False);
- if (unicode)
- {
- ascii_to_unibuf(&data[512 - new_pw_len], pwrd, new_pw_len);
- }
- else
- {
- fstrcpy(&data[512 - new_pw_len], pwrd);
- }
- SIVAL(data, 512, new_pw_len);
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100, ("make_oem_passwd_hash\n"));
- dump_data(100, data, 516);
-#endif
- if (old_pw_hash != NULL)
- {
- SamOEMhash(data, old_pw_hash, True);
- }
-
- return True;
-}
-
BOOL nt_encrypt_string2(STRING2 * out, const STRING2 * in, const uchar * key)
{
const uchar *keyptr = key;
/* the locking database handle */
static TDB_CONTEXT *tdb;
+int global_smbpid;
+
+
/****************************************************************************
- Utility function to map a lock type correctly depending on the real open
- mode of a file.
+remove any locks on this fd
****************************************************************************/
-static int map_lock_type(files_struct *fsp, int lock_type)
+void locking_close_file(files_struct *fsp)
{
- if((lock_type == F_WRLCK) && (fsp->fd_ptr->real_open_flags == O_RDONLY)) {
- /*
- * Many UNIX's cannot get a write lock on a file opened read-only.
- * Win32 locking semantics allow this.
- * Do the best we can and attempt a read-only lock.
- */
- DEBUG(10,("map_lock_type: Downgrading write lock to read due to read-only file.\n"));
- return F_RDLCK;
- } else if( (lock_type == F_RDLCK) && (fsp->fd_ptr->real_open_flags == O_WRONLY)) {
- /*
- * Ditto for read locks on write only files.
- */
- DEBUG(10,("map_lock_type: Changing read lock to write due to write-only file.\n"));
- return F_WRLCK;
- }
-
- /*
- * This return should be the most normal, as we attempt
- * to always open files read/write.
- */
-
- return lock_type;
+ if (!lp_locking(SNUM(fsp->conn))) return;
+
+ brl_close(fsp->fd_ptr->dev, fsp->fd_ptr->inode,
+ getpid(), fsp->conn->cnum, fsp->fnum);
}
+
/****************************************************************************
Utility function called to see if a file region is locked.
****************************************************************************/
BOOL is_locked(files_struct *fsp,connection_struct *conn,
- SMB_OFF_T count,SMB_OFF_T offset, int lock_type)
+ SMB_OFF_T count,SMB_OFF_T offset,
+ enum brl_type lock_type)
{
int snum = SNUM(conn);
if (!lp_locking(snum) || !lp_strict_locking(snum))
return(False);
- /*
- * Note that most UNIX's can *test* for a write lock on
- * a read-only fd, just not *set* a write lock on a read-only
- * fd. So we don't need to use map_lock_type here.
- */
-
- return(fcntl_lock(fsp->fd_ptr->fd,SMB_F_GETLK,offset,count,lock_type));
+ return !brl_locktest(fsp->fd_ptr->dev, fsp->fd_ptr->inode,
+ global_smbpid, getpid(), conn->cnum,
+ offset, count, lock_type);
}
Utility function called by locking requests.
****************************************************************************/
BOOL do_lock(files_struct *fsp,connection_struct *conn,
- SMB_OFF_T count,SMB_OFF_T offset,int lock_type,
+ SMB_OFF_T count,SMB_OFF_T offset,enum brl_type lock_type,
int *eclass,uint32 *ecode)
{
BOOL ok = False;
DEBUG(10,("do_lock: lock type %d start=%.0f len=%.0f requested for file %s\n",
lock_type, (double)offset, (double)count, fsp->fsp_name ));
- if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn))
- ok = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count,
- map_lock_type(fsp,lock_type));
+ if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) {
+ ok = brl_lock(fsp->fd_ptr->dev, fsp->fd_ptr->inode, fsp->fnum,
+ global_smbpid, getpid(), conn->cnum,
+ offset, count,
+ lock_type);
+ }
if (!ok) {
*eclass = ERRDOS;
Utility function called by unlocking requests.
****************************************************************************/
BOOL do_unlock(files_struct *fsp,connection_struct *conn,
- SMB_OFF_T count,SMB_OFF_T offset,int *eclass,uint32 *ecode)
+ SMB_OFF_T count,SMB_OFF_T offset,
+ int *eclass,uint32 *ecode)
{
BOOL ok = False;
DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n",
(double)offset, (double)count, fsp->fsp_name ));
- if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn))
- ok = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count,F_UNLCK);
+ if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) {
+ ok = brl_unlock(fsp->fd_ptr->dev, fsp->fd_ptr->inode, fsp->fnum,
+ global_smbpid, getpid(), conn->cnum,
+ offset, count);
+ }
if (!ok) {
*eclass = ERRDOS;
****************************************************************************/
BOOL locking_init(int read_only)
{
+ brl_init(read_only);
+
if (tdb) return True;
tdb = tdb_open(lock_path("locking.tdb"),
return mod_share_mode(fsp, modify_share_mode_fn, (void *)&mv);
}
-static void (*traverse_callback)(share_mode_entry *, char *);
/****************************************************************************
traverse the whole database with this function, calling traverse_callback
on each share mode
****************************************************************************/
-static int traverse_fn(TDB_CONTEXT *db, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
+static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
+ void* state)
{
struct locking_data *data;
share_mode_entry *shares;
char *name;
int i;
+ SHAREMODE_FN(traverse_callback) = (SHAREMODE_FN_CAST())state;
+
data = (struct locking_data *)dbuf.dptr;
shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
name = dbuf.dptr + sizeof(*data) + data->num_share_mode_entries*sizeof(*shares);
Call the specified function on each entry under management by the
share mode system.
********************************************************************/
-int share_mode_forall(void (*fn)(share_mode_entry *, char *))
+int share_mode_forall(SHAREMODE_FN(fn))
{
if (!tdb) return 0;
- traverse_callback = fn;
- return tdb_traverse(tdb, traverse_fn, NULL);
+ return tdb_traverse(tdb, traverse_fn, (void*)fn);
}
#endif
}
- locking_end();
-
DEBUG(3,("Server exit (%s)\n", (reason ? reason : "")));
#ifdef MEM_MAN
{
exit_server("open socket failed");
}
- if (!locking_init(0))
- exit(1);
-
/* possibly reload the services file. */
fn->reload_services(True);
to.tv_sec = timeout / 1000;
to.tv_usec = (timeout % 1000) * 1000;
- selrtn =
- sys_select(MAX(maxfd, c) + 1, &fds, NULL,
+ selrtn = sys_select(MAX(maxfd, c) + 1, &fds, NULL,
timeout > 0 ? &to : NULL);
/* Check if error */
int selrtn;
struct timeval to;
int maxfd;
- int timeout = SMBD_SELECT_LOOP * 1000;
+ int timeout = SMBD_SELECT_TIMEOUT * 1000;
smb_read_error = 0;
to.tv_sec = timeout / 1000;
to.tv_usec = (timeout % 1000) * 1000;
- selrtn =
- sys_select(MAX(maxfd, l->c) + 1, NULL, &fds,
+ selrtn = sys_select(MAX(maxfd, l->c) + 1, NULL, &fds,
timeout > 0 ? &to : NULL);
/* Check if error */
void msrpcd_process(msrpc_service_fns * fn, rpcsrv_struct * l,
const char *name)
{
+ int counter = 0;
extern fstring remote_machine;
extern fstring local_machine;
extern pstring global_myname;
while (True)
{
- int counter;
- int service_load_counter = 0;
BOOL got_msrpc = False;
prs_struct pdu;
errno = 0;
- for (counter = SMBD_SELECT_LOOP;
- !receive_message_or_msrpc(l->c, &pdu,
- SMBD_SELECT_LOOP * 1000,
- &got_msrpc);
- counter += SMBD_SELECT_LOOP)
+ counter = (counter + 1 ) % 200;
+
+ if (!receive_message_or_msrpc(l->c, &pdu,
+ SMBD_SELECT_TIMEOUT * 1000,
+ &got_msrpc))
{
- time_t t;
-
- if (counter > 365 * 3600) /* big number of seconds. */
- {
- counter = 0;
- service_load_counter = 0;
- }
-
if (smb_read_error == READ_EOF)
{
DEBUG(3, ("end of file from client\n"));
- if (fn->idle != NULL)
- {
- become_root(False);
- fn->idle();
- unbecome_root(False);
- }
- return;
}
if (smb_read_error == READ_ERROR)
{
DEBUG(3, ("receive error (%s) exiting\n",
strerror(errno)));
- if (fn->idle != NULL)
- {
- become_root(False);
- fn->idle();
- unbecome_root(False);
- }
- return;
}
- t = time(NULL);
-
- /* check for smb.conf reload */
- if (counter >=
- service_load_counter + SMBD_RELOAD_CHECK)
+ if (fn->idle != NULL)
{
- service_load_counter = counter;
-
- /* reload services, if files have changed. */
- fn->reload_services(True);
+ become_root(False);
+ fn->idle();
+ unbecome_root(False);
}
+ return;
+ }
+
+ if (counter == 0)
+ {
+ /* reload services, if files have changed. */
+ fn->reload_services(True);
+ }
+
+ /*
+ * If reload_after_sighup == True then we got a SIGHUP
+ * and are being asked to reload. Fix from <branko.cibej@hermes.si>
+ */
+
+ if (reload_after_sighup)
+ {
+ DEBUG(0,
+ ("Reloading services after SIGHUP\n"));
+ fn->reload_services(False);
+ reload_after_sighup = False;
/*
- * If reload_after_sighup == True then we got a SIGHUP
- * and are being asked to reload. Fix from <branko.cibej@hermes.si>
+ * Use this as an excuse to print some stats.
*/
-
- if (reload_after_sighup)
- {
- DEBUG(0,
- ("Reloading services after SIGHUP\n"));
- fn->reload_services(False);
- reload_after_sighup = False;
- /*
- * Use this as an excuse to print some stats.
- */
- }
}
if (got_msrpc)
prs_free_data(&pdu);
}
}
+
if (!(winbindd_surs_sam_sid_to_unixid(&domain_group_sid,
request->data.groupname,
- SID_NAME_ALIAS, &unix_gid) ||
+ RID_TYPE_ALIAS, &unix_gid) ||
winbindd_surs_sam_sid_to_unixid(&domain_group_sid,
request->data.groupname,
- SID_NAME_DOM_GRP, &unix_gid))) {
+ RID_TYPE_GROUP, &unix_gid))) {
DEBUG(1, ("error sursing unix gid for sid\n"));
} else {
DOM_SID temp;
/* Get sid from gid */
- if (!(winbindd_surs_unixid_to_sam_sid(request->data.gid, SID_NAME_ALIAS,
+ if (!(winbindd_surs_unixid_to_sam_sid(request->data.gid, RID_TYPE_ALIAS,
&domain_group_sid, False) ||
- winbindd_surs_unixid_to_sam_sid(request->data.gid, SID_NAME_DOM_GRP,
+ winbindd_surs_unixid_to_sam_sid(request->data.gid, RID_TYPE_GROUP,
&domain_group_sid, False))) {
DEBUG(1, ("Could not convert gid %d to domain or local sid\n",
request->data.gid));
uint32 hwm_id;
fstring temp;
+ DEBUG(0,("TODO: create_new_id: lock tdb databases\n"));
+
isgroup ? (id_by_sid = surs_tdb_gid_by_sid) :
(id_by_sid = surs_tdb_uid_by_sid);
sid_append_rid(&group_sid, user_info.info.id21->group_rid);
res = winbindd_surs_sam_sid_to_unixid(&user_sid, request->data.username,
- SID_NAME_USER, &unix_uid);
+ RID_TYPE_USER, &unix_uid);
if (!res) {
DEBUG(1, ("error sursing unix uid for sid\n"));
} else {
res = res ? (winbindd_surs_sam_sid_to_unixid(&group_sid, NULL,
- SID_NAME_ALIAS,
+ RID_TYPE_ALIAS,
&unix_gid) ||
winbindd_surs_sam_sid_to_unixid(&group_sid, NULL,
- SID_NAME_DOM_GRP,
+ RID_TYPE_GROUP,
&unix_gid)) : False;
if (!res) {
DEBUG(1, ("error sursing unix gid for sid\n"));
/* Get sid from uid */
- if (!winbindd_surs_unixid_to_sam_sid(request->data.uid, SID_NAME_USER,
+ if (!winbindd_surs_unixid_to_sam_sid(request->data.uid, RID_TYPE_USER,
&domain_user_sid, False)) {
DEBUG(1, ("Could not convert uid %d to domain sid\n",
request->data.uid));
}
res = winbindd_surs_sam_sid_to_unixid(&domain_user_sid, username,
- SID_NAME_USER, &unix_uid);
+ RID_TYPE_USER, &unix_uid);
if (!res) {
DEBUG(1, ("error sursing unix uid for sid\n"));
/* ??? Should be domain_group-sid??? */
res = res ? (winbindd_surs_sam_sid_to_unixid(&domain_user_sid, NULL,
- SID_NAME_ALIAS, &unix_gid) ||
+ RID_TYPE_ALIAS, &unix_gid) ||
winbindd_surs_sam_sid_to_unixid(&domain_user_sid, NULL,
- SID_NAME_DOM_GRP, &unix_gid))
+ RID_TYPE_GROUP, &unix_gid))
: False;
/* Fill in password structure */
extern int DEBUGLEVEL;
extern pstring user_socket_options;
extern pstring global_myname;
-pstring global_scope;
+pstring global_scope = "";
#ifndef GLOBAL_NAME
#define GLOBAL_NAME "global"
char *szConfigFile;
char *szSMBPasswdFile;
char *szSAMDirectory;
- char *szSMBPassGroupFile;
- char *szSMBGroupFile;
- char *szSMBAliasFile;
char *szPasswordServer;
char *szSocketOptions;
char *szValidChars;
char *szLogonHome;
char *szSmbrun;
char *szWINSserver;
- char *szWINSHook;
char *szCodingSystem;
char *szInterfaces;
char *szRemoteAnnounce;
char *szLdapBuiltinSubcontext;
#endif /* WITH_NT5LDAP */
char *szPanicAction;
+ char *szAddUserScript;
+ char *szDelUserScript;
+ char *szWINSHook;
char *szNtForms;
char *szNtDriverFile;
+#ifdef WITH_UTMP
+ char *szUtmpDir;
+#endif /* WITH_UTMP */
+ char *szSourceEnv;
int max_log_size;
int mangled_stack;
int max_xmit;
BOOL bTimestampLogs;
BOOL bNTSmbSupport;
BOOL bNTPipeSupport;
+ BOOL bNTAclSupport;
BOOL bStatCache;
BOOL bKernelOplocks;
#if defined(HAVE_MYSQL_H) && defined(WITH_MYSQLSAM)
BOOL bDebugHiresTimestamp;
BOOL bDebugPid;
BOOL bDebugUid;
+ BOOL bHostMSDfs;
} global;
static global Globals;
char *writelist;
char *volume;
char *fstype;
- char *vfsObjectFile;
- struct vfs_options *vfsOptions;
+ char *szVfsObjectFile;
+ char *szVfsOptions;
int iMinPrintSpace;
+ int iWriteCacheSize;
int iCreate_mask;
int iCreate_force_mode;
+ int iSecurity_mask;
+ int iSecurity_force_mode;
int iDir_mask;
int iDir_force_mode;
+ int iDir_Security_mask;
+ int iDir_Security_force_mode;
int iMaxConnections;
int iDefaultCase;
int iPrinting;
+ int iOplockContentionLimit;
BOOL bAlternatePerm;
+ BOOL bPreexecClose;
+ BOOL bRootpreexecClose;
BOOL bRevalidate;
BOOL bCaseSensitive;
BOOL bCasePreserve;
BOOL bMap_archive;
BOOL bLocking;
BOOL bStrictLocking;
+#ifdef WITH_UTMP
+ BOOL bUtmp;
+#endif
BOOL bShareModes;
BOOL bOpLocks;
+ BOOL bLevel2OpLocks;
BOOL bOnlyUser;
BOOL bMangledNames;
BOOL bWidelinks;
BOOL bDosFiletimeResolution;
BOOL bFakeDirCreateTimes;
BOOL bBlockingLocks;
+ BOOL bInheritPerms;
+#ifdef MS_DFS
+ char *szDfsMap;
+ BOOL bDfsMapLoaded;
+#endif
char dummy[3]; /* for alignment */
} service;
NULL, /* vfs object */
NULL, /* vfs options */
0, /* iMinPrintSpace */
+ 0, /* iWriteCacheSize */
0744, /* iCreate_mask */
0000, /* iCreate_force_mode */
+ -1, /* iSecurity_mask */
+ -1, /* iSecurity_force_mode */
0755, /* iDir_mask */
0000, /* iDir_force_mode */
+ -1, /* iDir_Security_mask */
+ -1, /* iDir_Security_force_mode */
0, /* iMaxConnections */
CASE_LOWER, /* iDefaultCase */
DEFAULT_PRINTING, /* iPrinting */
+ 2, /* iOplockContentionLimit */
False, /* bAlternatePerm */
+ False, /* bPreexecClose */
+ False, /* bRootpreexecClose */
False, /* revalidate */
False, /* case sensitive */
True, /* case preserve */
True, /* bMap_archive */
True, /* bLocking */
False, /* bStrictLocking */
+#ifdef WITH_UTMP
+ False, /* bUtmp */
+#endif
True, /* bShareModes */
True, /* bOpLocks */
+ True, /* bLevel2OpLocks */
False, /* bOnlyUser */
True, /* bMangledNames */
True, /* bWidelinks */
False, /* bDosFiletimeResolution */
False, /* bFakeDirCreateTimes */
True, /* bBlockingLocks */
+ False, /* bInheritPerms */
+#ifdef MS_DFS
+ NULL, /* MS Dfs map path */
+ False, /* bDfsMapLoaded */
+#endif
"" /* dummy */
};
-/* local variables */
+/* Local variables */
static service **ServicePtrs = NULL;
static int iNumServices = 0;
static int iServiceIndex = 0;
static BOOL handle_copy(char *pszParmValue, char **ptr);
static BOOL handle_character_set(char *pszParmValue,char **ptr);
static BOOL handle_coding_system(char *pszParmValue,char **ptr);
+static BOOL handle_client_code_page(char *pszParmValue,char **ptr);
static BOOL handle_vfs_object(char *pszParmValue, char **ptr);
-static BOOL handle_vfs_option(char *pszParmValue, char **ptr);
+static BOOL handle_source_env(char *pszParmValue,char **ptr);
+static BOOL handle_netbios_name(char *pszParmValue,char **ptr);
static void set_server_role(void);
static void set_default_server_announce_type(void);
{PRINT_HPUX, "hpux"}, {PRINT_BSD, "bsd"},
{PRINT_QNX, "qnx"}, {PRINT_PLP, "plp"},
{PRINT_LPRNG, "lprng"}, {PRINT_SOFTQ, "softq"},
- {-1, NULL}};
+ {PRINT_CUPS, "cups"}, {-1, NULL}};
+
+static struct enum_list enum_bool_auto[] = {{True, "True"},
+ {False, "False"},
+ {True, "Yes"},
+ {False, "No"},
+ {Auto, "Auto"},
+ {-1, NULL}};
-static struct enum_list enum_announce_as[] = {{ANNOUNCE_AS_NT, "NT"}, {ANNOUNCE_AS_WIN95, "win95"},
- {ANNOUNCE_AS_WFW, "WfW"}, {-1, NULL}};
+/* Types of machine we can announce as. */
+#define ANNOUNCE_AS_NT_SERVER 1
+#define ANNOUNCE_AS_WIN95 2
+#define ANNOUNCE_AS_WFW 3
+#define ANNOUNCE_AS_NT_WORKSTATION 4
+
+static struct enum_list enum_announce_as[] = {{ANNOUNCE_AS_NT_SERVER, "NT"}, {ANNOUNCE_AS_NT_SERVER, "NT Server"}, {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"}, {ANNOUNCE_AS_WIN95, "win95"}, {ANNOUNCE_AS_WFW, "WfW"}, {-1, NULL}};
static struct enum_list enum_case[] = {{CASE_LOWER, "lower"}, {CASE_UPPER, "upper"}, {-1, NULL}};
-static struct enum_list enum_bool_auto[] = {{True, "True"}, {False, "False"}, {True, "Yes"}, {False, "No"}, {Auto, "Auto"}, {-1, NULL}};
+static struct enum_list enum_lm_announce[] = {{0, "False"}, {1, "True"}, {2, "Auto"}, {-1, NULL}};
/*
Do you want session setups at user level security with a invalid
static struct parm_struct parm_table[] =
{
{"Base Options", P_SEP, P_SEPARATOR},
-
- {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
- {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
- {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, 0},
- {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC},
- {"netbios name", P_UGSTRING,P_GLOBAL, global_myname, NULL, NULL, FLAG_BASIC},
- {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, 0},
- {"netbios scope", P_UGSTRING, P_GLOBAL, global_scope, NULL, NULL, 0},
- {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC},
+ {"coding system", P_STRING, P_GLOBAL, &Globals.szCodingSystem, handle_coding_system, NULL, 0},
+ {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, handle_client_code_page, NULL, 0},
+ {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT|FLAG_DOS_STRING},
+ {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT|FLAG_DOS_STRING},
+ {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_DOS_STRING},
+ {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC|FLAG_DOS_STRING},
+ {"netbios name", P_UGSTRING,P_GLOBAL, global_myname, handle_netbios_name, NULL, FLAG_BASIC|FLAG_DOS_STRING},
+ {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_DOS_STRING},
+ {"netbios scope", P_UGSTRING,P_GLOBAL, global_scope, NULL, NULL, FLAG_DOS_STRING},
+ {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC|FLAG_DOS_STRING},
{"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC},
{"bind interfaces only", P_BOOL,P_GLOBAL, &Globals.bBindInterfacesOnly,NULL, NULL, 0},
{"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, 0},
{"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, 0},
{"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, 0},
- {"dfs map", P_STRING, P_GLOBAL, &Globals.szDfsMap, NULL, NULL, 0},
- {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL, NULL, FLAG_GLOBAL},
- {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL},
+ {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
+ {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL, NULL, 0},
+ {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
{"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
{"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
- {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL, NULL, FLAG_BASIC|FLAG_PRINT|FLAG_GLOBAL},
- {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL},
- {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL},
- {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL},
- {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL},
- {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL},
- {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, 0},
- {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
+ {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT|FLAG_GLOBAL},
+ {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
+ {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
+ {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
+ {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
+ {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
+ {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_SHARE},
+ {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_SHARE},
{"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
- {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC},
+ {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC|FLAG_SHARE},
{"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
{"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
{"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
- {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
+ {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
{"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
- {"force create mode",P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_GLOBAL},
- {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
+ {"force create mode",P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
+ {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
+ {"force security mode",P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode,NULL,NULL, FLAG_GLOBAL|FLAG_SHARE},
+ {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
{"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
- {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_GLOBAL},
- {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
+ {"force directory mode", P_OCTAL,P_LOCAL,&sDefault.iDir_force_mode, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
+ {"directory security mask",P_OCTAL,P_LOCAL,&sDefault.iDir_Security_mask,NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
+ {"force directory security mode",P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode,NULL,NULL,FLAG_GLOBAL|FLAG_SHARE},
+ {"inherit permissions",P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_SHARE},
+ {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
{"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
- {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
+ {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT},
{"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, 0},
- {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, 0},
- {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT},
+ {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
+ {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_SHARE|FLAG_PRINT},
{"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, 0},
- {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT},
+ {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_SHARE|FLAG_PRINT},
{"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, 0},
#ifdef WITH_SSL
{"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, 0},
{"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, 0},
{"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, 0},
- {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL, NULL, FLAG_GLOBAL},
+ {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE|FLAG_PRINT},
{"Protocol Options", P_SEP, P_SEPARATOR},
{"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, 0},
{"nt smb support", P_BOOL, P_GLOBAL, &Globals.bNTSmbSupport, NULL, NULL, 0},
{"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, 0},
+ {"nt acl support", P_BOOL, P_GLOBAL, &Globals.bNTAclSupport, NULL, NULL, 0},
{"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, 0},
{"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, 0},
{"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, 0},
{"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, 0},
{"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, 0},
{"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, 0},
- {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, 0},
+ {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
{"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, 0},
{"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, 0},
- {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, 0},
+ {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
{"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL, NULL, 0},
{"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, 0},
{"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL, NULL, 0},
{"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, 0},
{"stat cache size", P_INTEGER, P_GLOBAL, &Globals.stat_cache_size, NULL, NULL, 0},
- {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, 0},
- {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, 0},
+ {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_SHARE},
+ {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_SHARE},
+ {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_SHARE},
{"Printing Options", P_SEP, P_SEPARATOR},
-
- {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, 0},
- {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0},
+ {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
+ {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT},
{"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0},
- {"printer driver file", P_STRING, P_GLOBAL, &Globals.szDriverFile, NULL, NULL, 0},
+ {"printer driver file", P_STRING, P_GLOBAL, &Globals.szDriverFile, NULL, NULL, FLAG_PRINT},
+ {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
{"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0},
- {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0},
{"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL, NULL, FLAG_PRINT},
{"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT|FLAG_GLOBAL},
{"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
{"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
{"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
- {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_GLOBAL},
- {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL, NULL, FLAG_GLOBAL},
- {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_GLOBAL},
- {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_GLOBAL},
+ {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
+ {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
+ {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
+ {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
{"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
{"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, 0},
- {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, 0},
- {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL, FLAG_GLOBAL},
+ {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, FLAG_PRINT},
+ {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
{"nt forms file", P_STRING, P_GLOBAL, &Globals.szNtForms, NULL, NULL, FLAG_GLOBAL},
{"nt printer driver",P_STRING, P_GLOBAL, &Globals.szNtDriverFile, NULL, NULL, FLAG_GLOBAL},
{"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, 0},
{"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set, NULL, 0},
{"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, 0},
- {"coding system", P_STRING, P_GLOBAL, &Globals.szCodingSystem, handle_coding_system, NULL, 0},
- {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, NULL, NULL, 0},
- {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, 0},
- {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_GLOBAL},
+ {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_SHARE},
+ {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
{"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, 0},
- {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_GLOBAL},
- {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL, NULL, FLAG_GLOBAL},
- {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_GLOBAL},
- {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_GLOBAL},
- {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_GLOBAL},
- {"delete veto files",P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_GLOBAL},
- {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_GLOBAL},
- {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_GLOBAL},
- {"veto oplock files",P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles,NULL, NULL, FLAG_GLOBAL},
- {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_GLOBAL},
- {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_GLOBAL},
- {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_GLOBAL},
- {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_GLOBAL},
- {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_GLOBAL},
+ {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+ {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+ {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+ {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+ {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+ {"delete veto files",P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+ {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL|FLAG_DOS_STRING},
+ {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL|FLAG_DOS_STRING},
+ {"veto oplock files",P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles,NULL, NULL, FLAG_SHARE|FLAG_GLOBAL|FLAG_DOS_STRING},
+ {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+ {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+ {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+ {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+ {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
{"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, 0},
{"Domain Options", P_SEP, P_SEPARATOR},
{"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, 0},
{"Logon Options", P_SEP, P_SEPARATOR},
-
- {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, 0},
- {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, 0},
+ {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, 0},
+ {"delete user script",P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, 0},
+ {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_DOS_STRING},
+ {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_DOS_STRING},
{"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, 0},
- {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, 0},
+ {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_DOS_STRING},
{"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, 0},
{"Browse Options", P_SEP, P_SEPARATOR},
{"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC},
- {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, 0},
+ {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_lm_announce, 0},
{"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, 0},
{"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC},
{"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
{"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC},
{"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC},
{"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, 0},
- {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0},
+ {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT},
{"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0},
{"WINS Options", P_SEP, P_SEPARATOR},
{"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, 0},
{"Locking Options", P_SEP, P_SEPARATOR},
-
- {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, 0},
- {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, 0},
+ {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+ {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_SHARE},
{"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_GLOBAL},
- {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_GLOBAL},
+ {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+#ifdef WITH_UTMP
+ {"utmp", P_BOOL, P_LOCAL, &sDefault.bUtmp, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+#endif
{"ole locking compatibility", P_BOOL, P_GLOBAL, &Globals.bOleLockingCompat, NULL, NULL, FLAG_GLOBAL},
- {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_GLOBAL},
- {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_GLOBAL},
- {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_GLOBAL},
+ {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+ {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+ {"oplock break wait time",P_INTEGER,P_GLOBAL,&Globals.oplock_break_wait_time,NULL,NULL,FLAG_GLOBAL},
+ {"oplock contention limit",P_INTEGER,P_LOCAL,&sDefault.iOplockContentionLimit,NULL,NULL,FLAG_SHARE|FLAG_GLOBAL},
+ {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+ {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
#if defined(WITH_LDAP) || defined(WITH_NT5LDAP)
{"Ldap Options", P_SEP, P_SEPARATOR},
{"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0},
{"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
{"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
+#ifdef WITH_UTMP
+ {"utmp dir", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, 0},
+ {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, 0},
+#endif /* WITH_UTMP */
{"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
{"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
{"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, 0},
{"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
{"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
{"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
- {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0},
+ {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_SHARE|FLAG_PRINT},
{"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0},
- {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, 0},
- {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, 0},
- {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, 0},
- {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, 0},
- {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, 0},
- {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, 0},
- {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, 0},
- {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_GLOBAL},
- {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_GLOBAL},
- {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, 0},
- {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, 0},
- {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, 0},
- {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_GLOBAL},
- {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_GLOBAL},
- {"dos filetime resolution",P_BOOL,P_LOCAL,&sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_GLOBAL},
+ {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_SHARE},
+ {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_SHARE|FLAG_PRINT},
+ {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_SHARE|FLAG_PRINT},
+ {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose,NULL, NULL, FLAG_SHARE},
+ {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_SHARE|FLAG_PRINT},
+ {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT},
+ {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE},
+ {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
+ {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_SHARE},
+ {"source environment",P_STRING, P_GLOBAL, &Globals.szSourceEnv, handle_source_env,NULL,0},
+ {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+ {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+ {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_SHARE},
+ {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_SHARE},
+ {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_SHARE},
+ {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+ {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+ {"dos filetime resolution",P_BOOL,P_LOCAL,&sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
- {"fake directory create times", P_BOOL,P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_GLOBAL},
+ {"fake directory create times", P_BOOL,P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
{"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, 0},
{"VFS options", P_SEP, P_SEPARATOR},
- {"vfs object", P_STRING, P_LOCAL, &sDefault.vfsObjectFile, handle_vfs_object, NULL, 0},
- {"vfs option", P_PTR, P_LOCAL, &sDefault.vfsOptions, handle_vfs_option, NULL, 0},
+ {"vfs object", P_STRING, P_LOCAL, &sDefault.szVfsObjectFile, handle_vfs_object, NULL, 0},
+ {"vfs options", P_STRING, P_LOCAL, &sDefault.szVfsOptions, NULL, NULL, 0},
+
+#ifdef MS_DFS
+ {"dfs map", P_STRING, P_LOCAL, &sDefault.szDfsMap, NULL, NULL, FLAG_SHARE},
+ {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_GLOBAL},
+#endif
+
{NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
};
if ((parm_table[i].type == P_STRING ||
parm_table[i].type == P_USTRING) &&
parm_table[i].ptr)
- string_init(parm_table[i].ptr,"");
+ string_set(parm_table[i].ptr,"");
string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
string_set(&sDefault.szPrinterDriver, "NULL");
string_set(&Globals.szSMBGroupFile, SMB_GROUP_FILE);
string_set(&Globals.szSMBAliasFile, SMB_ALIAS_FILE);
#endif
- string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
+ string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
string_set(&Globals.szWorkGroup, WORKGROUP);
string_set(&Globals.szPasswdProgram, PASSWD_PROGRAM);
string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
string_set(&Globals.szNtDriverFile, NTDRIVERSDIR);
string_set(&Globals.szLockDir, LOCKDIR);
string_set(&Globals.szRootdir, "/");
+#ifdef WITH_UTMP
+ string_set(&Globals.szUtmpDir, "");
+#endif /* WITH_UTMP */
string_set(&Globals.szSmbrun, SMBRUN);
string_set(&Globals.szSocketAddress, "0.0.0.0");
pstrcpy(s, "Samba ");
Globals.bReadRaw = True;
Globals.bWriteRaw = True;
Globals.bReadPrediction = False;
- Globals.bReadbmpx = True;
+ Globals.bReadbmpx = False;
Globals.bNullPasswords = False;
Globals.bStripDot = False;
Globals.syslog = 1;
Globals.lm_interval = 60;
Globals.shmem_size = SHMEM_SIZE;
Globals.stat_cache_size = 50; /* Number of stat translations we'll keep */
- Globals.announce_as = ANNOUNCE_AS_NT;
+ Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
Globals.bUnixRealname = False;
#if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
Globals.bNISHomeMap = False;
Globals.bOleLockingCompat = True;
Globals.bNTSmbSupport = True; /* Do NT SMB's by default. */
Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
+ Globals.bNTAclSupport = True; /* Use NT ACLs by default. */
Globals.bStatCache = True; /* use stat cache by default */
Globals.map_to_guest = 0; /* By Default, "Never" */
- Globals.min_passwd_length = 5; /* By Default, 5. */
+ Globals.min_passwd_length = MINPASSWDLENGTH; /* By Default, 5. */
Globals.oplock_break_wait_time = 10; /* By Default, 10 msecs. */
#if defined(WITH_LDAP) || defined(WITH_NT5LDAP)
#ifdef WITH_SSL
Globals.sslVersion = SMB_SSL_V23;
-
- /*
- * Most of the next variables should be string_set!
- */
-
- string_set(&Globals.sslHostsRequire, NULL);
- string_set(&Globals.sslHostsResign, NULL);
- string_set(&Globals.sslCaCertDir, NULL);
- string_set(&Globals.sslCaCertFile, NULL);
- string_set(&Globals.sslCert, NULL);
- string_set(&Globals.sslPrivKey, NULL);
- string_set(&Globals.sslClientCert, NULL);
- string_set(&Globals.sslClientPrivKey, NULL);
- string_set(&Globals.sslCiphers, NULL);
+ string_set(&Globals.sslHostsRequire, "");
+ string_set(&Globals.sslHostsResign, "");
+ string_set(&Globals.sslCaCertDir, "");
+ string_set(&Globals.sslCaCertFile, "");
+ string_set(&Globals.sslCert, "");
+ string_set(&Globals.sslPrivKey, "");
+ string_set(&Globals.sslClientCert, "");
+ string_set(&Globals.sslClientPrivKey, "");
+ string_set(&Globals.sslCiphers, "");
Globals.sslEnabled = False;
Globals.sslReqClientCert = False;
Globals.sslReqServerCert = False;
interpret_coding_system(KANJI);
}
-/***************************************************************************
-check if a string is initialised and if not then initialise it
-***************************************************************************/
-static void string_initial(char **s,char *v)
-{
- if (!*s || !**s)
- string_init(s,v);
-}
-
-
/***************************************************************************
Initialise the sDefault parameter structure.
***************************************************************************/
{
case PRINT_BSD:
case PRINT_AIX:
+ case PRINT_LPRNG:
case PRINT_PLP:
- string_initial(&sDefault.szLpqcommand,"lpq -P%p");
- string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
- string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
+ string_set(&sDefault.szLpqcommand,"lpq -P%p");
+ string_set(&sDefault.szLprmcommand,"lprm -P%p %j");
+ string_set(&sDefault.szPrintcommand,"lpr -r -P%p %s");
break;
- case PRINT_LPRNG:
- string_initial(&sDefault.szLpqcommand,"lpq -P%p");
- string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
- string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
- string_initial(&sDefault.szQueuepausecommand, "lpc stop %p");
- string_initial(&sDefault.szQueueresumecommand, "lpc start %p");
- string_initial(&sDefault.szLppausecommand,"lpc hold %p %j");
- string_initial(&sDefault.szLpresumecommand,"lpc release %p %j");
+ case PRINT_CUPS:
+ string_set(&sDefault.szLpqcommand,"/usr/bin/lpstat -o%p");
+ string_set(&sDefault.szLprmcommand,"/usr/bin/cancel %p-%j");
+ string_set(&sDefault.szPrintcommand,"/usr/bin/lp -d%p -oraw %s; rm %s");
+ string_set(&sDefault.szQueuepausecommand, "/usr/bin/disable %p");
+ string_set(&sDefault.szQueueresumecommand, "/usr/bin/enable %p");
break;
case PRINT_SYSV:
case PRINT_HPUX:
- string_initial(&sDefault.szLpqcommand,"lpstat -o%p");
- string_initial(&sDefault.szLprmcommand,"cancel %p-%j");
- string_initial(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
-#ifdef SYSV
- string_initial(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
- string_initial(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
- string_initial(&sDefault.szQueuepausecommand, "lpc stop %p");
- string_initial(&sDefault.szQueueresumecommand, "lpc start %p");
-#else /* SYSV */
- string_initial(&sDefault.szQueuepausecommand, "disable %p");
- string_initial(&sDefault.szQueueresumecommand, "enable %p");
+ string_set(&sDefault.szLpqcommand,"lpstat -o%p");
+ string_set(&sDefault.szLprmcommand,"cancel %p-%j");
+ string_set(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
+ string_set(&sDefault.szQueuepausecommand, "disable %p");
+ string_set(&sDefault.szQueueresumecommand, "enable %p");
+#ifndef HPUX
+ string_set(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
+ string_set(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
#endif /* SYSV */
break;
case PRINT_QNX:
- string_initial(&sDefault.szLpqcommand,"lpq -P%p");
- string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
- string_initial(&sDefault.szPrintcommand,"lp -r -P%p %s");
+ string_set(&sDefault.szLpqcommand,"lpq -P%p");
+ string_set(&sDefault.szLprmcommand,"lprm -P%p %j");
+ string_set(&sDefault.szPrintcommand,"lp -r -P%p %s");
break;
case PRINT_SOFTQ:
- string_initial(&sDefault.szLpqcommand,"qstat -l -d%p");
- string_initial(&sDefault.szLprmcommand,"qstat -s -j%j -c");
- string_initial(&sDefault.szPrintcommand,"lp -d%p -s %s; rm %s");
- string_initial(&sDefault.szLppausecommand,"qstat -s -j%j -h");
- string_initial(&sDefault.szLpresumecommand,"qstat -s -j%j -r");
+ string_set(&sDefault.szLpqcommand,"qstat -l -d%p");
+ string_set(&sDefault.szLprmcommand,"qstat -s -j%j -c");
+ string_set(&sDefault.szPrintcommand,"lp -d%p -s %s; rm %s");
+ string_set(&sDefault.szLppausecommand,"qstat -s -j%j -h");
+ string_set(&sDefault.szLpresumecommand,"qstat -s -j%j -r");
break;
}
}
+static TALLOC_CTX *lp_talloc;
/******************************************************************* a
-convenience routine to grab string parameters into a rotating buffer,
+free up temporary memory - called from the main loop
+********************************************************************/
+void lp_talloc_free(void)
+{
+ if (!lp_talloc) return;
+ talloc_destroy(lp_talloc);
+ lp_talloc = NULL;
+}
+
+/*******************************************************************
+convenience routine to grab string parameters into temporary memory
and run standard_sub_basic on them. The buffers can be written to by
callers without affecting the source string.
********************************************************************/
-static char *lp_user_string(const user_struct *vuser, char *s)
+static char *lp_user_string(const user_struct *vuser, const char *s)
{
- static char *bufs[10];
- static int buflen[10];
- static int next = -1;
+ size_t len = s?strlen(s):0;
char *ret;
- int i;
- int len = s?strlen(s):0;
- if (next == -1) {
- /* initialisation */
- for (i=0;i<10;i++) {
- bufs[i] = NULL;
- buflen[i] = 0;
- }
- next = 0;
- }
+ if (!lp_talloc) lp_talloc = talloc_init();
- len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
- substitution room */
-
- if (buflen[next] != len) {
- buflen[next] = len;
- if (bufs[next])
- free(bufs[next]);
- bufs[next] = (char *)malloc(len);
- if (!bufs[next]) {
- DEBUG(0,("out of memory in lp_string()"));
- exit(1);
- }
- }
+ ret = (char *)talloc(lp_talloc, len + 100); /* leave room for substitution */
- ret = &bufs[next][0];
- next = (next+1)%10;
+ if (!ret) return NULL;
if (!s)
*ret = 0;
else
- StrCpy(ret,s);
+ StrnCpy(ret,s,len);
trim_string(ret, "\"", "\"");
return(ret);
}
-static TALLOC_CTX *lp_talloc;
-
-/******************************************************************* a
-free up temporary memory - called from the main loop
-********************************************************************/
-void lp_talloc_free(void)
-{
- if (!lp_talloc) return;
- talloc_destroy(lp_talloc);
- lp_talloc = NULL;
-}
-
-/******************************************************************* a
-convenience routine to grab string parameters into a rotating buffer,
+/*******************************************************************
+convenience routine to grab string parameters into temporary memory
and run standard_sub_basic on them. The buffers can be written to by
callers without affecting the source string.
********************************************************************/
-static char *lp_string(char *s)
+static char *lp_string(const char *s)
{
- static char *bufs[10];
- static int buflen[10];
- static int next = -1;
+ size_t len = s?strlen(s):0;
char *ret;
- int i;
- int len = s?strlen(s):0;
-
- if (next == -1) {
- /* initialisation */
- for (i=0;i<10;i++) {
- bufs[i] = NULL;
- buflen[i] = 0;
- }
- next = 0;
- }
- len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
- substitution room */
+ if (!lp_talloc) lp_talloc = talloc_init();
- if (buflen[next] != len) {
- buflen[next] = len;
- if (bufs[next]) free(bufs[next]);
- bufs[next] = (char *)malloc(len);
- if (!bufs[next]) {
- DEBUG(0,("out of memory in lp_string()"));
- exit(1);
- }
- }
+ ret = (char *)talloc(lp_talloc, len + 100); /* leave room for substitution */
- ret = &bufs[next][0];
- next = (next+1)%10;
+ if (!ret) return NULL;
if (!s)
*ret = 0;
else
- StrCpy(ret,s);
+ StrnCpy(ret,s,len);
trim_string(ret, "\"", "\"");
#define FN_VUSER_STRING(fn_name,ptr) \
char *fn_name(const user_struct *usr) {return(lp_user_string(usr, *(char **)(ptr) ? *(char **)(ptr) : ""));}
-struct vfs_options *lp_vfsoptions(int i)
-{ return(LP_SNUM_OK(i) ? pSERVICE(i)->vfsOptions : sDefault.vfsOptions); }
-
FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
+#ifdef WITH_UTMP
+FN_GLOBAL_STRING(lp_utmpdir,&Globals.szUtmpDir)
+#endif /* WITH_UTMP */
FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
+FN_GLOBAL_STRING(lp_source_environment,&Globals.szSourceEnv)
FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand)
+FN_GLOBAL_STRING(lp_dfree_command,&Globals.szDfree)
FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv)
FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices)
FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram)
FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce)
FN_GLOBAL_STRING(lp_remote_browse_sync,&Globals.szRemoteBrowseSync)
FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
-FN_GLOBAL_STRING(lp_wins_hook,&Globals.szWINSHook)
FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName)
FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases)
FN_GLOBAL_STRING(lp_driverfile,&Globals.szDriverFile)
FN_GLOBAL_STRING(lp_panic_action,&Globals.szPanicAction)
+FN_GLOBAL_STRING(lp_adduser_script,&Globals.szAddUserScript)
+FN_GLOBAL_STRING(lp_deluser_script,&Globals.szDelUserScript)
+FN_GLOBAL_STRING(lp_wins_hook,&Globals.szWINSHook)
+
FN_GLOBAL_STRING(lp_nt_forms,&Globals.szNtForms)
FN_GLOBAL_STRING(lp_nt_drivers_file,&Globals.szNtDriverFile)
-FN_GLOBAL_STRING(lp_dfs_map,&Globals.szDfsMap)
#if defined(WITH_LDAP) || defined(WITH_NT5LDAP)
FN_GLOBAL_STRING(lp_ldap_server,&Globals.szLdapServer);
FN_GLOBAL_BOOL(lp_ole_locking_compat,&Globals.bOleLockingCompat)
FN_GLOBAL_BOOL(lp_nt_smb_support,&Globals.bNTSmbSupport)
FN_GLOBAL_BOOL(lp_nt_pipe_support,&Globals.bNTPipeSupport)
+FN_GLOBAL_BOOL(lp_nt_acl_support,&Globals.bNTAclSupport)
FN_GLOBAL_BOOL(lp_stat_cache,&Globals.bStatCache)
-
+FN_GLOBAL_BOOL(lp_host_msdfs,&Globals.bHostMSDfs)
FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
FN_GLOBAL_INTEGER(lp_max_wins_ttl,&Globals.max_wins_ttl)
FN_LOCAL_STRING(lp_readlist,readlist)
FN_LOCAL_STRING(lp_writelist,writelist)
FN_LOCAL_STRING(lp_fstype,fstype)
-FN_LOCAL_STRING(lp_vfsobj,vfsObjectFile)
+FN_LOCAL_STRING(lp_vfsobj,szVfsObjectFile)
static FN_LOCAL_STRING(lp_volume,volume)
FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
FN_LOCAL_STRING(lp_veto_files,szVetoFiles)
FN_LOCAL_STRING(lp_veto_oplocks,szVetoOplockFiles)
FN_LOCAL_STRING(lp_driverlocation,szPrinterDriverLocation)
+#ifdef MS_DFS
+FN_LOCAL_STRING(lp_dfsmap,szDfsMap)
+FN_LOCAL_BOOL(lp_dfsmap_loaded,bDfsMapLoaded)
+#endif
+
+FN_LOCAL_BOOL(lp_preexec_close,bPreexecClose)
+FN_LOCAL_BOOL(lp_rootpreexec_close,bRootpreexecClose)
FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive)
FN_LOCAL_BOOL(lp_preservecase,bCasePreserve)
FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
FN_LOCAL_BOOL(lp_locking,bLocking)
FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
+#ifdef WITH_UTMP
+FN_LOCAL_BOOL(lp_utmp,bUtmp)
+#endif
FN_LOCAL_BOOL(lp_share_modes,bShareModes)
FN_LOCAL_BOOL(lp_oplocks,bOpLocks)
+FN_LOCAL_BOOL(lp_level2_oplocks,bLevel2OpLocks)
FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
FN_LOCAL_BOOL(lp_dos_filetime_resolution,bDosFiletimeResolution)
FN_LOCAL_BOOL(lp_fake_dir_create_times,bFakeDirCreateTimes)
FN_LOCAL_BOOL(lp_blocking_locks,bBlockingLocks)
+FN_LOCAL_BOOL(lp_inherit_perms,bInheritPerms)
-FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask)
+FN_LOCAL_INTEGER(lp_create_mask,iCreate_mask)
FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
-FN_LOCAL_INTEGER(lp_dir_mode,iDir_mask)
+FN_LOCAL_INTEGER(_lp_security_mask,iSecurity_mask)
+FN_LOCAL_INTEGER(_lp_force_security_mode,iSecurity_force_mode)
+FN_LOCAL_INTEGER(lp_dir_mask,iDir_mask)
FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode)
+FN_LOCAL_INTEGER(_lp_dir_security_mask,iDir_Security_mask)
+FN_LOCAL_INTEGER(_lp_force_dir_security_mode,iDir_Security_force_mode)
FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
FN_LOCAL_INTEGER(lp_printing,iPrinting)
+FN_LOCAL_INTEGER(lp_oplock_contention_limit,iOplockContentionLimit)
+FN_LOCAL_INTEGER(lp_write_cache_size,iWriteCacheSize)
FN_LOCAL_CHAR(lp_magicchar,magic_char)
init_service(pSERVICE(i));
copy_service(pSERVICE(i),&tservice,NULL);
- if (name)
+ if (name) {
string_set(&iSERVICE(i).szService,name);
-
+ unix_to_dos(iSERVICE(i).szService, True);
+ }
return(i);
}
}
/***************************************************************************
- handle the interpretation of the vfs object parameter
- *************************************************************************/
-static BOOL handle_vfs_object(char *pszParmValue,char **ptr)
+ Run standard_sub_basic on netbios name... needed because global_myname
+ is not accessed through any lp_ macro.
+ Note: We must *NOT* use string_set() here as ptr points to global_myname.
+***************************************************************************/
+
+static BOOL handle_netbios_name(char *pszParmValue,char **ptr)
{
- /* Set string value */
+ pstring netbios_name;
- string_set(ptr,pszParmValue);
+ pstrcpy(netbios_name,pszParmValue);
- /* Do any other initialisation required for vfs. Note that
- anything done here may have linking repercussions in nmbd. */
+ standard_sub_basic(netbios_name);
+ strupper(netbios_name);
- return True;
+ /*
+ * Convert from UNIX to DOS string - the UNIX to DOS converter
+ * isn't called on the special handlers.
+ */
+ unix_to_dos(netbios_name, True);
+ pstrcpy(global_myname,netbios_name);
+
+ DEBUG(4,("handle_netbios_name: set global_myname to: %s\n", global_myname));
+
+ return(True);
}
/***************************************************************************
- handle the interpretation of the vfs option parameter
- *************************************************************************/
-static BOOL handle_vfs_option(char *pszParmValue, char **ptr)
+ Do the work of sourcing in environment variable/value pairs.
+***************************************************************************/
+
+static BOOL source_env(FILE *fenv)
{
- struct vfs_options *new_option, **options = (struct vfs_options **)ptr;
- int i;
+ pstring line;
+ char *varval;
+ size_t len;
+ char *p;
- /* Create new vfs option */
+ while (!feof(fenv)) {
+ if (fgets(line, sizeof(line), fenv) == NULL)
+ break;
- new_option = (struct vfs_options *)malloc(sizeof(*new_option));
- if (new_option == NULL) {
- return False;
+ if(feof(fenv))
+ break;
+
+ if((len = strlen(line)) == 0)
+ continue;
+
+ if (line[len - 1] == '\n')
+ line[--len] = '\0';
+
+ if ((varval=malloc(len+1)) == NULL) {
+ DEBUG(0,("source_env: Not enough memory!\n"));
+ return(False);
}
- ZERO_STRUCTP(new_option);
+ DEBUG(4,("source_env: Adding to environment: %s\n", line));
+ strncpy(varval, line, len);
+ varval[len] = '\0';
- /* Get name and value */
+ p=strchr(line, (int) '=');
+ if (p == NULL) {
+ DEBUG(4,("source_env: missing '=': %s\n", line));
+ continue;
+ }
- new_option->name = strtok(pszParmValue, "=");
+ if (putenv(varval)) {
+ DEBUG(0,("source_env: Failed to put environment variable %s\n", varval ));
+ continue;
+ }
- if (new_option->name == NULL) {
- return False;
+ *p='\0';
+ p++;
+ DEBUG(4,("source_env: getting var %s = %s\n", line, getenv(line)));
}
- while(isspace(*new_option->name)) {
- new_option->name++;
+ DEBUG(4,("source_env: returning successfully\n"));
+ return(True);
}
- for (i = strlen(new_option->name); i > 0; i--) {
- if (!isspace(new_option->name[i - 1])) break;
+/***************************************************************************
+ Handle the source environment operation
+***************************************************************************/
+
+static BOOL handle_source_env(char *pszParmValue,char **ptr)
+{
+ pstring fname;
+ char *p = fname;
+ FILE *env;
+ BOOL result;
+
+ pstrcpy(fname,pszParmValue);
+
+ standard_sub_basic(fname);
+
+ string_set(ptr,pszParmValue);
+
+ DEBUG(4, ("handle_source_env: checking env type\n"));
+
+ /*
+ * Filename starting with '|' means popen and read from stdin.
+ */
+
+ if (*p == '|') {
+
+ DEBUG(4, ("handle_source_env: source env from pipe\n"));
+ p++;
+
+ if ((env = sys_popen(p, "r", True)) == NULL) {
+ DEBUG(0,("handle_source_env: Failed to popen %s. Error was %s\n", p, strerror(errno) ));
+ return(False);
}
- new_option->name[i] = '\0';
- new_option->name = strdup(new_option->name);
+ DEBUG(4, ("handle_source_env: calling source_env()\n"));
+ result = source_env(env);
+ sys_pclose(env);
- new_option->value = strtok(NULL, "=");
+ } else {
- if (new_option->value != NULL) {
+ SMB_STRUCT_STAT st;
- while(isspace(*new_option->value)) {
- new_option->value++;
+ DEBUG(4, ("handle_source_env: source env from file %s\n", fname));
+ if ((env = sys_fopen(fname, "r")) == NULL) {
+ DEBUG(0,("handle_source_env: Failed to open file %s, Error was %s\n", fname, strerror(errno) ));
+ return(False);
}
- for (i = strlen(new_option->value); i > 0; i--) {
- if (!isspace(new_option->value[i - 1])) break;
+ /*
+ * Ensure this file is owned by root and not writable by world.
+ */
+ if(fstat(fileno(env), &st) != 0) {
+ DEBUG(0,("handle_source_env: Failed to stat file %s, Error was %s\n", fname, strerror(errno) ));
+ fclose(env);
+ return False;
}
- new_option->value[i] = '\0';
- new_option->value = strdup(new_option->value);
+ if((st.st_uid != (uid_t)0) || (st.st_mode & S_IWOTH)) {
+ DEBUG(0,("handle_source_env: unsafe to source env file %s. Not owned by root or world writable\n", fname ));
+ fclose(env);
+ return False;
}
- /* Add to list */
+ result=source_env(env);
+ fclose(env);
+ }
+ return(result);
+}
+
+
+
+#ifdef MS_DFS
+void set_dfsmap_loaded(int i,BOOL b)
+{
+ pSERVICE(i)->bDfsMapLoaded = b;
+}
+
+#endif
- DLIST_ADD(*options, new_option);
+/***************************************************************************
+ handle the interpretation of the vfs object parameter
+ *************************************************************************/
+static BOOL handle_vfs_object(char *pszParmValue,char **ptr)
+{
+ /* Set string value */
+
+ string_set(ptr,pszParmValue);
+
+ /* Do any other initialisation required for vfs. Note that
+ anything done here may have linking repercussions in nmbd. */
return True;
}
}
/***************************************************************************
- Handle the interpretation of the character set system parameter
+ Handle the interpretation of the character set system parameter.
***************************************************************************/
+
+static char *saved_character_set = NULL;
+
static BOOL handle_character_set(char *pszParmValue,char **ptr)
{
+ /* A dependency here is that the parameter client code page should be
+ set before this is called.
+ */
string_set(ptr,pszParmValue);
- interpret_character_set(pszParmValue);
+ strupper(*ptr);
+ saved_character_set = strdup(*ptr);
+ interpret_character_set(*ptr,lp_client_code_page());
return(True);
}
+/***************************************************************************
+ Handle the interpretation of the client code page parameter.
+ We handle this separately so that we can reset the character set
+ parameter in case this came before 'client code page' in the smb.conf.
+***************************************************************************/
+
+static BOOL handle_client_code_page(char *pszParmValue,char **ptr)
+{
+ Globals.client_code_page = atoi(pszParmValue);
+ if (saved_character_set != NULL)
+ interpret_character_set(saved_character_set,lp_client_code_page());
+ return(True);
+}
/***************************************************************************
handle the valid chars lines
pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
if (!pservice->copymap)
DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",(int)NUMPARAMETERS));
-
+ else
for (i=0;i<NUMPARAMETERS;i++)
pservice->copymap[i] = True;
}
case P_STRING:
string_set(parm_ptr,pszParmValue);
+ if (parm_table[parmnum].flags & FLAG_DOS_STRING)
+ unix_to_dos(*(char **)parm_ptr, True);
break;
case P_USTRING:
string_set(parm_ptr,pszParmValue);
+ if (parm_table[parmnum].flags & FLAG_DOS_STRING)
+ unix_to_dos(*(char **)parm_ptr, True);
strupper(*(char **)parm_ptr);
break;
case P_GSTRING:
pstrcpy((char *)parm_ptr,pszParmValue);
+ if (parm_table[parmnum].flags & FLAG_DOS_STRING)
+ unix_to_dos((char *)parm_ptr, True);
break;
case P_UGSTRING:
pstrcpy((char *)parm_ptr,pszParmValue);
+ if (parm_table[parmnum].flags & FLAG_DOS_STRING)
+ unix_to_dos((char *)parm_ptr, True);
strupper((char *)parm_ptr);
break;
}
}
break;
-
- default:
+ case P_SEP:
break;
}
break;
case P_OCTAL:
- fprintf(f,"0%o",*(int *)ptr);
+ fprintf(f,"%s",octal_string(*(int *)ptr));
break;
case P_GSTRING:
if (*(char **)ptr)
fprintf(f,"%s",*(char **)ptr);
break;
-
- default:
+ case P_SEP:
break;
}
}
if (p2 && !*p2) p2 = NULL;
return(p1==p2 || strequal(p1,p2));
}
-
- default:
+ case P_SEP:
break;
}
return(False);
case P_OCTAL:
case P_ENUM:
return parm_table[i].def.ivalue == *(int *)parm_table[i].ptr;
- default:
+ case P_SEP:
break;
}
return False;
case P_ENUM:
parm_table[i].def.ivalue = *(int *)parm_table[i].ptr;
break;
- default:
+ case P_SEP:
break;
}
}
defaults_saved = True;
}
+/*******************************************************************
+ Set the server type we will announce as via nmbd.
+********************************************************************/
+static void set_server_role(void)
+{
+ server_role = ROLE_DOMAIN_NONE;
+
+ switch (lp_security())
+ {
+ case SEC_SHARE:
+ {
+ if (lp_domain_logons())
+ {
+ DEBUG(0,("Server's Role (logon server) conflicts with share-level security\n"));
+ }
+ break;
+ }
+ case SEC_SERVER:
+ case SEC_DOMAIN:
+ {
+ if (lp_domain_logons())
+ {
+ server_role = ROLE_DOMAIN_BDC;
+ break;
+ }
+ server_role = ROLE_DOMAIN_MEMBER;
+ break;
+ }
+ case SEC_USER:
+ {
+ if (lp_domain_logons())
+ {
+ server_role = ROLE_DOMAIN_PDC;
+ break;
+ }
+ break;
+ }
+ default:
+ {
+ DEBUG(0,("Server's Role undefined due to unknown security mode\n"));
+ }
+ }
+}
+
/***************************************************************************
Load the services array from the services file. Return True on success,
}
+/***************************************************************************
+reset the max number of services
+***************************************************************************/
+void lp_resetnumservices(void)
+{
+ iNumServices = 0;
+}
+
/***************************************************************************
return the max number of services
***************************************************************************/
/***************************************************************************
Display the contents of the services array in human-readable form.
***************************************************************************/
-void lp_dump(FILE *f, BOOL show_defaults)
+void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
{
int iService;
dump_a_service(&sDefault, f);
- for (iService = 0; iService < iNumServices; iService++)
- {
- if (VALID(iService))
- {
- if (iSERVICE(iService).szService[0] == '\0')
- break;
- dump_a_service(pSERVICE(iService), f);
- }
- }
+ for (iService = 0; iService < maxtoprint; iService++)
+ lp_dump_one(f, show_defaults, iService);
}
/***************************************************************************
}
-/*******************************************************************
- Set the server type we will announce as via nmbd.
-********************************************************************/
-static void set_server_role(void)
-{
- server_role = ROLE_DOMAIN_NONE;
-
- switch (lp_security())
- {
- case SEC_SHARE:
- {
- if (lp_domain_logons())
- {
- DEBUG(0,("Server's Role (logon server) conflicts with share-level security\n"));
- }
- break;
- }
- case SEC_SERVER:
- case SEC_DOMAIN:
- {
- if (lp_domain_logons())
- {
- server_role = ROLE_DOMAIN_BDC;
- break;
- }
- server_role = ROLE_DOMAIN_MEMBER;
- break;
- }
- case SEC_USER:
- {
- if (lp_domain_logons())
- {
- server_role = ROLE_DOMAIN_PDC;
- break;
- }
- break;
- }
- default:
- {
- DEBUG(0,("Server's Role undefined due to unknown security mode\n"));
- }
- }
-}
-
/*******************************************************************
Set the server type we will announce as via nmbd.
********************************************************************/
}
}
+/***********************************************************
+ returns role of Samba server
+************************************************************/
+
+int lp_server_role(void)
+{
+ return server_role;
+}
+
+/***********************************************************
+ If we are PDC then prefer us as DMB
+************************************************************/
+
+BOOL lp_domain_master(void)
+{
+ if (Globals.bDomainMaster == Auto)
+ {
+ return (lp_server_role() == ROLE_DOMAIN_PDC);
+ }
+
+ return Globals.bDomainMaster;
+}
+
+/***********************************************************
+ If we are DMB then prefer us as LMB
+************************************************************/
+
+BOOL lp_preferred_master(void)
+{
+ if (Globals.bPreferredMaster == Auto)
+ {
+ return (lp_local_master() && lp_domain_master());
+ }
+
+ return Globals.bPreferredMaster;
+}
+
+
/*******************************************************************
remove a service
}
/***********************************************************
- returns role of Samba server
+ Functions to return the current security masks/modes. If
+ set to -1 then return the create mask/mode instead.
************************************************************/
-int lp_server_role(void)
+int lp_security_mask(int snum)
{
- return server_role;
+ int val = _lp_security_mask(snum);
+ if(val == -1)
+ return lp_create_mask(snum);
+ return val;
}
-/***********************************************************
- If we are PDC then prefer us as DMB
-************************************************************/
-
-BOOL lp_domain_master(void)
+int lp_force_security_mode(int snum)
{
- if (Globals.bDomainMaster == Auto)
- {
- return (lp_server_role() == ROLE_DOMAIN_PDC);
- }
-
- return Globals.bDomainMaster;
+ int val = _lp_force_security_mode(snum);
+ if(val == -1)
+ return lp_force_create_mode(snum);
+ return val;
}
-/***********************************************************
- If we are DMB then prefer us as LMB
-************************************************************/
-
-BOOL lp_preferred_master(void)
+int lp_dir_security_mask(int snum)
{
- if (Globals.bPreferredMaster == Auto)
- {
- return (lp_local_master() && lp_domain_master());
- }
+ int val = _lp_dir_security_mask(snum);
+ if(val == -1)
+ return lp_dir_mask(snum);
+ return val;
+}
- return Globals.bPreferredMaster;
+int lp_force_dir_security_mode(int snum)
+{
+ int val = _lp_force_dir_security_mode(snum);
+ if(val == -1)
+ return lp_force_dir_mode(snum);
+ return val;
}
return( c );
} /* EatComment */
+/*****************************************************************************
+ * Scan backards within a string to discover if the last non-whitespace
+ * character is a line-continuation character ('\\').
+ *
+ * Input: line - A pointer to a buffer containing the string to be
+ * scanned.
+ * pos - This is taken to be the offset of the end of the
+ * string. This position is *not* scanned.
+ *
+ * Output: The offset of the '\\' character if it was found, or -1 to
+ * indicate that it was not.
+ *
+ *****************************************************************************/
+
static int Continuation( char *line, int pos )
- /* ------------------------------------------------------------------------ **
- * Scan backards within a string to discover if the last non-whitespace
- * character is a line-continuation character ('\\').
- *
- * Input: line - A pointer to a buffer containing the string to be
- * scanned.
- * pos - This is taken to be the offset of the end of the
- * string. This position is *not* scanned.
- *
- * Output: The offset of the '\\' character if it was found, or -1 to
- * indicate that it was not.
- *
- * ------------------------------------------------------------------------ **
- */
- {
+{
+ int pos2 = 0;
+
pos--;
while( (pos >= 0) && isspace(line[pos]) )
pos--;
- return( ((pos >= 0) && ('\\' == line[pos])) ? pos : -1 );
- } /* Continuation */
+ /* we should recognize if `\` is part of a multibyte character or not. */
+ while(pos2 <= pos) {
+ size_t skip = 0;
+ skip = get_character_len(line[pos2]);
+ if (skip) {
+ pos2 += skip;
+ } else if (pos == pos2) {
+ return( ((pos >= 0) && ('\\' == line[pos])) ? pos : -1 );
+ } else {
+ pos2++;
+ }
+ }
+ return (-1);
+}
static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
-*.lo
\ No newline at end of file
+.libs
+*.lo
{
DEBUGADD(7,("Found: [%s]\n", dpname));
- StrCpy(driver_name, dpname+match_len);
+ fstrcpy(driver_name, dpname+match_len);
all_string_sub(driver_name, "#", "/", 0);
*list = Realloc(*list, sizeof(fstring)*(total+1));
StrnCpy((*list)[total], driver_name, strlen(driver_name));
* should I init this ones ???
nt_devmode->devicename
*/
- StrCpy(nt_devmode->formname, "A4");
+ safe_strcpy(nt_devmode->formname, "A4", sizeof(nt_devmode->formname)-1);
nt_devmode->specversion = 0x0401;
nt_devmode->driverversion = 0x0400;
static char *build_print_command(connection_struct *conn, const vuser_key *key,
int snum,
char *command,
- char *syscmd, char *filename1)
+ char *syscmd, char *filename)
{
char *tstr;
- pstring filename;
/* get the print command for the service. */
tstr = command;
DEBUG(2,("WARNING! No placeholder for the filename in the print command for service %s!\n", SERVICE(snum)));
}
- if (strstr(syscmd,"%s")) {
- pstrcpy(filename,filename1);
-
- string_sub(syscmd, "%s", filename);
- }
-
- string_sub(syscmd, "%f", filename1);
+ pstring_sub(syscmd, "%s", filename);
+ pstring_sub(syscmd, "%f", filename);
/* Does the service have a printername? If not, make a fake
and empty */
tstr = SERVICE(snum);
}
- string_sub(syscmd, "%p", tstr);
+ pstring_sub(syscmd, "%p", tstr);
{
user_struct *vuser = get_valid_user_struct(key);
return(False);
/* the Job and Total columns must be integer */
- if (!isdigit(*tok[JOBTOK]) || !isdigit(*tok[TOTALTOK])) return(False);
+ if (!isdigit((int)*tok[JOBTOK]) || !isdigit((int)*tok[TOTALTOK])) return(False);
buf->job = atoi(tok[JOBTOK]);
buf->size = atoi(tok[TOTALTOK]);
break;
}
}
+ /* Ensure null termination. */
+ buf->file[sizeof(buf->file)-1] = '\0';
}
#ifdef PRIOTOK
return(False);
}
- if (!isdigit(*tokarr[LPRNG_JOBTOK]) || !isdigit(*tokarr[LPRNG_TOTALTOK])) {
+ if (!isdigit((int)*tokarr[LPRNG_JOBTOK]) || !isdigit((int)*tokarr[LPRNG_TOTALTOK])) {
return(False);
}
if (strequal(tokarr[LPRNG_RANKTOK],"active")) {
buf->status = LPQ_PRINTING;
- } else if (isdigit(*tokarr[LPRNG_RANKTOK])) {
+ } else if (isdigit((int)*tokarr[LPRNG_RANKTOK])) {
buf->status = LPQ_QUEUED;
} else {
buf->status = LPQ_PAUSED;
break;
}
}
+ /* Ensure null termination. */
+ buf->file[sizeof(buf->file)-1] = '\0';
}
return(True);
int count=0;
/* handle the case of "(standard input)" as a filename */
- string_sub(line,"standard input","STDIN");
- all_string_sub(line,"(","\"", 0);
- all_string_sub(line,")","\"", 0);
+ pstring_sub(line,"standard input","STDIN");
+ all_string_sub(line,"(","\"",0);
+ all_string_sub(line,")","\"",0);
for (count=0;
count<10 &&
}
if (!header_line_ok) return (False); /* incorrect header line */
/* handle the case of "(standard input)" as a filename */
- string_sub(line,"standard input","STDIN");
- all_string_sub(line,"(","\"", 0);
- all_string_sub(line,")","\"", 0);
+ pstring_sub(line,"standard input","STDIN");
+ all_string_sub(line,"(","\"",0);
+ all_string_sub(line,")","\"",0);
for (count=0; count<2 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
/* we must get 2 tokens */
else if (base_prio) base_prio_reset=False;
/* handle the dash in the job id */
- string_sub(line,"-"," ");
+ pstring_sub(line,"-"," ");
for (count=0; count<12 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
/****************************************************************************
-parse a lpq line
+parse a lpstat line
here is an example of "lpstat -o dcslw" output under sysv
int count=0;
char *p;
- /* handle the dash in the job id */
- string_sub(line,"-"," ");
+ /*
+ * Handle the dash in the job id, but make sure that we skip over
+ * the printer name in case we have a dash in that.
+ * Patch from Dom.Mitchell@palmerharvey.co.uk.
+ */
- for (count=0; count<9 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
+ /*
+ * Move to the first space.
+ */
+ for (p = line ; !isspace(*p) && *p; p++)
+ ;
+
+ /*
+ * Back up until the last '-' character or
+ * start of line.
+ */
+ for (; (p >= line) && (*p != '-'); p--)
+ ;
+
+ if((p >= line) && (*p == '-'))
+ *p = ' ';
+
+ for (count=0; count<9 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++)
+ ;
/* we must get 7 tokens */
if (count < 7)
return(False);
/* the 2nd and 4th, 6th columns must be integer */
- if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[3])) return(False);
- if (!isdigit((int)*tok[5])) return(False);
+ if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[3]))
+ return(False);
+ if (!isdigit((int)*tok[5]))
+ return(False);
/* if the user contains a ! then trim the first part of it */
- if ((p=strchr(tok[2],'!')))
- {
+ if ((p=strchr(tok[2],'!'))) {
fstring tmp;
fstrcpy(tmp,p+1);
fstrcpy(tok[2],tmp);
DEBUG(4,("antes [%s]\n", line));
/* handle the case of "-- standard input --" as a filename */
- string_sub(line,"standard input","STDIN");
+ pstring_sub(line,"standard input","STDIN");
DEBUG(4,("despues [%s]\n", line));
- all_string_sub(line,"-- ","\"", 0);
- all_string_sub(line," --","\"", 0);
+ all_string_sub(line,"-- ","\"",0);
+ all_string_sub(line," --","\"",0);
DEBUG(4,("despues 1 [%s]\n", line));
- string_sub(line,"[job #","");
- string_sub(line,"]","");
+ pstring_sub(line,"[job #","");
+ pstring_sub(line,"]","");
DEBUG(4,("despues 2 [%s]\n", line));
int count=0;
/* handle the case of "(standard input)" as a filename */
- string_sub(line,"stdin","STDIN");
- all_string_sub(line,"(","\"", 0);
- all_string_sub(line,")","\"", 0);
+ pstring_sub(line,"stdin","STDIN");
+ all_string_sub(line,"(","\"",0);
+ all_string_sub(line,")","\"",0);
for (count=0; count<11 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
int count=0;
/* mung all the ":"s to spaces*/
- string_sub(line,":"," ");
+ pstring_sub(line,":"," ");
for (count=0; count<10 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
t->tm_mon = atoi(tok[count+2]+3);
switch (*tok[count+2])
{
- case 7: case 8: case 9: t->tm_year = atoi(tok[count+2]) + 1900; break;
- default: t->tm_year = atoi(tok[count+2]) + 2000; break;
+ case 7: case 8: case 9: t->tm_year = atoi(tok[count+2]); break;
+ default: t->tm_year = atoi(tok[count+2]); break;
}
t->tm_hour = atoi(tok[count+3]);
if (p) *p = 0;
}
+ /* in the LPRNG case, we skip lines starting by a space.*/
+ if (line && !ret && (lp_printing(snum)==PRINT_LPRNG) )
+ {
+ if (line[0]==' ')
+ return ret;
+ }
+
+
if (status && !ret)
{
/* a few simple checks to see if the line might be a
}
pstrcpy(syscmd,lpq_command);
- string_sub(syscmd,"%p",printername);
+ pstring_sub(syscmd,"%p",printername);
{
user_struct *vuser = get_valid_user_struct(key);
break;
}
- memset((char *)&(*queue)[count], 0, sizeof(**queue));
+ memset((char *)&(*queue)[count],'\0',sizeof(**queue));
/* parse it */
if (!parse_lpq_entry(snum,line,
slprintf(jobstr,sizeof(jobstr)-1,"%d",jobid);
pstrcpy(syscmd,lprm_command);
- string_sub(syscmd,"%p",printername);
- string_sub(syscmd,"%j",jobstr);
+ pstring_sub(syscmd,"%p",printername);
+ pstring_sub(syscmd,"%j",jobstr);
{
user_struct *vuser = get_valid_user_struct(key);
standard_sub(conn, vuser, syscmd);
slprintf(jobstr,sizeof(jobstr)-1,"%d",jobid);
pstrcpy(syscmd,lpstatus_command);
- string_sub(syscmd,"%p",printername);
- string_sub(syscmd,"%j",jobstr);
+ pstring_sub(syscmd,"%p",printername);
+ pstring_sub(syscmd,"%j",jobstr);
{
user_struct *vuser = get_valid_user_struct(key);
standard_sub(conn, vuser, syscmd);
}
pstrcpy(syscmd,queuestatus_command);
- string_sub(syscmd,"%p",printername);
+ pstring_sub(syscmd,"%p",printername);
{
user_struct *vuser = get_valid_user_struct(key);
standard_sub(conn, vuser, syscmd);
vuid_free_user_struct(vuser);
}
+ return ret == 0 ? 0x0 : NT_STATUS_INVALID_PARAMETER;
+
ret = smbrun(syscmd,NULL,False);
DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
lpq_reset(snum); /* queue has changed */
-
- return ret == 0 ? 0x0 : NT_STATUS_INVALID_PARAMETER;
}
-*.lo
\ No newline at end of file
+.libs
+*.lo
-*.lo
\ No newline at end of file
+.libs
+*.lo
/*******************************************************************
makes a DOM_CLNT_SRV structure.
********************************************************************/
-static BOOL make_clnt_srv(DOM_CLNT_SRV *log,
- const char *logon_srv,
- const char *comp_name)
+static BOOL make_clnt_srv(DOM_CLNT_SRV * log,
+ const char *logon_srv, const char *comp_name)
{
- if (log == NULL) return False;
+ if (log == NULL)
+ return False;
- DEBUG(5,("make_clnt_srv: %d\n", __LINE__));
+ DEBUG(5, ("make_clnt_srv: %d\n", __LINE__));
if (logon_srv != NULL)
{
log->undoc_buffer = 1;
- make_unistr2(&(log->uni_logon_srv), logon_srv, strlen(logon_srv)+1);
+ make_unistr2(&(log->uni_logon_srv), logon_srv,
+ strlen(logon_srv) + 1);
}
else
{
if (comp_name != NULL)
{
log->undoc_buffer2 = 1;
- make_unistr2(&(log->uni_comp_name), comp_name, strlen(comp_name)+1);
+ make_unistr2(&(log->uni_comp_name), comp_name,
+ strlen(comp_name) + 1);
}
else
{
/*******************************************************************
reads or writes a DOM_CLNT_SRV structure.
********************************************************************/
-static BOOL smb_io_clnt_srv(char *desc, DOM_CLNT_SRV *log, prs_struct *ps, int depth)
+static BOOL smb_io_clnt_srv(char *desc, DOM_CLNT_SRV * log, prs_struct *ps,
+ int depth)
{
- if (log == NULL) return False;
+ if (log == NULL)
+ return False;
prs_debug(ps, depth, desc, "smb_io_clnt_srv");
depth++;
prs_align(ps);
-
- prs_uint32("undoc_buffer ", ps, depth, &(log->undoc_buffer ));
+
+ prs_uint32("undoc_buffer ", ps, depth, &(log->undoc_buffer));
if (log->undoc_buffer != 0)
{
- smb_io_unistr2("unistr2", &(log->uni_logon_srv), log->undoc_buffer, ps, depth);
+ smb_io_unistr2("unistr2", &(log->uni_logon_srv),
+ log->undoc_buffer, ps, depth);
}
prs_align(ps);
prs_uint32("undoc_buffer2", ps, depth, &(log->undoc_buffer2));
if (log->undoc_buffer2 != 0)
{
- smb_io_unistr2("unistr2", &(log->uni_comp_name), log->undoc_buffer2, ps, depth);
+ smb_io_unistr2("unistr2", &(log->uni_comp_name),
+ log->undoc_buffer2, ps, depth);
}
return True;
/*******************************************************************
makes a DOM_LOG_INFO structure.
********************************************************************/
-BOOL make_log_info(DOM_LOG_INFO *log,
- const char *logon_srv, const char *acct_name,
- uint16 sec_chan, const char *comp_name)
+BOOL make_log_info(DOM_LOG_INFO * log,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name)
{
- if (log == NULL) return False;
+ if (log == NULL)
+ return False;
- DEBUG(5,("make_log_info %d\n", __LINE__));
+ DEBUG(5, ("make_log_info %d\n", __LINE__));
log->undoc_buffer = 1;
- make_unistr2(&(log->uni_logon_srv), logon_srv, strlen(logon_srv)+1);
- make_unistr2(&(log->uni_acct_name), acct_name, strlen(acct_name)+1);
+ make_unistr2(&(log->uni_logon_srv), logon_srv, strlen(logon_srv) + 1);
+ make_unistr2(&(log->uni_acct_name), acct_name, strlen(acct_name) + 1);
log->sec_chan = sec_chan;
- make_unistr2(&(log->uni_comp_name), comp_name, strlen(comp_name)+1);
+ make_unistr2(&(log->uni_comp_name), comp_name, strlen(comp_name) + 1);
return True;
}
/*******************************************************************
reads or writes a DOM_LOG_INFO structure.
********************************************************************/
-BOOL smb_io_log_info(char *desc, DOM_LOG_INFO *log, prs_struct *ps, int depth)
+BOOL smb_io_log_info(char *desc, DOM_LOG_INFO * log, prs_struct *ps,
+ int depth)
{
- if (log == NULL) return False;
+ if (log == NULL)
+ return False;
prs_debug(ps, depth, desc, "smb_io_log_info");
depth++;
prs_align(ps);
-
+
prs_uint32("undoc_buffer", ps, depth, &(log->undoc_buffer));
smb_io_unistr2("unistr2", &(log->uni_logon_srv), True, ps, depth);
/*******************************************************************
makes a DOM_CLNT_INFO2 structure.
********************************************************************/
-BOOL make_clnt_info2(DOM_CLNT_INFO2 *clnt,
- const char *logon_srv, const char *comp_name,
- DOM_CRED *clnt_cred)
+BOOL make_clnt_info2(DOM_CLNT_INFO2 * clnt,
+ const char *logon_srv, const char *comp_name,
+ DOM_CRED * clnt_cred)
{
- if (clnt == NULL) return False;
+ if (clnt == NULL)
+ return False;
- DEBUG(5,("make_clnt_info: %d\n", __LINE__));
+ DEBUG(5, ("make_clnt_info: %d\n", __LINE__));
make_clnt_srv(&(clnt->login), logon_srv, comp_name);
- if (clnt_cred != NULL)
- {
- clnt->ptr_cred = 1;
- memcpy(&(clnt->cred), clnt_cred, sizeof(clnt->cred));
- }
- else
- {
- clnt->ptr_cred = 0;
- }
+ clnt->ptr_cred = Memcpy(&clnt->cred, clnt_cred, sizeof(clnt->cred));
return True;
}
/*******************************************************************
reads or writes a DOM_CLNT_INFO2 structure.
********************************************************************/
-BOOL smb_io_clnt_info2(char *desc, DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth)
+BOOL smb_io_clnt_info2(char *desc, DOM_CLNT_INFO2 * clnt, prs_struct *ps,
+ int depth)
{
- if (clnt == NULL) return False;
+ if (clnt == NULL)
+ return False;
prs_debug(ps, depth, desc, "smb_io_clnt_info2");
depth++;
prs_align(ps);
-
+
smb_io_clnt_srv("", &(clnt->login), ps, depth);
prs_align(ps);
-
+
prs_uint32("ptr_cred", ps, depth, &(clnt->ptr_cred));
- smb_io_cred ("", &(clnt->cred ), ps, depth);
+ smb_io_cred("", &(clnt->cred), ps, depth);
return True;
}
/*******************************************************************
makes a DOM_CLNT_INFO structure.
********************************************************************/
-BOOL make_clnt_info(DOM_CLNT_INFO *clnt,
- const char *logon_srv, const char *acct_name,
- uint16 sec_chan, const char *comp_name,
- DOM_CRED *cred)
+BOOL make_clnt_info(DOM_CLNT_INFO * clnt,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name, DOM_CRED * cred)
{
- if (clnt == NULL || cred == NULL) return False;
+ if (clnt == NULL || cred == NULL)
+ return False;
- DEBUG(5,("make_clnt_info\n"));
+ DEBUG(5, ("make_clnt_info\n"));
- make_log_info(&(clnt->login), logon_srv, acct_name, sec_chan, comp_name);
- memcpy(&(clnt->cred), cred, sizeof(clnt->cred));
+ make_log_info(&(clnt->login), logon_srv, acct_name, sec_chan,
+ comp_name);
+ Memcpy(&clnt->cred, cred, sizeof(clnt->cred));
return True;
}
/*******************************************************************
reads or writes a DOM_CLNT_INFO structure.
********************************************************************/
-BOOL smb_io_clnt_info(char *desc, DOM_CLNT_INFO *clnt, prs_struct *ps, int depth)
+BOOL smb_io_clnt_info(char *desc, DOM_CLNT_INFO * clnt, prs_struct *ps,
+ int depth)
{
- if (clnt == NULL) return False;
+ if (clnt == NULL)
+ return False;
prs_debug(ps, depth, desc, "smb_io_clnt_info");
depth++;
prs_align(ps);
-
+
smb_io_log_info("", &(clnt->login), ps, depth);
- smb_io_cred ("", &(clnt->cred ), ps, depth);
+ smb_io_cred("", &(clnt->cred), ps, depth);
return True;
}
/*******************************************************************
makes an OWF_INFO structure.
********************************************************************/
-BOOL make_owf_info(OWF_INFO *hash, const uint8 data[16])
+BOOL make_owf_info(OWF_INFO * hash, const uint8 data[16])
{
- if (hash == NULL) return False;
+ if (hash == NULL)
+ return False;
- DEBUG(5,("make_owf_info: %d\n", __LINE__));
-
- if (data != NULL)
- {
- memcpy(hash->data, data, sizeof(hash->data));
- }
- else
- {
- ZERO_STRUCT(hash->data);
- }
+ DEBUG(5, ("make_owf_info: %d\n", __LINE__));
+
+ Memcpy(hash->data, data, sizeof(hash->data));
return True;
}
/*******************************************************************
reads or writes an OWF_INFO structure.
********************************************************************/
-BOOL smb_io_owf_info(char *desc, OWF_INFO *hash, prs_struct *ps, int depth)
+BOOL smb_io_owf_info(char *desc, OWF_INFO * hash, prs_struct *ps, int depth)
{
- if (hash == NULL) return False;
+ if (hash == NULL)
+ return False;
prs_debug(ps, depth, desc, "smb_io_owf_info");
depth++;
prs_align(ps);
-
- prs_uint8s (False, "data", ps, depth, hash->data, 16);
+
+ prs_uint8s(False, "data", ps, depth, hash->data, 16);
return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-static BOOL net_io_neg_flags(char *desc, NEG_FLAGS * neg, prs_struct * ps,
+static BOOL net_io_neg_flags(char *desc, NEG_FLAGS * neg, prs_struct *ps,
int depth)
{
if (neg == NULL)
reads or writes a NETLOGON_INFO_3 structure.
********************************************************************/
static BOOL net_io_netinfo_3(char *desc, NETLOGON_INFO_3 * info,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (info == NULL)
return False;
reads or writes a NETLOGON_INFO_1 structure.
********************************************************************/
static BOOL net_io_netinfo_1(char *desc, NETLOGON_INFO_1 * info,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (info == NULL)
return False;
reads or writes a NETLOGON_INFO_2 structure.
********************************************************************/
static BOOL net_io_netinfo_2(char *desc, NETLOGON_INFO_2 * info,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (info == NULL)
return False;
reads or writes an NET_Q_LOGON_CTRL2 structure.
********************************************************************/
BOOL net_io_q_logon_ctrl2(char *desc, NET_Q_LOGON_CTRL2 * q_l,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_l == NULL)
return False;
r_l->switch_value = switch_value; /* should only be 0x1 */
r_l->status = status;
- memcpy(&(r_l->logon), logon_info, sizeof(NETLOGON_INFO));
+ Memcpy(&r_l->logon, logon_info, sizeof(NETLOGON_INFO));
if (status == NT_STATUS_NOPROBLEMO)
{
reads or writes an NET_R_LOGON_CTRL2 structure.
********************************************************************/
BOOL net_io_r_logon_ctrl2(char *desc, NET_R_LOGON_CTRL2 * r_l,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_l == NULL)
return False;
reads or writes an NET_R_TRUST_DOM_LIST structure.
********************************************************************/
BOOL net_io_r_trust_dom(char *desc, NET_R_TRUST_DOM_LIST * r_t,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_t == NULL)
return False;
reads or writes an NET_Q_TRUST_DOM_LIST structure.
********************************************************************/
BOOL net_io_q_trust_dom(char *desc, NET_Q_TRUST_DOM_LIST * q_l,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_l == NULL)
return False;
/*******************************************************************
reads or writes an NET_Q_REQ_CHAL structure.
********************************************************************/
-BOOL net_io_q_req_chal(char *desc, NET_Q_REQ_CHAL * q_c, prs_struct * ps,
+BOOL net_io_q_req_chal(char *desc, NET_Q_REQ_CHAL * q_c, prs_struct *ps,
int depth)
{
int old_align;
ps->align = 0;
smb_io_unistr2("logon_clnt", &(q_c->uni_logon_clnt), True, ps, depth);
- smb_io_chal("clnt_chal", &(q_c->clnt_chal), ps, depth);
+ smb_io_chal("clnt_chal", &(q_c->clnt_chal), ps, depth);
ps->align = old_align;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL * r_c, prs_struct * ps,
+BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL * r_c, prs_struct *ps,
int depth)
{
if (r_c == NULL)
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL net_io_q_auth(char *desc, NET_Q_AUTH * q_a, prs_struct * ps, int depth)
+BOOL net_io_q_auth(char *desc, NET_Q_AUTH * q_a, prs_struct *ps, int depth)
{
int old_align;
if (q_a == NULL)
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL net_io_r_auth(char *desc, NET_R_AUTH * r_a, prs_struct * ps, int depth)
+BOOL net_io_r_auth(char *desc, NET_R_AUTH * r_a, prs_struct *ps, int depth)
{
if (r_a == NULL)
return False;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 * q_a, prs_struct * ps,
+BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 * q_a, prs_struct *ps,
int depth)
{
int old_align;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 * r_a, prs_struct * ps,
+BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 * r_a, prs_struct *ps,
int depth)
{
if (r_a == NULL)
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET * q_s, prs_struct * ps,
+BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET * q_s, prs_struct *ps,
int depth)
{
if (q_s == NULL)
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET * r_s, prs_struct * ps,
+BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET * r_s, prs_struct *ps,
int depth)
{
if (r_s == NULL)
/*******************************************************************
reads or writes an NET_ID_INFO_1 structure.
********************************************************************/
-static BOOL net_io_id_info1(char *desc, NET_ID_INFO_1 * id, prs_struct * ps,
+static BOOL net_io_id_info1(char *desc, NET_ID_INFO_1 * id, prs_struct *ps,
int depth)
{
if (id == NULL)
/*******************************************************************
reads or writes an NET_ID_INFO_4 structure.
********************************************************************/
-static BOOL net_io_id_info4(char *desc, NET_ID_INFO_4 * id, prs_struct * ps,
+static BOOL net_io_id_info4(char *desc, NET_ID_INFO_4 * id, prs_struct *ps,
int depth)
{
if (id == NULL)
/*******************************************************************
reads or writes an NET_ID_INFO_2 structure.
********************************************************************/
-static BOOL net_io_id_info2(char *desc, NET_ID_INFO_2 * id, prs_struct * ps,
+static BOOL net_io_id_info2(char *desc, NET_ID_INFO_2 * id, prs_struct *ps,
int depth)
{
if (id == NULL)
make_clnt_info2(&(sam->client), logon_srv, comp_name, clnt_cred);
- if (rtn_cred != NULL)
- {
- sam->ptr_rtn_cred = 1;
- memcpy(&(sam->rtn_cred), rtn_cred, sizeof(sam->rtn_cred));
- }
- else
- {
- sam->ptr_rtn_cred = 0;
- }
-
+ sam->ptr_rtn_cred =
+ Memcpy(&sam->rtn_cred, rtn_cred, sizeof(sam->rtn_cred));
sam->logon_level = logon_level;
sam->ctr = ctr;
reads or writes a DOM_SAM_INFO structure.
********************************************************************/
static BOOL net_io_id_info_ctr(char *desc, NET_ID_INFO_CTR * ctr,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (ctr == NULL)
return False;
/*******************************************************************
reads or writes a DOM_SAM_INFO structure.
********************************************************************/
-static BOOL smb_io_sam_info(char *desc, DOM_SAM_INFO * sam, prs_struct * ps,
+static BOOL smb_io_sam_info(char *desc, DOM_SAM_INFO * sam, prs_struct *ps,
int depth)
{
if (sam == NULL)
const NTTIME * pass_last_set_time,
const NTTIME * pass_can_change_time,
const NTTIME * pass_must_change_time,
- const UNISTR2 * user_name,
- const UNISTR2 * full_name,
- const UNISTR2 * log_scr,
- const UNISTR2 * prof_path,
- const UNISTR2 * home_dir,
- const UNISTR2 * dir_drive,
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
uint16 logon_count,
uint16 bad_pw_count,
uint32 user_id,
const DOM_GID * gids,
uint32 user_flgs,
const char sess_key[16],
- const UNISTR2 * logon_srv,
- const UNISTR2 * logon_dom,
- const char *padding, const DOM_SID * dom_sid)
+ const UNISTR2 *logon_srv,
+ const UNISTR2 *logon_dom,
+ const char *padding, const DOM_SID *dom_sid)
{
/* only cope with one "other" sid, right now. */
/* need to count the number of space-delimited sids */
usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
usr->user_flgs = user_flgs;
- if (sess_key != NULL)
- {
- memcpy(usr->user_sess_key, sess_key,
- sizeof(usr->user_sess_key));
- }
- else
- {
- ZERO_STRUCT(usr->user_sess_key);
- }
+ Memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key));
make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv);
make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom);
usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, put a domain SID in */
- ZERO_STRUCT(usr->padding);
- if (padding != NULL)
- {
- memcpy(usr->padding, padding, 8);
- }
+ Memcpy(usr->padding, padding, sizeof(usr->padding));
copy_unistr2(&(usr->uni_user_name), user_name);
copy_unistr2(&(usr->uni_full_name), full_name);
uint32 user_flgs,
char sess_key[16],
char *logon_srv,
- char *logon_dom, char *padding, DOM_SID * dom_sid)
+ char *logon_dom, char *padding, DOM_SID *dom_sid)
{
/* only cope with one "other" sid, right now. */
/* need to count the number of space-delimited sids */
usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
usr->user_flgs = user_flgs;
- if (sess_key != NULL)
- {
- memcpy(usr->user_sess_key, sess_key,
- sizeof(usr->user_sess_key));
- }
- else
- {
- ZERO_STRUCT(usr->user_sess_key);
- }
+ Memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key));
make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv);
make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom);
usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
- ZERO_STRUCT(usr->padding);
- if (padding != NULL)
- {
- memcpy(usr->padding, padding, 8);
- }
+ Memcpy(usr->padding, padding, sizeof(usr->padding));
make_unistr2(&(usr->uni_user_name), user_name, len_user_name);
make_unistr2(&(usr->uni_full_name), full_name, len_full_name);
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL net_io_user_info2(char *desc, NET_USER_INFO_2 * usr, prs_struct * ps,
+BOOL net_io_user_info2(char *desc, NET_USER_INFO_2 * usr, prs_struct *ps,
int depth)
{
uint32 i;
net_user_info_3_copy_from_ctr
*************************************************************************/
BOOL net_user_info_3_copy_from_ctr(NET_USER_INFO_3 * usr,
- const NET_USER_INFO_CTR *ctr)
+ const NET_USER_INFO_CTR * ctr)
{
ZERO_STRUCTP(usr);
if (ctr->ptr_user_info == 0)
{
const NET_USER_INFO_2 *usr2 = ctr->usr.id2;
if (!make_net_user_info3W(usr,
- &usr2->logon_time,
- &usr2->logoff_time,
- &usr2->kickoff_time,
- &usr2->pass_last_set_time,
- &usr2->pass_can_change_time,
- &usr2->pass_must_change_time,
- &usr2->uni_user_name,
- &usr2->uni_full_name,
- &usr2->uni_logon_script,
- &usr2->uni_profile_path,
- &usr2->uni_home_dir,
- &usr2->uni_dir_drive,
- usr2->logon_count,
- usr2->bad_pw_count,
- usr2->user_id,
- usr2->group_id,
- usr2->num_groups,
- usr2->gids,
- usr2->user_flgs,
- usr2->user_sess_key,
- &usr2->uni_logon_srv,
- &usr2->uni_logon_dom,
- usr2->padding,
- &usr2->dom_sid.sid, NULL))
+ &usr2->logon_time,
+ &usr2->logoff_time,
+ &usr2->kickoff_time,
+ &usr2->pass_last_set_time,
+ &usr2->pass_can_change_time,
+ &usr2->
+ pass_must_change_time,
+ &usr2->uni_user_name,
+ &usr2->uni_full_name,
+ &usr2->uni_logon_script,
+ &usr2->uni_profile_path,
+ &usr2->uni_home_dir,
+ &usr2->uni_dir_drive,
+ usr2->logon_count,
+ usr2->bad_pw_count,
+ usr2->user_id,
+ usr2->group_id,
+ usr2->num_groups,
+ usr2->gids, usr2->user_flgs,
+ usr2->user_sess_key,
+ &usr2->uni_logon_srv,
+ &usr2->uni_logon_dom,
+ usr2->padding,
+ &usr2->dom_sid.sid, NULL))
{
return False;
}
}
default:
{
- DEBUG(0,("invalid NET_USER_INFO_X info class\n"));
+ DEBUG(0, ("invalid NET_USER_INFO_X info class\n"));
return False;
}
}
const NTTIME * pass_last_set_time,
const NTTIME * pass_can_change_time,
const NTTIME * pass_must_change_time,
- const UNISTR2 * user_name,
- const UNISTR2 * full_name,
- const UNISTR2 * log_scr,
- const UNISTR2 * prof_path,
- const UNISTR2 * home_dir,
- const UNISTR2 * dir_drive,
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
uint16 logon_count,
uint16 bad_pw_count,
uint32 user_id,
const DOM_GID * gids,
uint32 user_flgs,
const char sess_key[16],
- const UNISTR2 * logon_srv,
- const UNISTR2 * logon_dom,
+ const UNISTR2 *logon_srv,
+ const UNISTR2 *logon_dom,
const char *padding,
- const DOM_SID * dom_sid, const char *other_sids)
+ const DOM_SID *dom_sid, const char *other_sids)
{
/* only cope with one "other" sid, right now. */
/* need to count the number of space-delimited sids */
usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
usr->user_flgs = user_flgs;
- if (sess_key != NULL)
- {
- memcpy(usr->user_sess_key, sess_key,
- sizeof(usr->user_sess_key));
- }
- else
- {
- ZERO_STRUCT(usr->user_sess_key);
- }
+ Memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key));
make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv);
make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom);
usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, put a domain SID in */
- ZERO_STRUCT(usr->padding);
- if (padding != NULL)
- {
- memcpy(usr->padding, padding, 8);
- }
+ Memcpy(usr->padding, padding, sizeof(usr->padding));
num_other_sids =
make_dom_sid2s(other_sids, usr->other_sids, LSA_MAX_SIDS);
char sess_key[16],
char *logon_srv,
char *logon_dom,
- char *padding, DOM_SID * dom_sid, char *other_sids)
+ char *padding, DOM_SID *dom_sid, char *other_sids)
{
/* only cope with one "other" sid, right now. */
/* need to count the number of space-delimited sids */
usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
usr->user_flgs = user_flgs;
- if (sess_key != NULL)
- {
- memcpy(usr->user_sess_key, sess_key,
- sizeof(usr->user_sess_key));
- }
- else
- {
- ZERO_STRUCT(usr->user_sess_key);
- }
+ Memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key));
make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv);
make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom);
usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
- ZERO_STRUCT(usr->padding);
- if (padding != NULL)
- {
- memcpy(usr->padding, padding, 8);
- }
+ Memcpy(usr->padding, padding, sizeof(usr->padding));
num_other_sids =
make_dom_sid2s(other_sids, usr->other_sids, LSA_MAX_SIDS);
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 * usr, prs_struct * ps,
+BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 * usr, prs_struct *ps,
int depth)
{
uint32 i;
smb_io_time("kickoff_time", &(usr->kickoff_time), ps, depth); /* kickoff time */
smb_io_time("pass_last_set_time", &(usr->pass_last_set_time), ps, depth); /* password last set time */
smb_io_time("pass_can_change_time", &(usr->pass_can_change_time), ps, depth); /* password can change time */
- smb_io_time("pass_must_change_time", &(usr->pass_must_change_time), ps, depth); /* password must change time */
+ smb_io_time("pass_must_change_time", &(usr->pass_must_change_time),
+ ps, depth); /* password must change time */
smb_io_unihdr("hdr_user_name", &(usr->hdr_user_name), ps, depth); /* username unicode string header */
smb_io_unihdr("hdr_full_name", &(usr->hdr_full_name), ps, depth); /* user's full name unicode string header */
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON * q_l, prs_struct * ps,
+BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON * q_l, prs_struct *ps,
int depth)
{
if (q_l == NULL)
********************************************************************/
BOOL make_r_sam_logon(NET_R_SAM_LOGON * r_s,
const DOM_CRED * srv_creds,
- uint16 switch_value,
- void *id, uint32 status)
+ uint16 switch_value, void *id, uint32 status)
{
if (r_s == NULL)
return False;
if (id != NULL)
{
r_s->ctr.ptr_user_info = 1;
- r_s->ctr.switch_value = switch_value;
+ r_s->ctr.switch_value = switch_value;
}
else
{
reads or writes a structure.
********************************************************************/
BOOL net_io_user_info_ctr(char *desc, NET_USER_INFO_CTR * ctr,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (ctr == NULL)
return False;
{
if (UNMARSHALLING(ps))
{
- ctr->usr.id2 = g_new(NET_USER_INFO_2, 1);
+ ctr->usr.id2 =
+ g_new(NET_USER_INFO_2, 1);
}
if (ctr->usr.id == NULL)
{
{
if (UNMARSHALLING(ps))
{
- ctr->usr.id3 = g_new(NET_USER_INFO_3, 1);
+ ctr->usr.id3 =
+ g_new(NET_USER_INFO_3, 1);
}
if (ctr->usr.id == NULL)
{
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON * r_l, prs_struct * ps,
+BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON * r_l, prs_struct *ps,
int depth)
{
if (r_l == NULL)
depth++;
prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds);
- smb_io_cred("", &(r_l->srv_creds), ps, depth);
+ smb_io_cred("", &(r_l->srv_creds), ps, depth);
net_io_user_info_ctr("", &r_l->ctr, ps, depth);
- prs_uint32("auth_resp ", ps, depth, &r_l->auth_resp);
+ prs_uint32("auth_resp ", ps, depth, &r_l->auth_resp);
prs_uint32("status ", ps, depth, &r_l->status);
prs_align(ps);
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF * q_l, prs_struct * ps,
+BOOL net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF * q_l, prs_struct *ps,
int depth)
{
if (q_l == NULL)
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF * r_l, prs_struct * ps,
+BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF * r_l, prs_struct *ps,
int depth)
{
if (r_l == NULL)
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC * q_s, prs_struct * ps,
+BOOL net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC * q_s, prs_struct *ps,
int depth)
{
if (q_s == NULL)
reads or writes a structure.
********************************************************************/
static BOOL net_io_sam_delta_hdr(char *desc, SAM_DELTA_HDR * delta,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (delta == NULL)
return False;
reads or writes a structure.
********************************************************************/
static BOOL net_io_sam_domain_info(char *desc, SAM_DOMAIN_INFO * info,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (info == NULL)
return False;
reads or writes a structure.
********************************************************************/
static BOOL net_io_sam_group_info(char *desc, SAM_GROUP_INFO * info,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (info == NULL)
return False;
makes a SAM_ACCOUNT_INFO structure.
********************************************************************/
BOOL make_sam_account_info(SAM_ACCOUNT_INFO * info,
- const UNISTR2 * user_name,
- const UNISTR2 * full_name,
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
uint32 user_rid, uint32 group_rid,
- const UNISTR2 * home_dir,
- const UNISTR2 * dir_drive,
- const UNISTR2 * log_scr,
- const UNISTR2 * desc,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *desc,
uint32 acb_info,
- const UNISTR2 * prof_path,
- const UNISTR2 * wkstas,
- const UNISTR2 * unk_str, const UNISTR2 * mung_dial)
+ const UNISTR2 *prof_path,
+ const UNISTR2 *wkstas,
+ const UNISTR2 *unk_str, const UNISTR2 *mung_dial)
{
int len_user_name = user_name != NULL ? user_name->uni_str_len : 0;
int len_full_name = full_name != NULL ? full_name->uni_str_len : 0;
reads or writes a structure.
********************************************************************/
static BOOL net_io_sam_passwd_info(char *desc, SAM_PWD * pwd,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (pwd == NULL)
return False;
reads or writes a structure.
********************************************************************/
static BOOL net_io_sam_account_info(char *desc, uint8 sess_key[16],
- SAM_ACCOUNT_INFO * info, prs_struct * ps,
+ SAM_ACCOUNT_INFO * info, prs_struct *ps,
int depth)
{
BUFHDR2 hdr_priv_data;
reads or writes a structure.
********************************************************************/
static BOOL net_io_sam_group_mem_info(char *desc, SAM_GROUP_MEM_INFO * info,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
uint32 i;
fstring tmp;
reads or writes a structure.
********************************************************************/
static BOOL net_io_sam_alias_info(char *desc, SAM_ALIAS_INFO * info,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (info == NULL)
return False;
reads or writes a structure.
********************************************************************/
static BOOL net_io_sam_alias_mem_info(char *desc, SAM_ALIAS_MEM_INFO * info,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
uint32 i;
fstring tmp;
********************************************************************/
static BOOL net_io_sam_delta_ctr(char *desc, uint8 sess_key[16],
SAM_DELTA_CTR * delta, uint16 type,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (delta == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL net_io_r_sam_sync(char *desc, uint8 sess_key[16],
- NET_R_SAM_SYNC * r_s, prs_struct * ps, int depth)
+ NET_R_SAM_SYNC * r_s, prs_struct *ps, int depth)
{
uint32 i;
/*******************************************************************
checks an RPC_HDR_AUTH structure.
********************************************************************/
-BOOL rpc_hdr_netsec_auth_chk(RPC_HDR_AUTH *rai)
+BOOL rpc_hdr_netsec_auth_chk(RPC_HDR_AUTH * rai)
{
return (rai->auth_type == 0x44 && rai->auth_level == 0x06);
}
/*******************************************************************
creates an RPC_AUTH_NETSEC_NEG structure.
********************************************************************/
-BOOL make_rpc_auth_netsec_neg(RPC_AUTH_NETSEC_NEG *neg,
- fstring domain,
- fstring myname)
+BOOL make_rpc_auth_netsec_neg(RPC_AUTH_NETSEC_NEG * neg,
+ fstring domain, fstring myname)
{
- if (neg == NULL) return False;
+ if (neg == NULL)
+ return False;
fstrcpy(neg->domain, domain);
fstrcpy(neg->myname, myname);
*** lkclXXXX HACK ALERT! ***
********************************************************************/
-BOOL smb_io_rpc_auth_netsec_neg(char *desc, RPC_AUTH_NETSEC_NEG *neg, prs_struct *ps, int depth)
+BOOL smb_io_rpc_auth_netsec_neg(char *desc, RPC_AUTH_NETSEC_NEG * neg,
+ prs_struct *ps, int depth)
{
- if (neg == NULL) return False;
+ if (neg == NULL)
+ return False;
prs_debug(ps, depth, desc, "smb_io_rpc_auth_netsec_neg");
depth++;
- prs_string("domain", ps, depth, neg->domain, 0, sizeof(neg->domain));
- prs_string("myname", ps, depth, neg->myname, 0, sizeof(neg->myname));
+ prs_string("domain", ps, depth, neg->domain, 0, sizeof(neg->domain));
+ prs_string("myname", ps, depth, neg->myname, 0, sizeof(neg->myname));
return True;
}
*** lkclXXXX the actual offset is at the start of the auth verifier ***
********************************************************************/
-BOOL make_rpc_auth_netsec_resp(RPC_AUTH_NETSEC_RESP *rsp, uint32 flags)
+BOOL make_rpc_auth_netsec_resp(RPC_AUTH_NETSEC_RESP * rsp, uint32 flags)
{
- DEBUG(5,("make_rpc_auth_netsec_resp\n"));
+ DEBUG(5, ("make_rpc_auth_netsec_resp\n"));
- if (rsp == NULL) return False;
+ if (rsp == NULL)
+ return False;
rsp->flags = flags;
*** lkclXXXX the actual offset is at the start of the auth verifier ***
********************************************************************/
-BOOL smb_io_rpc_auth_netsec_resp(char *desc, RPC_AUTH_NETSEC_RESP *rsp, prs_struct *ps, int depth)
+BOOL smb_io_rpc_auth_netsec_resp(char *desc, RPC_AUTH_NETSEC_RESP * rsp,
+ prs_struct *ps, int depth)
{
- if (rsp == NULL) return False;
+ if (rsp == NULL)
+ return False;
prs_debug(ps, depth, desc, "smb_io_rpc_auth_netsec_resp");
depth++;
- prs_uint32("flags", ps, depth, &rsp->flags);
+ prs_uint32("flags", ps, depth, &rsp->flags);
return True;
}
/*******************************************************************
checks an RPC_AUTH_NETSEC_CHK structure.
********************************************************************/
-BOOL rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK *chk)
+BOOL rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK * chk)
{
static const uchar netsec_sig[8] = NETSEC_SIGNATURE;
/*******************************************************************
creates an RPC_AUTH_NETSEC_CHK structure.
********************************************************************/
-BOOL make_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK *chk,
- const uchar sig[8],
- const uchar data1[8],
- const uchar data3[8],
- const uchar data8[8])
+BOOL make_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK * chk,
+ const uchar sig[8],
+ const uchar data1[8],
+ const uchar data3[8], const uchar data8[8])
{
- if (chk == NULL) return False;
+ if (chk == NULL)
+ return False;
- if (sig != NULL)
- {
- memcpy(chk->sig , sig , sizeof(chk->sig ));
- }
- if (data1 != NULL)
- {
- memcpy(chk->data1, data1, sizeof(chk->data1));
- }
- if (data3 != NULL)
- {
- memcpy(chk->data3, data3, sizeof(chk->data3));
- }
- if (data8 != NULL)
- {
- memcpy(chk->data8, data8, sizeof(chk->data8));
- }
+ Memcpy(chk->sig, sig, sizeof(chk->sig));
+ Memcpy(chk->data1, data1, sizeof(chk->data1));
+ Memcpy(chk->data3, data3, sizeof(chk->data3));
+ Memcpy(chk->data8, data8, sizeof(chk->data8));
return True;
}
/*******************************************************************
reads or writes an RPC_AUTH_NETSEC_CHK structure.
********************************************************************/
-BOOL smb_io_rpc_auth_netsec_chk(char *desc, RPC_AUTH_NETSEC_CHK *chk, prs_struct *ps, int depth)
+BOOL smb_io_rpc_auth_netsec_chk(char *desc, RPC_AUTH_NETSEC_CHK * chk,
+ prs_struct *ps, int depth)
{
- if (chk == NULL) return False;
+ if (chk == NULL)
+ return False;
prs_debug(ps, depth, desc, "smb_io_rpc_auth_netsec_chk");
depth++;
- prs_uint8s(False, "sig ", ps, depth, chk->sig , sizeof(chk->sig ));
+ prs_uint8s(False, "sig ", ps, depth, chk->sig, sizeof(chk->sig));
prs_uint8s(False, "data3", ps, depth, chk->data3, sizeof(chk->data3));
prs_uint8s(False, "data1", ps, depth, chk->data1, sizeof(chk->data1));
prs_uint8s(False, "data8", ps, depth, chk->data8, sizeof(chk->data8));
return True;
}
-static void netsechash(uchar *key, uchar *data, int data_len)
+static void netsechash(uchar * key, uchar * data, int data_len)
{
- uchar hash[256];
- uchar index_i = 0;
- uchar index_j = 0;
- uchar j = 0;
- int ind;
-
- for (ind = 0; ind < 256; ind++)
- {
- hash[ind] = (uchar)ind;
- }
-
- for( ind = 0; ind < 256; ind++)
- {
- uchar tc;
-
- j += (hash[ind] + key[ind%16]);
-
- tc = hash[ind];
- hash[ind] = hash[j];
- hash[j] = tc;
- }
-
- for( ind = 0; ind < data_len; ind++)
- {
- uchar tc;
- uchar 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];
- }
+ uchar hash[256];
+ uchar index_i = 0;
+ uchar index_j = 0;
+ uchar j = 0;
+ int ind;
+
+ for (ind = 0; ind < 256; ind++)
+ {
+ hash[ind] = (uchar) ind;
+ }
+
+ for (ind = 0; ind < 256; ind++)
+ {
+ uchar tc;
+
+ j += (hash[ind] + key[ind % 16]);
+
+ tc = hash[ind];
+ hash[ind] = hash[j];
+ hash[j] = tc;
+ }
+
+ for (ind = 0; ind < data_len; ind++)
+ {
+ uchar tc;
+ uchar 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];
+ }
}
BOOL netsec_encode(struct netsec_auth_struct *a,
- RPC_AUTH_NETSEC_CHK *verf,
- char *data, size_t data_len)
+ RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len)
{
char dataN[4];
- char digest1[16];
- struct MD5Context ctx3;
+ char digest1[16];
+ struct MD5Context ctx3;
uchar sess_kf0[16];
int i;
MD5Update(&ctx3, dataN, 0x4);
MD5Update(&ctx3, verf->sig, 8);
- MD5Update(&ctx3, verf->data8, 8);
+ MD5Update(&ctx3, verf->data8, 8);
dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8));
dump_data_pw("sess_kf0:\n", sess_kf0, sizeof(sess_kf0));
- hmac_md5(sess_kf0, dataN, 0x4, digest1 );
+ hmac_md5(sess_kf0, dataN, 0x4, digest1);
dump_data_pw("digest1 (ebp-8):\n", digest1, sizeof(digest1));
hmac_md5(digest1, verf->data3, 8, digest1);
dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1));
dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8));
dump_data_pw("data :\n", data, data_len);
- MD5Update(&ctx3, data, data_len);
+ MD5Update(&ctx3, data, data_len);
{
char digest_tmp[16];
memcpy(verf->data1, digest2, sizeof(verf->data1));
}
- netsechash(digest1, data , data_len);
+ netsechash(digest1, data, data_len);
dump_data_pw("data:\n", data, data_len);
- hmac_md5(a->sess_key, dataN , 0x4, digest1 );
+ hmac_md5(a->sess_key, dataN, 0x4, digest1);
dump_data_pw("ctx:\n", digest1, sizeof(digest1));
hmac_md5(digest1, verf->data1, 8, digest1);
netsechash(digest1, verf->data3, 8);
dump_data_pw("verf->data3:\n", verf->data3, sizeof(verf->data3));
-
return True;
}
BOOL netsec_decode(struct netsec_auth_struct *a,
- RPC_AUTH_NETSEC_CHK *verf,
- char *data, size_t data_len)
+ RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len)
{
char dataN[4];
- char digest1[16];
- struct MD5Context ctx3;
+ char digest1[16];
+ struct MD5Context ctx3;
uchar sess_kf0[16];
int i;
dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key));
dump_data_pw("a->seq_num :\n", dataN, sizeof(dataN));
- hmac_md5(a->sess_key, dataN , 0x4, digest1 );
+ hmac_md5(a->sess_key, dataN, 0x4, digest1);
dump_data_pw("ctx:\n", digest1, sizeof(digest1));
hmac_md5(digest1, verf->data1, 8, digest1);
dump_data_pw("sess_kf0:\n", sess_kf0, sizeof(sess_kf0));
- hmac_md5(sess_kf0, dataN, 0x4, digest1 );
+ hmac_md5(sess_kf0, dataN, 0x4, digest1);
dump_data_pw("digest1 (ebp-8):\n", digest1, sizeof(digest1));
hmac_md5(digest1, verf->data3, 8, digest1);
dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1));
dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8));
netsechash(digest1, verf->data8, 8);
dump_data_pw("verf->data8_dec:\n", verf->data8, sizeof(verf->data8));
- MD5Update(&ctx3, verf->data8, 8);
+ MD5Update(&ctx3, verf->data8, 8);
dump_data_pw("data :\n", data, data_len);
- netsechash(digest1, data , data_len);
+ netsechash(digest1, data, data_len);
dump_data_pw("datadec:\n", data, data_len);
- MD5Update(&ctx3, data, data_len);
+ MD5Update(&ctx3, data, data_len);
{
char digest_tmp[16];
MD5Final(digest_tmp, &ctx3);
void prs_mem_free(prs_struct *ps)
{
- if (ps->data)
- free(ps->data);
+ safe_free(ps->data);
ps->data = NULL;
ps->offset = 0;
}
return False;
}
- DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, data8s,
- len) ps->offset = end_offset;
+ DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, data8s, len);
+ ps->offset = end_offset;
return True;
}
}
DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q,
- str->buffer, str->buf_len) ps->offset = end_offset;
+ str->buffer, str->buf_len);
+ ps->offset = end_offset;
return True;
}
}
DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q,
- str->buffer, str->str_str_len) ps->offset = end_offset;
+ str->buffer, str->str_str_len);
+ ps->offset = end_offset;
return True;
}
/*******************************************************************
creates a structure.
********************************************************************/
-BOOL make_reg_q_open_hkcr(REG_Q_OPEN_HKCR *q_o,
- uint16 unknown_0, uint32 level)
+BOOL make_reg_q_open_hkcr(REG_Q_OPEN_HKCR * q_o,
+ uint16 unknown_0, uint32 level)
{
q_o->ptr = 1;
q_o->unknown_0 = unknown_0;
- q_o->unknown_1 = 0x0; /* random - changes */
+ q_o->unknown_1 = 0x0; /* random - changes */
q_o->level = level;
return True;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_open_hkcr(char *desc, REG_Q_OPEN_HKCR *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_open_hkcr(char *desc, REG_Q_OPEN_HKCR * r_q, prs_struct *ps,
+ int depth)
{
- if (r_q == NULL) return False;
+ if (r_q == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_q_open_hkcr");
depth++;
prs_align(ps);
-
- prs_uint32("ptr ", ps, depth, &(r_q->ptr ));
+
+ prs_uint32("ptr ", ps, depth, &(r_q->ptr));
if (r_q->ptr != 0)
{
prs_uint16("unknown_0", ps, depth, &(r_q->unknown_0));
prs_uint16("unknown_1", ps, depth, &(r_q->unknown_1));
- prs_uint32("level ", ps, depth, &(r_q->level ));
+ prs_uint32("level ", ps, depth, &(r_q->level));
}
return True;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_open_hkcr(char *desc, REG_R_OPEN_HKCR *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_open_hkcr(char *desc, REG_R_OPEN_HKCR * r_r, prs_struct *ps,
+ int depth)
{
- if (r_r == NULL) return False;
+ if (r_r == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_r_open_hkcr");
depth++;
prs_align(ps);
-
+
smb_io_pol_hnd("", &(r_r->pol), ps, depth);
prs_uint32("status", ps, depth, &(r_r->status));
/*******************************************************************
creates a structure.
********************************************************************/
-BOOL make_reg_q_open_hklm(REG_Q_OPEN_HKLM *q_o,
- uint16 unknown_0, uint32 access_mask)
+BOOL make_reg_q_open_hklm(REG_Q_OPEN_HKLM * q_o,
+ uint16 unknown_0, uint32 access_mask)
{
q_o->ptr = 1;
q_o->unknown_0 = unknown_0;
- q_o->unknown_1 = 0x0; /* random - changes */
+ q_o->unknown_1 = 0x0; /* random - changes */
q_o->access_mask = access_mask;
return True;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_open_hklm(char *desc, REG_Q_OPEN_HKLM *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_open_hklm(char *desc, REG_Q_OPEN_HKLM * r_q, prs_struct *ps,
+ int depth)
{
- if (r_q == NULL) return False;
+ if (r_q == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_q_open_hklm");
depth++;
prs_align(ps);
-
- prs_uint32("ptr ", ps, depth, &(r_q->ptr ));
+
+ prs_uint32("ptr ", ps, depth, &(r_q->ptr));
if (r_q->ptr != 0)
{
prs_uint16("unknown_0", ps, depth, &(r_q->unknown_0));
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_open_hklm(char *desc, REG_R_OPEN_HKLM *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_open_hklm(char *desc, REG_R_OPEN_HKLM * r_r, prs_struct *ps,
+ int depth)
{
- if (r_r == NULL) return False;
+ if (r_r == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_r_open_hklm");
depth++;
prs_align(ps);
-
+
smb_io_pol_hnd("", &(r_r->pol), ps, depth);
prs_uint32("status", ps, depth, &(r_r->status));
/*******************************************************************
creates a structure.
********************************************************************/
-BOOL make_reg_q_flush_key(REG_Q_FLUSH_KEY *q_u, POLICY_HND *pol)
+BOOL make_reg_q_flush_key(REG_Q_FLUSH_KEY * q_u, POLICY_HND *pol)
{
- memcpy(&(q_u->pol), pol, sizeof(q_u->pol));
+ q_u->pol = *pol;
return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_flush_key(char *desc, REG_Q_FLUSH_KEY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_flush_key(char *desc, REG_Q_FLUSH_KEY * r_q, prs_struct *ps,
+ int depth)
{
- if (r_q == NULL) return False;
+ if (r_q == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_q_flush_key");
depth++;
prs_align(ps);
-
+
smb_io_pol_hnd("", &(r_q->pol), ps, depth);
return True;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_flush_key(char *desc, REG_R_FLUSH_KEY *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_flush_key(char *desc, REG_R_FLUSH_KEY * r_r, prs_struct *ps,
+ int depth)
{
- if (r_r == NULL) return False;
+ if (r_r == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_r_flush_key");
depth++;
prs_align(ps);
-
+
prs_uint32("status", ps, depth, &(r_r->status));
return True;
/*******************************************************************
reads or writes SEC_DESC_BUF and SEC_DATA structures.
********************************************************************/
-static BOOL reg_io_hdrbuf_sec(uint32 ptr, uint32 *ptr3, BUFHDR *hdr_sec,
- SEC_DESC_BUF *data, prs_struct *ps, int depth)
+static BOOL reg_io_hdrbuf_sec(uint32 ptr, uint32 *ptr3, BUFHDR * hdr_sec,
+ SEC_DESC_BUF * data, prs_struct *ps, int depth)
{
if (ptr != 0)
{
}
if (ptr3 == NULL || *ptr3 != 0)
{
- sec_io_desc_buf("data ", data , ps, depth);
+ sec_io_desc_buf("data ", data, ps, depth);
}
smb_io_hdrbuf_post("hdr_sec", hdr_sec, ps, depth, hdr_offset,
- data->max_len, data->len);
- ps->offset = old_offset + data->len + sizeof(uint32) * ((ptr3 != NULL) ? 5 : 3);
+ data->max_len, data->len);
+ ps->offset =
+ old_offset + data->len +
+ sizeof(uint32) * ((ptr3 != NULL) ? 5 : 3);
prs_align(ps);
}
/*******************************************************************
creates a structure.
********************************************************************/
-BOOL make_reg_q_create_key(REG_Q_CREATE_KEY *q_c, POLICY_HND *hnd,
- char *key_name, char *key_class,
- SEC_ACCESS *sam_access,
- SEC_DESC_BUF *sec_buf,
- int sec_len, SEC_DESC *sec)
+BOOL make_reg_q_create_key(REG_Q_CREATE_KEY * q_c, POLICY_HND *hnd,
+ char *key_name, char *key_class,
+ SEC_ACCESS * sam_access,
+ SEC_DESC_BUF * sec_buf,
+ int sec_len, SEC_DESC * sec)
{
- int len_name = key_name != NULL ? strlen(key_name ) + 1: 0;
- int len_class = key_class != NULL ? strlen(key_class) + 1: 0;
+ int len_name = key_name != NULL ? strlen(key_name) + 1 : 0;
+ int len_class = key_class != NULL ? strlen(key_class) + 1 : 0;
ZERO_STRUCTP(q_c);
- memcpy(&(q_c->pnt_pol), hnd, sizeof(q_c->pnt_pol));
+ q_c->pnt_pol = *hnd;
make_uni_hdr(&(q_c->hdr_name), len_name);
make_unistr2(&(q_c->uni_name), key_name, len_name);
make_unistr2(&(q_c->uni_class), key_class, len_class);
q_c->reserved = 0x00000000;
- memcpy(&(q_c->sam_access), sam_access, sizeof(q_c->sam_access));
+ q_c->sam_access = *sam_access;
q_c->ptr1 = 1;
q_c->sec_info = DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_create_key(char *desc, REG_Q_CREATE_KEY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_create_key(char *desc, REG_Q_CREATE_KEY * r_q, prs_struct *ps,
+ int depth)
{
- if (r_q == NULL) return False;
+ if (r_q == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_q_create_key");
depth++;
prs_align(ps);
-
+
smb_io_pol_hnd("", &(r_q->pnt_pol), ps, depth);
- smb_io_unihdr ("", &(r_q->hdr_name), ps, depth);
+ smb_io_unihdr("", &(r_q->hdr_name), ps, depth);
smb_io_unistr2("", &(r_q->uni_name), r_q->hdr_name.buffer, ps, depth);
prs_align(ps);
- smb_io_unihdr ("", &(r_q->hdr_class), ps, depth);
- smb_io_unistr2("", &(r_q->uni_class), r_q->hdr_class.buffer, ps, depth);
+ smb_io_unihdr("", &(r_q->hdr_class), ps, depth);
+ smb_io_unistr2("", &(r_q->uni_class), r_q->hdr_class.buffer, ps,
+ depth);
prs_align(ps);
prs_uint32("reserved", ps, depth, &(r_q->reserved));
}
prs_uint32("ptr2", ps, depth, &(r_q->ptr2));
- reg_io_hdrbuf_sec(r_q->ptr2, &r_q->ptr3, &r_q->hdr_sec, r_q->data, ps, depth);
+ reg_io_hdrbuf_sec(r_q->ptr2, &r_q->ptr3, &r_q->hdr_sec, r_q->data, ps,
+ depth);
prs_uint32("unknown_2", ps, depth, &(r_q->unknown_2));
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_create_key(char *desc, REG_R_CREATE_KEY *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_create_key(char *desc, REG_R_CREATE_KEY * r_r, prs_struct *ps,
+ int depth)
{
- if (r_r == NULL) return False;
+ if (r_r == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_r_create_key");
depth++;
prs_align(ps);
-
+
smb_io_pol_hnd("", &(r_r->key_pol), ps, depth);
prs_uint32("unknown", ps, depth, &(r_r->unknown));
/*******************************************************************
creates a structure.
********************************************************************/
-BOOL make_reg_q_delete_val(REG_Q_DELETE_VALUE *q_c, POLICY_HND *hnd,
- char *name)
+BOOL make_reg_q_delete_val(REG_Q_DELETE_VALUE * q_c, POLICY_HND *hnd,
+ char *name)
{
- int len_name = name != NULL ? strlen(name ) + 1: 0;
+ int len_name = name != NULL ? strlen(name) + 1 : 0;
ZERO_STRUCTP(q_c);
- memcpy(&(q_c->pnt_pol), hnd, sizeof(q_c->pnt_pol));
+ q_c->pnt_pol = *hnd;
make_uni_hdr(&(q_c->hdr_name), len_name);
make_unistr2(&(q_c->uni_name), name, len_name);
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_delete_val(char *desc, REG_Q_DELETE_VALUE *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_delete_val(char *desc, REG_Q_DELETE_VALUE * r_q, prs_struct *ps,
+ int depth)
{
- if (r_q == NULL) return False;
+ if (r_q == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_q_delete_val");
depth++;
prs_align(ps);
-
+
smb_io_pol_hnd("", &(r_q->pnt_pol), ps, depth);
- smb_io_unihdr ("", &(r_q->hdr_name), ps, depth);
+ smb_io_unihdr("", &(r_q->hdr_name), ps, depth);
smb_io_unistr2("", &(r_q->uni_name), r_q->hdr_name.buffer, ps, depth);
prs_align(ps);
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_delete_val(char *desc, REG_R_DELETE_VALUE *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_delete_val(char *desc, REG_R_DELETE_VALUE * r_r, prs_struct *ps,
+ int depth)
{
- if (r_r == NULL) return False;
+ if (r_r == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_r_delete_val");
depth++;
prs_align(ps);
-
+
prs_uint32("status", ps, depth, &(r_r->status));
return True;
/*******************************************************************
creates a structure.
********************************************************************/
-BOOL make_reg_q_delete_key(REG_Q_DELETE_KEY *q_c, POLICY_HND *hnd,
- char *name)
+BOOL make_reg_q_delete_key(REG_Q_DELETE_KEY * q_c, POLICY_HND *hnd,
+ char *name)
{
- int len_name = name != NULL ? strlen(name ) + 1: 0;
+ int len_name = name != NULL ? strlen(name) + 1 : 0;
ZERO_STRUCTP(q_c);
- memcpy(&(q_c->pnt_pol), hnd, sizeof(q_c->pnt_pol));
+ q_c->pnt_pol = *hnd;
make_uni_hdr(&(q_c->hdr_name), len_name);
make_unistr2(&(q_c->uni_name), name, len_name);
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_delete_key(char *desc, REG_Q_DELETE_KEY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_delete_key(char *desc, REG_Q_DELETE_KEY * r_q, prs_struct *ps,
+ int depth)
{
- if (r_q == NULL) return False;
+ if (r_q == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_q_delete_key");
depth++;
prs_align(ps);
-
+
smb_io_pol_hnd("", &(r_q->pnt_pol), ps, depth);
- smb_io_unihdr ("", &(r_q->hdr_name), ps, depth);
+ smb_io_unihdr("", &(r_q->hdr_name), ps, depth);
smb_io_unistr2("", &(r_q->uni_name), r_q->hdr_name.buffer, ps, depth);
prs_align(ps);
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_delete_key(char *desc, REG_R_DELETE_KEY *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_delete_key(char *desc, REG_R_DELETE_KEY * r_r, prs_struct *ps,
+ int depth)
{
- if (r_r == NULL) return False;
+ if (r_r == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_r_delete_key");
depth++;
prs_align(ps);
-
+
prs_uint32("status", ps, depth, &(r_r->status));
return True;
/*******************************************************************
creates a structure.
********************************************************************/
-BOOL make_reg_q_query_key(REG_Q_QUERY_KEY *q_o, POLICY_HND *hnd,
- uint32 max_class_len)
+BOOL make_reg_q_query_key(REG_Q_QUERY_KEY * q_o, POLICY_HND *hnd,
+ uint32 max_class_len)
{
ZERO_STRUCTP(q_o);
- memcpy(&(q_o->pol), hnd, sizeof(q_o->pol));
+ q_o->pol = *hnd;
q_o->hdr_class.uni_str_len = 0;
q_o->hdr_class.uni_max_len = max_class_len * 2;
q_o->hdr_class.buffer = max_class_len > 0 ? 1 : 0;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_query_key(char *desc, REG_Q_QUERY_KEY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_query_key(char *desc, REG_Q_QUERY_KEY * r_q, prs_struct *ps,
+ int depth)
{
- if (r_q == NULL) return False;
+ if (r_q == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_q_query_key");
depth++;
prs_align(ps);
-
+
smb_io_pol_hnd("", &(r_q->pol), ps, depth);
- smb_io_unihdr ("", &(r_q->hdr_class), ps, depth);
- smb_io_unistr2("", &(r_q->uni_class), r_q->hdr_class.buffer, ps, depth);
+ smb_io_unihdr("", &(r_q->hdr_class), ps, depth);
+ smb_io_unistr2("", &(r_q->uni_class), r_q->hdr_class.buffer, ps,
+ depth);
prs_align(ps);
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_query_key(char *desc, REG_R_QUERY_KEY *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_query_key(char *desc, REG_R_QUERY_KEY * r_r, prs_struct *ps,
+ int depth)
{
- if (r_r == NULL) return False;
+ if (r_r == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_r_query_key");
depth++;
prs_align(ps);
-
- smb_io_unihdr ("", &(r_r->hdr_class), ps, depth);
- smb_io_unistr2("", &(r_r->uni_class), r_r->hdr_class.buffer, ps, depth);
+
+ smb_io_unihdr("", &(r_r->hdr_class), ps, depth);
+ smb_io_unistr2("", &(r_r->uni_class), r_r->hdr_class.buffer, ps,
+ depth);
prs_align(ps);
- prs_uint32("num_subkeys ", ps, depth, &(r_r->num_subkeys ));
- prs_uint32("max_subkeylen ", ps, depth, &(r_r->max_subkeylen ));
+ prs_uint32("num_subkeys ", ps, depth, &(r_r->num_subkeys));
+ prs_uint32("max_subkeylen ", ps, depth, &(r_r->max_subkeylen));
prs_uint32("mak_subkeysize", ps, depth, &(r_r->max_subkeysize));
- prs_uint32("num_values ", ps, depth, &(r_r->num_values ));
+ prs_uint32("num_values ", ps, depth, &(r_r->num_values));
prs_uint32("max_valnamelen", ps, depth, &(r_r->max_valnamelen));
prs_uint32("max_valbufsize", ps, depth, &(r_r->max_valbufsize));
- prs_uint32("sec_desc ", ps, depth, &(r_r->sec_desc ));
+ prs_uint32("sec_desc ", ps, depth, &(r_r->sec_desc));
smb_io_time("mod_time ", &(r_r->mod_time), ps, depth);
-
+
prs_uint32("status", ps, depth, &(r_r->status));
return True;
/*******************************************************************
creates a structure.
********************************************************************/
-BOOL make_reg_q_unk_1a(REG_Q_UNK_1A *q_o, POLICY_HND *hnd)
+BOOL make_reg_q_unk_1a(REG_Q_UNK_1A * q_o, POLICY_HND *hnd)
{
- memcpy(&(q_o->pol), hnd, sizeof(q_o->pol));
+ q_o->pol = *hnd;
return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_unk_1a(char *desc, REG_Q_UNK_1A *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_unk_1a(char *desc, REG_Q_UNK_1A * r_q, prs_struct *ps,
+ int depth)
{
- if (r_q == NULL) return False;
+ if (r_q == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_q_unk_1a");
depth++;
prs_align(ps);
-
+
smb_io_pol_hnd("", &(r_q->pol), ps, depth);
return True;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_unk_1a(char *desc, REG_R_UNK_1A *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_unk_1a(char *desc, REG_R_UNK_1A * r_r, prs_struct *ps,
+ int depth)
{
- if (r_r == NULL) return False;
+ if (r_r == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_r_unk_1a");
depth++;
prs_align(ps);
-
+
prs_uint32("unknown", ps, depth, &(r_r->unknown));
- prs_uint32("status" , ps, depth, &(r_r->status ));
+ prs_uint32("status", ps, depth, &(r_r->status));
return True;
}
/*******************************************************************
creates a structure.
********************************************************************/
-BOOL make_reg_q_open_hku(REG_Q_OPEN_HKU *q_o,
- uint16 unknown_0, uint32 level)
+BOOL make_reg_q_open_hku(REG_Q_OPEN_HKU * q_o, uint16 unknown_0, uint32 level)
{
q_o->ptr = 1;
q_o->unknown_0 = unknown_0;
- q_o->unknown_1 = 0x0; /* random - changes */
+ q_o->unknown_1 = 0x0; /* random - changes */
q_o->level = level;
return True;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_open_hku(char *desc, REG_Q_OPEN_HKU *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_open_hku(char *desc, REG_Q_OPEN_HKU * r_q, prs_struct *ps,
+ int depth)
{
- if (r_q == NULL) return False;
+ if (r_q == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_q_open_hku");
depth++;
prs_align(ps);
-
- prs_uint32("ptr ", ps, depth, &(r_q->ptr ));
+
+ prs_uint32("ptr ", ps, depth, &(r_q->ptr));
if (r_q->ptr != 0)
{
prs_uint16("unknown_0", ps, depth, &(r_q->unknown_0));
prs_uint16("unknown_1", ps, depth, &(r_q->unknown_1));
- prs_uint32("level ", ps, depth, &(r_q->level ));
+ prs_uint32("level ", ps, depth, &(r_q->level));
}
return True;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_open_hku(char *desc, REG_R_OPEN_HKU *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_open_hku(char *desc, REG_R_OPEN_HKU * r_r, prs_struct *ps,
+ int depth)
{
- if (r_r == NULL) return False;
+ if (r_r == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_r_open_hku");
depth++;
prs_align(ps);
-
+
smb_io_pol_hnd("", &(r_r->pol), ps, depth);
prs_uint32("status", ps, depth, &(r_r->status));
/*******************************************************************
makes an REG_Q_CLOSE structure.
********************************************************************/
-BOOL make_reg_q_close(REG_Q_CLOSE *q_c, POLICY_HND *hnd)
+BOOL make_reg_q_close(REG_Q_CLOSE * q_c, POLICY_HND *hnd)
{
- if (q_c == NULL || hnd == NULL) return False;
+ if (q_c == NULL || hnd == NULL)
+ return False;
- DEBUG(5,("make_reg_q_close\n"));
+ DEBUG(5, ("make_reg_q_close\n"));
- memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
+ q_c->pol = *hnd;
return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_close(char *desc, REG_Q_CLOSE *q_u, prs_struct *ps, int depth)
+BOOL reg_io_q_close(char *desc, REG_Q_CLOSE * q_u, prs_struct *ps, int depth)
{
- if (q_u == NULL) return False;
+ if (q_u == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_q_close");
depth++;
prs_align(ps);
- smb_io_pol_hnd("", &(q_u->pol), ps, depth);
+ smb_io_pol_hnd("", &(q_u->pol), ps, depth);
prs_align(ps);
return True;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_close(char *desc, REG_R_CLOSE *r_u, prs_struct *ps, int depth)
+BOOL reg_io_r_close(char *desc, REG_R_CLOSE * r_u, prs_struct *ps, int depth)
{
- if (r_u == NULL) return False;
+ if (r_u == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_r_close");
depth++;
prs_align(ps);
- smb_io_pol_hnd("", &(r_u->pol), ps, depth);
+ smb_io_pol_hnd("", &(r_u->pol), ps, depth);
prs_align(ps);
prs_uint32("status", ps, depth, &(r_u->status));
/*******************************************************************
makes a structure.
********************************************************************/
-BOOL make_reg_q_set_key_sec(REG_Q_SET_KEY_SEC *q_i, POLICY_HND *pol,
- uint32 sec_info,
- uint32 buf_len, SEC_DESC *sec_desc)
+BOOL make_reg_q_set_key_sec(REG_Q_SET_KEY_SEC * q_i, POLICY_HND *pol,
+ uint32 sec_info,
+ uint32 buf_len, SEC_DESC * sec_desc)
{
- if (q_i == NULL) return False;
+ if (q_i == NULL)
+ return False;
- memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
+ q_i->pol = *pol;
q_i->sec_info = sec_info;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_set_key_sec(char *desc, REG_Q_SET_KEY_SEC *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_set_key_sec(char *desc, REG_Q_SET_KEY_SEC * r_q, prs_struct *ps,
+ int depth)
{
- if (r_q == NULL) return False;
+ if (r_q == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_q_set_key_sec");
depth++;
prs_align(ps);
-
- smb_io_pol_hnd("", &(r_q->pol), ps, depth);
+
+ smb_io_pol_hnd("", &(r_q->pol), ps, depth);
prs_uint32("sec_info", ps, depth, &(r_q->sec_info));
- prs_uint32("ptr ", ps, depth, &(r_q->ptr ));
+ prs_uint32("ptr ", ps, depth, &(r_q->ptr));
- reg_io_hdrbuf_sec(r_q->ptr, NULL, &r_q->hdr_sec, r_q->data, ps, depth);
+ reg_io_hdrbuf_sec(r_q->ptr, NULL, &r_q->hdr_sec, r_q->data, ps,
+ depth);
return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_set_key_sec(char *desc, REG_R_SET_KEY_SEC *r_q, prs_struct *ps, int depth)
+BOOL reg_io_r_set_key_sec(char *desc, REG_R_SET_KEY_SEC * r_q, prs_struct *ps,
+ int depth)
{
- if (r_q == NULL) return False;
+ if (r_q == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_r_set_key_sec");
depth++;
prs_align(ps);
-
+
prs_uint32("status", ps, depth, &(r_q->status));
return True;
/*******************************************************************
makes a structure.
********************************************************************/
-BOOL make_reg_q_get_key_sec(REG_Q_GET_KEY_SEC *q_i, POLICY_HND *pol,
- uint32 sec_info,
- uint32 buf_len, SEC_DESC_BUF *sec_buf)
+BOOL make_reg_q_get_key_sec(REG_Q_GET_KEY_SEC * q_i, POLICY_HND *pol,
+ uint32 sec_info,
+ uint32 buf_len, SEC_DESC_BUF * sec_buf)
{
- if (q_i == NULL) return False;
+ if (q_i == NULL)
+ return False;
- memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
+ q_i->pol = *pol;
q_i->sec_info = sec_info;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_get_key_sec(char *desc, REG_Q_GET_KEY_SEC *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_get_key_sec(char *desc, REG_Q_GET_KEY_SEC * r_q, prs_struct *ps,
+ int depth)
{
- if (r_q == NULL) return False;
+ if (r_q == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_q_get_key_sec");
depth++;
prs_align(ps);
-
- smb_io_pol_hnd("", &(r_q->pol), ps, depth);
+
+ smb_io_pol_hnd("", &(r_q->pol), ps, depth);
prs_uint32("sec_info", ps, depth, &(r_q->sec_info));
- prs_uint32("ptr ", ps, depth, &(r_q->ptr ));
+ prs_uint32("ptr ", ps, depth, &(r_q->ptr));
- reg_io_hdrbuf_sec(r_q->ptr, NULL, &r_q->hdr_sec, r_q->data, ps, depth);
+ reg_io_hdrbuf_sec(r_q->ptr, NULL, &r_q->hdr_sec, r_q->data, ps,
+ depth);
return True;
}
/*******************************************************************
makes a structure.
********************************************************************/
- void make_reg_r_get_key_sec(REG_R_GET_KEY_SEC *r_i, POLICY_HND *pol,
- uint32 buf_len, uint8 *buf,
- uint32 status)
+void make_reg_r_get_key_sec(REG_R_GET_KEY_SEC * r_i, POLICY_HND *pol,
+ uint32 buf_len, uint8 *buf, uint32 status)
{
- if (r_i == NULL) return False;
+ if (r_i == NULL)
+ return False;
r_i->ptr = 1;
make_buf_hdr(&(r_i->hdr_sec), buf_len, buf_len);
make_sec_desc_buf(r_i->data, buf_len, 1);
- r_i->status = status; /* 0x0000 0000 or 0x0000 007a */
+ r_i->status = status; /* 0x0000 0000 or 0x0000 007a */
return True;
}
-#endif
+#endif
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_get_key_sec(char *desc, REG_R_GET_KEY_SEC *r_q, prs_struct *ps, int depth)
+BOOL reg_io_r_get_key_sec(char *desc, REG_R_GET_KEY_SEC * r_q, prs_struct *ps,
+ int depth)
{
- if (r_q == NULL) return False;
+ if (r_q == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_r_get_key_sec");
depth++;
prs_align(ps);
-
- prs_uint32("ptr ", ps, depth, &(r_q->ptr ));
+
+ prs_uint32("ptr ", ps, depth, &(r_q->ptr));
if (r_q->ptr != 0)
{
/*******************************************************************
makes a structure.
********************************************************************/
-BOOL make_reg_q_info(REG_Q_INFO *q_i, POLICY_HND *pol, const char *val_name,
- uint8 major, uint8 minor)
+BOOL make_reg_q_info(REG_Q_INFO * q_i, POLICY_HND *pol, const char *val_name,
+ uint8 major, uint8 minor)
{
int len_type = val_name != NULL ? strlen(val_name) + 1 : 0;
- if (q_i == NULL) return False;
+ if (q_i == NULL)
+ return False;
- memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
+ q_i->pol = *pol;
make_uni_hdr(&(q_i->hdr_val), len_type);
make_unistr2(&(q_i->uni_val), val_name, len_type);
q_i->ptr_uni_type = 0x1;
q_i->uni_type.buf_max_len = 0x104;
- q_i->uni_type.buf_len = 0x0;
- q_i->uni_type.undoc = 0;
+ q_i->uni_type.buf_len = 0x0;
+ q_i->uni_type.undoc = 0;
q_i->ptr_max_len = 1;
q_i->buf_max_len = 0x104;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_info(char *desc, REG_Q_INFO *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_info(char *desc, REG_Q_INFO * r_q, prs_struct *ps, int depth)
{
- if (r_q == NULL) return False;
+ if (r_q == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_q_info");
depth++;
prs_align(ps);
-
- smb_io_pol_hnd("", &(r_q->pol), ps, depth);
- smb_io_unihdr ("", &(r_q->hdr_val), ps, depth);
+
+ smb_io_pol_hnd("", &(r_q->pol), ps, depth);
+ smb_io_unihdr("", &(r_q->hdr_val), ps, depth);
smb_io_unistr2("", &(r_q->uni_val), r_q->hdr_val.buffer, ps, depth);
prs_align(ps);
-
+
prs_uint32("ptr_type", ps, depth, &(r_q->ptr_type));
if (r_q->ptr_type != 0)
{
prs_uint32("ptr_uni_type", ps, depth, &(r_q->ptr_uni_type));
- smb_io_buffer2("uni_type", &(r_q->uni_type), r_q->ptr_uni_type, ps, depth);
+ smb_io_buffer2("uni_type", &(r_q->uni_type), r_q->ptr_uni_type, ps,
+ depth);
prs_align(ps);
prs_uint32("ptr_max_len", ps, depth, &(r_q->ptr_max_len));
/*******************************************************************
creates a structure.
********************************************************************/
-BOOL make_reg_r_info(REG_R_INFO *r_r,
- uint32 *type, BUFFER2 *buf,
- uint32 status)
+BOOL make_reg_r_info(REG_R_INFO * r_r,
+ uint32 *type, BUFFER2 * buf, uint32 status)
{
- if (r_r == NULL) return False;
+ if (r_r == NULL)
+ return False;
r_r->ptr_type = type != NULL ? 1 : 0;
r_r->type = type;
r_r->ptr_max_len = 0;
r_r->ptr_len = 0;
}
-
+
r_r->status = status;
return True;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_info(char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_info(char *desc, REG_R_INFO * r_r, prs_struct *ps, int depth)
{
- if (r_r == NULL) return False;
+ if (r_r == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_r_info");
depth++;
prs_align(ps);
-
+
prs_uint32("ptr_type", ps, depth, &(r_r->ptr_type));
if (r_r->ptr_type != 0)
{
}
prs_uint32("ptr_uni_type", ps, depth, &(r_r->ptr_uni_type));
- smb_io_buffer2("uni_type", r_r->uni_type, r_r->ptr_uni_type, ps, depth);
+ smb_io_buffer2("uni_type", r_r->uni_type, r_r->ptr_uni_type, ps,
+ depth);
prs_align(ps);
prs_uint32("ptr_max_len", ps, depth, &(r_r->ptr_max_len));
/*******************************************************************
makes a structure.
********************************************************************/
-BOOL make_reg_q_enum_val(REG_Q_ENUM_VALUE *q_i, POLICY_HND *pol,
- uint32 val_idx, uint32 max_val_len,
- uint32 max_buf_len)
+BOOL make_reg_q_enum_val(REG_Q_ENUM_VALUE * q_i, POLICY_HND *pol,
+ uint32 val_idx, uint32 max_val_len,
+ uint32 max_buf_len)
{
- if (q_i == NULL) return False;
+ if (q_i == NULL)
+ return False;
ZERO_STRUCTP(q_i);
- memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
+ q_i->pol = *pol;
q_i->val_index = val_idx;
q_i->hdr_name.uni_str_len = 0;
q_i->hdr_name.uni_max_len = max_val_len * 2;
q_i->hdr_name.buffer = max_val_len > 0 ? 1 : 0;
q_i->uni_name.uni_max_len = max_val_len;
-
+
q_i->ptr_type = 1;
q_i->type = 0x0;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_enum_val(char *desc, REG_Q_ENUM_VALUE *q_q, prs_struct *ps, int depth)
+BOOL reg_io_q_enum_val(char *desc, REG_Q_ENUM_VALUE * q_q, prs_struct *ps,
+ int depth)
{
- if (q_q == NULL) return False;
+ if (q_q == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_q_enum_val");
depth++;
prs_align(ps);
-
- smb_io_pol_hnd("", &(q_q->pol), ps, depth);
-
+
+ smb_io_pol_hnd("", &(q_q->pol), ps, depth);
+
prs_uint32("val_index", ps, depth, &(q_q->val_index));
- smb_io_unihdr ("hdr_name", &(q_q->hdr_name), ps, depth);
- smb_io_unistr2("uni_name", &(q_q->uni_name), q_q->hdr_name.buffer, ps, depth);
+ smb_io_unihdr("hdr_name", &(q_q->hdr_name), ps, depth);
+ smb_io_unistr2("uni_name", &(q_q->uni_name), q_q->hdr_name.buffer, ps,
+ depth);
prs_align(ps);
prs_uint32("ptr_type", ps, depth, &(q_q->ptr_type));
}
prs_uint32("ptr_value", ps, depth, &(q_q->ptr_value));
- smb_io_buffer2("buf_value", &(q_q->buf_value), q_q->ptr_value, ps, depth);
+ smb_io_buffer2("buf_value", &(q_q->buf_value), q_q->ptr_value, ps,
+ depth);
prs_align(ps);
prs_uint32("ptr1", ps, depth, &(q_q->ptr1));
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_enum_val(char *desc, REG_R_ENUM_VALUE *r_q, prs_struct *ps, int depth)
+BOOL reg_io_r_enum_val(char *desc, REG_R_ENUM_VALUE * r_q, prs_struct *ps,
+ int depth)
{
- if (r_q == NULL) return False;
+ if (r_q == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_r_enum_val");
depth++;
prs_align(ps);
-
- smb_io_unihdr ("hdr_name", &(r_q->hdr_name), ps, depth);
- smb_io_unistr2("uni_name", &(r_q->uni_name), r_q->hdr_name.buffer, ps, depth);
+
+ smb_io_unihdr("hdr_name", &(r_q->hdr_name), ps, depth);
+ smb_io_unistr2("uni_name", &(r_q->uni_name), r_q->hdr_name.buffer, ps,
+ depth);
prs_align(ps);
prs_uint32("ptr_type", ps, depth, &(r_q->ptr_type));
}
prs_uint32("ptr_value", ps, depth, &(r_q->ptr_value));
- smb_io_buffer2("buf_value", r_q->buf_value, r_q->ptr_value, ps, depth);
+ smb_io_buffer2("buf_value", r_q->buf_value, r_q->ptr_value, ps,
+ depth);
prs_align(ps);
prs_uint32("ptr1", ps, depth, &(r_q->ptr1));
/*******************************************************************
makes a structure.
********************************************************************/
-BOOL make_reg_q_create_val(REG_Q_CREATE_VALUE *q_i, POLICY_HND *pol,
- char *val_name, uint32 type,
- BUFFER3 *val)
+BOOL make_reg_q_create_val(REG_Q_CREATE_VALUE * q_i, POLICY_HND *pol,
+ char *val_name, uint32 type, BUFFER3 * val)
{
int val_len = strlen(val_name) + 1;
- if (q_i == NULL) return False;
+ if (q_i == NULL)
+ return False;
ZERO_STRUCTP(q_i);
- memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
+ q_i->pol = *pol;
make_uni_hdr(&q_i->hdr_name, val_len);
make_unistr2(&(q_i->uni_name), val_name, val_len);
-
- q_i->type = type;
+
+ q_i->type = type;
q_i->buf_value = val;
return True;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_create_val(char *desc, REG_Q_CREATE_VALUE *q_q, prs_struct *ps, int depth)
+BOOL reg_io_q_create_val(char *desc, REG_Q_CREATE_VALUE * q_q, prs_struct *ps,
+ int depth)
{
- if (q_q == NULL) return False;
+ if (q_q == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_q_create_val");
depth++;
prs_align(ps);
-
- smb_io_pol_hnd("", &(q_q->pol), ps, depth);
-
- smb_io_unihdr ("hdr_name", &(q_q->hdr_name), ps, depth);
- smb_io_unistr2("uni_name", &(q_q->uni_name), q_q->hdr_name.buffer, ps, depth);
+
+ smb_io_pol_hnd("", &(q_q->pol), ps, depth);
+
+ smb_io_unihdr("hdr_name", &(q_q->hdr_name), ps, depth);
+ smb_io_unistr2("uni_name", &(q_q->uni_name), q_q->hdr_name.buffer, ps,
+ depth);
prs_align(ps);
prs_uint32("type", ps, depth, &(q_q->type));
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_create_val(char *desc, REG_R_CREATE_VALUE *r_q, prs_struct *ps, int depth)
+BOOL reg_io_r_create_val(char *desc, REG_R_CREATE_VALUE * r_q, prs_struct *ps,
+ int depth)
{
- if (r_q == NULL) return False;
+ if (r_q == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_r_create_val");
depth++;
prs_align(ps);
-
+
prs_uint32("status", ps, depth, &(r_q->status));
return True;
/*******************************************************************
makes a structure.
********************************************************************/
-BOOL make_reg_q_enum_key(REG_Q_ENUM_KEY *q_i, POLICY_HND *pol, uint32 key_idx)
+BOOL make_reg_q_enum_key(REG_Q_ENUM_KEY * q_i, POLICY_HND *pol,
+ uint32 key_idx)
{
- if (q_i == NULL) return False;
+ if (q_i == NULL)
+ return False;
- memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
+ q_i->pol = *pol;
q_i->key_index = key_idx;
q_i->key_name_len = 0;
memset(q_i->pad2, 0, sizeof(q_i->pad2));
q_i->ptr3 = 1;
- init_nt_time(&(q_i->time)); /* ignored ? */
+ init_nt_time(&(q_i->time)); /* ignored ? */
return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_enum_key(char *desc, REG_Q_ENUM_KEY *q_q, prs_struct *ps, int depth)
+BOOL reg_io_q_enum_key(char *desc, REG_Q_ENUM_KEY * q_q, prs_struct *ps,
+ int depth)
{
- if (q_q == NULL) return False;
+ if (q_q == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_q_enum_key");
depth++;
prs_align(ps);
-
- smb_io_pol_hnd("", &(q_q->pol), ps, depth);
-
+
+ smb_io_pol_hnd("", &(q_q->pol), ps, depth);
+
prs_uint32("key_index", ps, depth, &(q_q->key_index));
prs_uint16("key_name_len", ps, depth, &(q_q->key_name_len));
prs_uint16("unknown_1", ps, depth, &(q_q->unknown_1));
if (q_q->ptr1 != 0)
{
prs_uint32("unknown_2", ps, depth, &(q_q->unknown_2));
- prs_uint8s(False, "pad1", ps, depth, q_q->pad1, sizeof(q_q->pad1));
+ prs_uint8s(False, "pad1", ps, depth, q_q->pad1,
+ sizeof(q_q->pad1));
}
prs_uint32("ptr2", ps, depth, &(q_q->ptr2));
if (q_q->ptr2 != 0)
{
- prs_uint8s(False, "pad2", ps, depth, q_q->pad2, sizeof(q_q->pad2));
+ prs_uint8s(False, "pad2", ps, depth, q_q->pad2,
+ sizeof(q_q->pad2));
}
prs_uint32("ptr3", ps, depth, &(q_q->ptr3));
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_enum_key(char *desc, REG_R_ENUM_KEY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_r_enum_key(char *desc, REG_R_ENUM_KEY * r_q, prs_struct *ps,
+ int depth)
{
- if (r_q == NULL) return False;
+ if (r_q == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_r_enum_key");
depth++;
prs_align(ps);
-
+
prs_uint16("key_name_len", ps, depth, &(r_q->key_name_len));
prs_uint16("unknown_1", ps, depth, &(r_q->unknown_1));
if (r_q->ptr2 != 0)
{
- prs_uint8s(False, "pad2", ps, depth, r_q->pad2, sizeof(r_q->pad2));
+ prs_uint8s(False, "pad2", ps, depth, r_q->pad2,
+ sizeof(r_q->pad2));
}
prs_uint32("ptr3", ps, depth, &(r_q->ptr3));
/*******************************************************************
makes a structure.
********************************************************************/
-BOOL make_reg_q_open_entry(REG_Q_OPEN_ENTRY *r_q, POLICY_HND *pol,
- char *key_name, uint32 access_mask)
+BOOL make_reg_q_open_entry(REG_Q_OPEN_ENTRY * r_q, POLICY_HND *pol,
+ char *key_name, uint32 access_mask)
{
- int len_name = strlen(key_name)+1;
+ int len_name = strlen(key_name) + 1;
- if (r_q == NULL) return False;
+ if (r_q == NULL)
+ return False;
- memcpy(&(r_q->pol), pol, sizeof(r_q->pol));
+ r_q->pol = *pol;
make_uni_hdr(&(r_q->hdr_name), len_name);
make_unistr2(&(r_q->uni_name), key_name, len_name);
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_open_entry(char *desc, REG_Q_OPEN_ENTRY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_open_entry(char *desc, REG_Q_OPEN_ENTRY * r_q, prs_struct *ps,
+ int depth)
{
- if (r_q == NULL) return False;
+ if (r_q == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_q_entry");
depth++;
prs_align(ps);
-
+
smb_io_pol_hnd("", &(r_q->pol), ps, depth);
- smb_io_unihdr ("", &(r_q->hdr_name), ps, depth);
+ smb_io_unihdr("", &(r_q->hdr_name), ps, depth);
smb_io_unistr2("", &(r_q->uni_name), r_q->hdr_name.buffer, ps, depth);
prs_align(ps);
-
+
prs_uint32("unknown_0", ps, depth, &(r_q->unknown_0));
prs_uint32("access_mask", ps, depth, &(r_q->access_mask));
/*******************************************************************
creates a structure.
********************************************************************/
-BOOL make_reg_r_open_entry(REG_R_OPEN_ENTRY *r_r,
- POLICY_HND *pol, uint32 status)
+BOOL make_reg_r_open_entry(REG_R_OPEN_ENTRY * r_r,
+ POLICY_HND *pol, uint32 status)
{
- if (r_r == NULL) return False;
+ if (r_r == NULL)
+ return False;
- memcpy(&(r_r->pol), pol, sizeof(r_r->pol));
+ r_r->pol = *pol;
r_r->status = status;
return True;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_open_entry(char *desc, REG_R_OPEN_ENTRY *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_open_entry(char *desc, REG_R_OPEN_ENTRY * r_r, prs_struct *ps,
+ int depth)
{
- if (r_r == NULL) return False;
+ if (r_r == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_r_open_entry");
depth++;
prs_align(ps);
-
+
smb_io_pol_hnd("", &(r_r->pol), ps, depth);
prs_uint32("status", ps, depth, &(r_r->status));
/*******************************************************************
makes a structure.
********************************************************************/
-BOOL make_reg_q_shutdown(REG_Q_SHUTDOWN *q_i,
- const char *msg, uint32 timeout, uint16 flags)
+BOOL make_reg_q_shutdown(REG_Q_SHUTDOWN * q_i,
+ const char *msg, uint32 timeout, uint16 flags)
{
int len = strlen(msg) + 1;
- if (q_i == NULL) return False;
+ if (q_i == NULL)
+ return False;
ZERO_STRUCTP(q_i);
make_uni_hdr(&q_i->hdr_msg, len);
make_unistr2(&(q_i->uni_msg), msg, len);
-
+
q_i->timeout = timeout;
- q_i->flags = flags;
+ q_i->flags = flags;
return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_shutdown(char *desc, REG_Q_SHUTDOWN *q_q, prs_struct *ps, int depth)
+BOOL reg_io_q_shutdown(char *desc, REG_Q_SHUTDOWN * q_q, prs_struct *ps,
+ int depth)
{
- if (q_q == NULL) return False;
+ if (q_q == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_q_shutdown");
depth++;
prs_align(ps);
-
+
prs_uint32("ptr_0", ps, depth, &(q_q->ptr_0));
prs_uint32("ptr_1", ps, depth, &(q_q->ptr_1));
prs_uint32("ptr_2", ps, depth, &(q_q->ptr_2));
-
- smb_io_unihdr ("hdr_msg", &(q_q->hdr_msg), ps, depth);
- smb_io_unistr2("uni_msg", &(q_q->uni_msg), q_q->hdr_msg.buffer, ps, depth);
+
+ smb_io_unihdr("hdr_msg", &(q_q->hdr_msg), ps, depth);
+ smb_io_unistr2("uni_msg", &(q_q->uni_msg), q_q->hdr_msg.buffer, ps,
+ depth);
prs_align(ps);
prs_uint32("timeout", ps, depth, &(q_q->timeout));
- prs_uint16("flags ", ps, depth, &(q_q->flags ));
+ prs_uint16("flags ", ps, depth, &(q_q->flags));
prs_align(ps);
return True;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_shutdown(char *desc, REG_R_SHUTDOWN *r_q, prs_struct *ps, int depth)
+BOOL reg_io_r_shutdown(char *desc, REG_R_SHUTDOWN * r_q, prs_struct *ps,
+ int depth)
{
- if (r_q == NULL) return False;
+ if (r_q == NULL)
+ return False;
prs_debug(ps, depth, desc, "reg_io_r_shutdown");
depth++;
prs_align(ps);
-
+
prs_uint32("status", ps, depth, &(r_q->status));
return True;
}
-
/*******************************************************************
makes a SAMR_Q_CLOSE_HND structure.
********************************************************************/
-BOOL make_samr_q_close_hnd(SAMR_Q_CLOSE_HND * q_c, POLICY_HND * hnd)
+BOOL make_samr_q_close_hnd(SAMR_Q_CLOSE_HND * q_c, POLICY_HND *hnd)
{
if (q_c == NULL || hnd == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_close_hnd(char *desc, SAMR_Q_CLOSE_HND * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_close_hnd(char *desc, SAMR_R_CLOSE_HND * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
makes a SAMR_Q_LOOKUP_DOMAIN structure.
********************************************************************/
BOOL make_samr_q_lookup_domain(SAMR_Q_LOOKUP_DOMAIN * q_u,
- POLICY_HND * pol, const char *dom_name)
+ POLICY_HND *pol, const char *dom_name)
{
int len_name = strlen(dom_name);
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_lookup_domain(char *desc, SAMR_Q_LOOKUP_DOMAIN * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
makes a SAMR_R_LOOKUP_DOMAIN structure.
********************************************************************/
BOOL make_samr_r_lookup_domain(SAMR_R_LOOKUP_DOMAIN * r_u,
- DOM_SID * dom_sid, uint32 status)
+ DOM_SID *dom_sid, uint32 status)
{
if (r_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_lookup_domain(char *desc, SAMR_R_LOOKUP_DOMAIN * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL make_samr_q_unknown_2d(SAMR_Q_UNKNOWN_2D * q_u,
- const POLICY_HND * dom_pol, const DOM_SID * sid)
+ const POLICY_HND *dom_pol, const DOM_SID *sid)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_unknown_2d(char *desc, SAMR_Q_UNKNOWN_2D * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_unknown_2d(char *desc, SAMR_R_UNKNOWN_2D * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL make_samr_q_open_domain(SAMR_Q_OPEN_DOMAIN * q_u,
- const POLICY_HND * connect_pol, uint32 flags,
- const DOM_SID * sid)
+ const POLICY_HND *connect_pol, uint32 flags,
+ const DOM_SID *sid)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_open_domain(char *desc, SAMR_Q_OPEN_DOMAIN * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_open_domain(char *desc, SAMR_R_OPEN_DOMAIN * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL make_samr_q_get_usrdom_pwinfo(SAMR_Q_GET_USRDOM_PWINFO * q_u,
- POLICY_HND * user_pol)
+ POLICY_HND *user_pol)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_get_usrdom_pwinfo(char *desc, SAMR_Q_GET_USRDOM_PWINFO * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_get_usrdom_pwinfo(char *desc, SAMR_R_GET_USRDOM_PWINFO * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL make_samr_q_query_sec_obj(SAMR_Q_QUERY_SEC_OBJ * q_u,
- const POLICY_HND * user_pol, uint32 sec_info)
+ const POLICY_HND *user_pol, uint32 sec_info)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_query_sec_obj(char *desc, SAMR_Q_QUERY_SEC_OBJ * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL make_samr_q_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO * q_u,
- POLICY_HND * domain_pol, uint16 switch_value)
+ POLICY_HND *domain_pol, uint16 switch_value)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_query_dom_info(char *desc, SAMR_Q_QUERY_DOMAIN_INFO * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
static BOOL sam_io_unk_info3(char *desc, SAM_UNK_INFO_3 * u_3,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (u_3 == NULL)
return False;
reads or writes a structure.
********************************************************************/
static BOOL sam_io_unk_info6(char *desc, SAM_UNK_INFO_6 * u_6,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (u_6 == NULL)
return False;
reads or writes a structure.
********************************************************************/
static BOOL sam_io_unk_info7(char *desc, SAM_UNK_INFO_7 * u_7,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (u_7 == NULL)
return False;
reads or writes a structure.
********************************************************************/
static BOOL sam_io_unk_info12(char *desc, SAM_UNK_INFO_12 * u_12,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (u_12 == NULL)
return False;
reads or writes a structure.
********************************************************************/
static BOOL sam_io_unk_info2(char *desc, SAM_UNK_INFO_2 * u_2,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (u_2 == NULL)
return False;
reads or writes a structure.
********************************************************************/
static BOOL sam_io_unk_info1(char *desc, SAM_UNK_INFO_1 * u_1,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (u_1 == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_query_dom_info(char *desc, SAMR_R_QUERY_DOMAIN_INFO * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
reads or writes a SAMR_R_QUERY_SEC_OBJ structure.
********************************************************************/
BOOL samr_io_r_query_sec_obj(char *desc, SAMR_R_QUERY_SEC_OBJ * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
********************************************************************/
static BOOL sam_io_sam_str1(char *desc, SAM_STR1 * sam, uint32 acct_buf,
uint32 name_buf, uint32 desc_buf,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (sam == NULL)
return False;
reads or writes a SAM_ENTRY1 structure.
********************************************************************/
static BOOL sam_io_sam_entry1(char *desc, SAM_ENTRY1 * sam,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (sam == NULL)
return False;
reads or writes a SAM_STR2 structure.
********************************************************************/
static BOOL sam_io_sam_str2(char *desc, SAM_STR2 * sam, uint32 acct_buf,
- uint32 desc_buf,
- prs_struct * ps, int depth)
+ uint32 desc_buf, prs_struct *ps, int depth)
{
if (sam == NULL)
return False;
reads or writes a SAM_ENTRY2 structure.
********************************************************************/
static BOOL sam_io_sam_entry2(char *desc, SAM_ENTRY2 * sam,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (sam == NULL)
return False;
reads or writes a SAM_STR3 structure.
********************************************************************/
static BOOL sam_io_sam_str3(char *desc, SAM_STR3 * sam, uint32 acct_buf,
- uint32 desc_buf,
- prs_struct * ps, int depth)
+ uint32 desc_buf, prs_struct *ps, int depth)
{
if (sam == NULL)
return False;
reads or writes a SAM_ENTRY3 structure.
********************************************************************/
static BOOL sam_io_sam_entry3(char *desc, SAM_ENTRY3 * sam,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (sam == NULL)
return False;
reads or writes a SAM_ENTRY4 structure.
********************************************************************/
static BOOL sam_io_sam_entry4(char *desc, SAM_ENTRY4 * sam,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (sam == NULL)
return False;
reads or writes a SAM_ENTRY5 structure.
********************************************************************/
static BOOL sam_io_sam_entry5(char *desc, SAM_ENTRY5 * sam,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (sam == NULL)
return False;
reads or writes a SAM_ENTRY structure.
********************************************************************/
static BOOL sam_io_sam_entry(char *desc, SAM_ENTRY * sam,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (sam == NULL)
return False;
/*******************************************************************
makes a SAMR_Q_ENUM_DOM_USERS structure.
********************************************************************/
-BOOL make_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS * q_e, POLICY_HND * pol,
+BOOL make_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS * q_e, POLICY_HND *pol,
uint32 start_idx,
uint16 acb_mask, uint16 unk_1, uint32 size)
{
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_enum_dom_users(char *desc, SAMR_Q_ENUM_DOM_USERS * q_e,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_e == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_enum_dom_users(char *desc, SAMR_R_ENUM_DOM_USERS * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
uint32 i;
/*******************************************************************
makes a SAMR_Q_QUERY_DISPINFO structure.
********************************************************************/
-BOOL make_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO * q_e, POLICY_HND * pol,
+BOOL make_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO * q_e, POLICY_HND *pol,
uint16 switch_level, uint32 start_idx,
uint32 max_entries)
{
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_query_dispinfo(char *desc, SAMR_Q_QUERY_DISPINFO * q_e,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_e == NULL)
return False;
********************************************************************/
static BOOL sam_io_sam_dispinfo_1(char *desc, SAM_DISPINFO_1 * sam,
uint32 num_entries,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
uint32 i;
********************************************************************/
static BOOL sam_io_sam_dispinfo_2(char *desc, SAM_DISPINFO_2 * sam,
uint32 num_entries,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
uint32 i;
********************************************************************/
static BOOL sam_io_sam_dispinfo_3(char *desc, SAM_DISPINFO_3 * sam,
uint32 num_entries,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
uint32 i;
********************************************************************/
static BOOL sam_io_sam_dispinfo_4(char *desc, SAM_DISPINFO_4 * sam,
uint32 num_entries,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
uint32 i;
********************************************************************/
static BOOL sam_io_sam_dispinfo_5(char *desc, SAM_DISPINFO_5 * sam,
uint32 num_entries,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
uint32 i;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_query_dispinfo(char *desc, SAMR_R_QUERY_DISPINFO * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
makes a SAMR_Q_OPEN_GROUP structure.
********************************************************************/
BOOL make_samr_q_open_group(SAMR_Q_OPEN_GROUP * q_c,
- const POLICY_HND * hnd,
+ const POLICY_HND *hnd,
uint32 access_mask, uint32 rid)
{
if (q_c == NULL || hnd == NULL)
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_open_group(char *desc, SAMR_Q_OPEN_GROUP * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_open_group(char *desc, SAMR_R_OPEN_GROUP * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_group_info1(char *desc, GROUP_INFO1 * gr1,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (gr1 == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_group_info4(char *desc, GROUP_INFO4 * gr4,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (gr4 == NULL)
return False;
reads or writes a structure.
********************************************************************/
static BOOL samr_group_info_ctr(char *desc, GROUP_INFO_CTR * ctr,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (ctr == NULL)
return False;
makes a SAMR_Q_CREATE_DOM_GROUP structure.
********************************************************************/
BOOL make_samr_q_create_dom_group(SAMR_Q_CREATE_DOM_GROUP * q_e,
- POLICY_HND * pol, const char *acct_desc)
+ POLICY_HND *pol, const char *acct_desc)
{
int acct_len = acct_desc != NULL ? strlen(acct_desc) : 0;
if (q_e == NULL || pol == NULL)
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_create_dom_group(char *desc, SAMR_Q_CREATE_DOM_GROUP * q_e,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_e == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_create_dom_group(char *desc, SAMR_R_CREATE_DOM_GROUP * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
makes a SAMR_Q_DELETE_DOM_GROUP structure.
********************************************************************/
BOOL make_samr_q_delete_dom_group(SAMR_Q_DELETE_DOM_GROUP * q_c,
- POLICY_HND * hnd)
+ POLICY_HND *hnd)
{
if (q_c == NULL || hnd == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_delete_dom_group(char *desc, SAMR_Q_DELETE_DOM_GROUP * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_delete_dom_group(char *desc, SAMR_R_DELETE_DOM_GROUP * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
makes a SAMR_Q_DEL_GROUPMEM structure.
********************************************************************/
BOOL make_samr_q_del_groupmem(SAMR_Q_DEL_GROUPMEM * q_e,
- POLICY_HND * pol, uint32 rid)
+ POLICY_HND *pol, uint32 rid)
{
if (q_e == NULL || pol == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_del_groupmem(char *desc, SAMR_Q_DEL_GROUPMEM * q_e,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_e == NULL)
return False;
/*******************************************************************
makes a SAMR_R_DEL_GROUPMEM structure.
********************************************************************/
-BOOL make_samr_r_del_groupmem(SAMR_R_DEL_GROUPMEM * r_u, POLICY_HND * pol,
+BOOL make_samr_r_del_groupmem(SAMR_R_DEL_GROUPMEM * r_u, POLICY_HND *pol,
uint32 status)
{
if (r_u == NULL)
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_del_groupmem(char *desc, SAMR_R_DEL_GROUPMEM * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
makes a SAMR_Q_ADD_GROUPMEM structure.
********************************************************************/
BOOL make_samr_q_add_groupmem(SAMR_Q_ADD_GROUPMEM * q_e,
- POLICY_HND * pol, uint32 rid)
+ POLICY_HND *pol, uint32 rid)
{
if (q_e == NULL || pol == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_add_groupmem(char *desc, SAMR_Q_ADD_GROUPMEM * q_e,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_e == NULL)
return False;
/*******************************************************************
makes a SAMR_R_ADD_GROUPMEM structure.
********************************************************************/
-BOOL make_samr_r_add_groupmem(SAMR_R_ADD_GROUPMEM * r_u, POLICY_HND * pol,
+BOOL make_samr_r_add_groupmem(SAMR_R_ADD_GROUPMEM * r_u, POLICY_HND *pol,
uint32 status)
{
if (r_u == NULL)
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_add_groupmem(char *desc, SAMR_R_ADD_GROUPMEM * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
makes a SAMR_Q_SET_GROUPINFO structure.
********************************************************************/
BOOL make_samr_q_set_groupinfo(SAMR_Q_SET_GROUPINFO * q_e,
- POLICY_HND * pol, GROUP_INFO_CTR * ctr)
+ POLICY_HND *pol, GROUP_INFO_CTR * ctr)
{
if (q_e == NULL || pol == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_set_groupinfo(char *desc, SAMR_Q_SET_GROUPINFO * q_e,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_e == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_set_groupinfo(char *desc, SAMR_R_SET_GROUPINFO * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
makes a SAMR_Q_QUERY_GROUPINFO structure.
********************************************************************/
BOOL make_samr_q_query_groupinfo(SAMR_Q_QUERY_GROUPINFO * q_e,
- POLICY_HND * pol, uint16 switch_level)
+ POLICY_HND *pol, uint16 switch_level)
{
if (q_e == NULL || pol == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_query_groupinfo(char *desc, SAMR_Q_QUERY_GROUPINFO * q_e,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_e == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_query_groupinfo(char *desc, SAMR_R_QUERY_GROUPINFO * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
/*******************************************************************
makes a SAMR_Q_QUERY_GROUPMEM structure.
********************************************************************/
-BOOL make_samr_q_query_groupmem(SAMR_Q_QUERY_GROUPMEM * q_c, POLICY_HND * hnd)
+BOOL make_samr_q_query_groupmem(SAMR_Q_QUERY_GROUPMEM * q_c, POLICY_HND *hnd)
{
if (q_c == NULL || hnd == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_query_groupmem(char *desc, SAMR_Q_QUERY_GROUPMEM * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_query_groupmem(char *desc, SAMR_R_QUERY_GROUPMEM * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
uint32 i;
prs_uint32("num_rids", ps, depth, &(r_u->num_rids));
if (r_u->num_rids != 0)
{
- r_u->rid = (uint32 *) Realloc(r_u->rid,
- sizeof(r_u->rid
- [0]) *
- r_u->num_rids);
+ r_u->rid = (uint32 *)Realloc(r_u->rid,
+ sizeof(r_u->rid
+ [0]) *
+ r_u->num_rids);
if (r_u->rid == NULL)
{
samr_free_r_query_groupmem(r_u);
if (r_u->num_attrs != 0)
{
- r_u->attr = (uint32 *) Realloc(r_u->attr,
- sizeof
- (r_u->attr[0])
- *
- r_u->num_attrs);
+ r_u->attr = (uint32 *)Realloc(r_u->attr,
+ sizeof
+ (r_u->attr[0])
+ *
+ r_u->num_attrs);
if (r_u->attr == NULL)
{
samr_free_r_query_groupmem(r_u);
makes a SAMR_Q_QUERY_USERGROUPS structure.
********************************************************************/
BOOL make_samr_q_query_usergroups(SAMR_Q_QUERY_USERGROUPS * q_u,
- POLICY_HND * hnd)
+ POLICY_HND *hnd)
{
if (q_u == NULL || hnd == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_query_usergroups(char *desc, SAMR_Q_QUERY_USERGROUPS * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_gids(char *desc, uint32 *num_gids, DOM_GID ** gid,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
uint32 i;
if (gid == NULL)
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_query_usergroups(char *desc, SAMR_R_QUERY_USERGROUPS * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
makes a SAMR_Q_ENUM_DOMAINS structure.
********************************************************************/
BOOL make_samr_q_enum_domains(SAMR_Q_ENUM_DOMAINS * q_e,
- const POLICY_HND * pol,
+ const POLICY_HND *pol,
uint32 start_idx, uint32 size)
{
if (q_e == NULL || pol == NULL)
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_enum_domains(char *desc, SAMR_Q_ENUM_DOMAINS * q_e,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_e == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_enum_domains(char *desc, SAMR_R_ENUM_DOMAINS * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
uint32 i;
makes a SAMR_Q_ENUM_DOM_GROUPS structure.
********************************************************************/
BOOL make_samr_q_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS * q_e,
- const POLICY_HND * pol,
+ const POLICY_HND *pol,
uint32 start_idx, uint32 size)
{
if (q_e == NULL || pol == NULL)
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_enum_dom_groups(char *desc, SAMR_Q_ENUM_DOM_GROUPS * q_e,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_e == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_enum_dom_groups(char *desc, SAMR_R_ENUM_DOM_GROUPS * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
uint32 i;
makes a SAMR_Q_ENUM_DOM_ALIASES structure.
********************************************************************/
BOOL make_samr_q_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES * q_e,
- POLICY_HND * pol, uint32 start_idx,
+ POLICY_HND *pol, uint32 start_idx,
uint32 size)
{
if (q_e == NULL || pol == NULL)
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_enum_dom_aliases(char *desc, SAMR_Q_ENUM_DOM_ALIASES * q_e,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_e == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_enum_dom_aliases(char *desc, SAMR_R_ENUM_DOM_ALIASES * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
uint32 i;
reads or writes a structure.
********************************************************************/
BOOL samr_io_alias_info3(char *desc, ALIAS_INFO3 * al3,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (al3 == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_alias_info_ctr(char *desc, ALIAS_INFO_CTR * ctr,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (ctr == NULL)
return False;
makes a SAMR_Q_QUERY_ALIASINFO structure.
********************************************************************/
BOOL make_samr_q_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO * q_e,
- const POLICY_HND * pol, uint16 switch_level)
+ const POLICY_HND *pol, uint16 switch_level)
{
if (q_e == NULL || pol == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_query_aliasinfo(char *desc, SAMR_Q_QUERY_ALIASINFO * q_e,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_e == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_query_aliasinfo(char *desc, SAMR_R_QUERY_ALIASINFO * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
makes a SAMR_Q_SET_ALIASINFO structure.
********************************************************************/
BOOL make_samr_q_set_aliasinfo(SAMR_Q_SET_ALIASINFO * q_u,
- const POLICY_HND * hnd, ALIAS_INFO_CTR * ctr)
+ const POLICY_HND *hnd, ALIAS_INFO_CTR * ctr)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_set_aliasinfo(char *desc, SAMR_Q_SET_ALIASINFO * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_set_aliasinfo(char *desc, SAMR_R_SET_ALIASINFO * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
makes a SAMR_Q_QUERY_USERALIASES structure.
********************************************************************/
BOOL make_samr_q_query_useraliases(SAMR_Q_QUERY_USERALIASES * q_u,
- const POLICY_HND * hnd,
+ const POLICY_HND *hnd,
uint32 num_sids,
uint32 *ptr_sid, DOM_SID2 * sid)
{
reads or writes a SAMR_Q_QUERY_USERALIASES structure.
********************************************************************/
BOOL samr_io_q_query_useraliases(char *desc, SAMR_Q_QUERY_USERALIASES * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
fstring tmp;
uint32 i;
if (q_u->num_sids2 != 0)
{
- q_u->ptr_sid = (uint32 *) Realloc(q_u->ptr_sid,
- sizeof(q_u->ptr_sid[0]) *
- q_u->num_sids2);
+ q_u->ptr_sid = (uint32 *)Realloc(q_u->ptr_sid,
+ sizeof(q_u->ptr_sid[0]) *
+ q_u->num_sids2);
if (q_u->ptr_sid == NULL)
{
samr_free_q_query_useraliases(q_u);
reads or writes a structure.
********************************************************************/
BOOL samr_io_rids(char *desc, uint32 *num_rids, uint32 **rid,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
fstring tmp;
uint32 i;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_query_useraliases(char *desc, SAMR_R_QUERY_USERALIASES * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
/*******************************************************************
makes a SAMR_Q_OPEN_ALIAS structure.
********************************************************************/
-BOOL make_samr_q_open_alias(SAMR_Q_OPEN_ALIAS * q_u, const POLICY_HND * pol,
+BOOL make_samr_q_open_alias(SAMR_Q_OPEN_ALIAS * q_u, const POLICY_HND *pol,
uint32 unknown_0, uint32 rid)
{
if (q_u == NULL)
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_open_alias(char *desc, SAMR_Q_OPEN_ALIAS * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_open_alias(char *desc, SAMR_R_OPEN_ALIAS * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
makes a SAMR_Q_LOOKUP_RIDS structure.
********************************************************************/
BOOL make_samr_q_lookup_rids(SAMR_Q_LOOKUP_RIDS * q_u,
- const POLICY_HND * pol, uint32 flags,
+ const POLICY_HND *pol, uint32 flags,
uint32 num_rids, const uint32 *rid)
{
if (q_u == NULL)
q_u->flags = flags;
q_u->ptr = 0;
q_u->num_rids2 = num_rids;
- q_u->rid = (uint32 *) memdup(rid, num_rids * sizeof(q_u->rid[0]));
+ q_u->rid = (uint32 *)memdup(rid, num_rids * sizeof(q_u->rid[0]));
return True;
}
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_lookup_rids(char *desc, SAMR_Q_LOOKUP_RIDS * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
uint32 i;
fstring tmp;
if (q_u->num_rids2 != 0)
{
- q_u->rid = (uint32 *) Realloc(q_u->rid, sizeof(q_u->rid[0]) *
- q_u->num_rids2);
+ q_u->rid = (uint32 *)Realloc(q_u->rid, sizeof(q_u->rid[0]) *
+ q_u->num_rids2);
if (q_u->rid == NULL)
{
samr_free_q_lookup_rids(q_u);
********************************************************************/
BOOL make_samr_r_lookup_rids(SAMR_R_LOOKUP_RIDS * r_u,
uint32 num_names, UNIHDR * hdr_name,
- UNISTR2 * uni_name, uint32 *type)
+ UNISTR2 *uni_name, uint32 *type)
{
if (r_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_lookup_rids(char *desc, SAMR_R_LOOKUP_RIDS * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
uint32 i;
fstring tmp;
return False;
}
- r_u->uni_name = (UNISTR2 *) Realloc(r_u->uni_name,
- r_u->num_names2 *
- sizeof(r_u->uni_name[0]));
+ r_u->uni_name = (UNISTR2 *)Realloc(r_u->uni_name,
+ r_u->num_names2 *
+ sizeof(r_u->uni_name[0]));
if (r_u->uni_name == NULL)
{
free(r_u->hdr_name);
if (r_u->ptr_types != 0 && r_u->num_types1 != 0)
{
- r_u->type = (uint32 *) Realloc(r_u->type, r_u->num_types2 *
- sizeof(r_u->type[0]));
+ r_u->type = (uint32 *)Realloc(r_u->type, r_u->num_types2 *
+ sizeof(r_u->type[0]));
if (r_u->type == NULL)
{
if (r_u->uni_name != NULL)
/*******************************************************************
makes a SAMR_Q_OPEN_ALIAS structure.
********************************************************************/
-BOOL make_samr_q_delete_alias(SAMR_Q_DELETE_DOM_ALIAS * q_u, POLICY_HND * hnd)
+BOOL make_samr_q_delete_alias(SAMR_Q_DELETE_DOM_ALIAS * q_u, POLICY_HND *hnd)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_delete_alias(char *desc, SAMR_Q_DELETE_DOM_ALIAS * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_delete_alias(char *desc, SAMR_R_DELETE_DOM_ALIAS * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
makes a SAMR_Q_CREATE_DOM_ALIAS structure.
********************************************************************/
BOOL make_samr_q_create_dom_alias(SAMR_Q_CREATE_DOM_ALIAS * q_u,
- POLICY_HND * hnd, const char *acct_desc)
+ POLICY_HND *hnd, const char *acct_desc)
{
int acct_len = acct_desc != NULL ? strlen(acct_desc) : 0;
if (q_u == NULL)
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_create_dom_alias(char *desc, SAMR_Q_CREATE_DOM_ALIAS * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_create_dom_alias(char *desc, SAMR_R_CREATE_DOM_ALIAS * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
/*******************************************************************
makes a SAMR_Q_ADD_ALIASMEM structure.
********************************************************************/
-BOOL make_samr_q_add_aliasmem(SAMR_Q_ADD_ALIASMEM * q_u, POLICY_HND * hnd,
- DOM_SID * sid)
+BOOL make_samr_q_add_aliasmem(SAMR_Q_ADD_ALIASMEM * q_u, POLICY_HND *hnd,
+ DOM_SID *sid)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_add_aliasmem(char *desc, SAMR_Q_ADD_ALIASMEM * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_add_aliasmem(char *desc, SAMR_R_ADD_ALIASMEM * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
/*******************************************************************
makes a SAMR_Q_DEL_ALIASMEM structure.
********************************************************************/
-BOOL make_samr_q_del_aliasmem(SAMR_Q_DEL_ALIASMEM * q_u, POLICY_HND * hnd,
- DOM_SID * sid)
+BOOL make_samr_q_del_aliasmem(SAMR_Q_DEL_ALIASMEM * q_u, POLICY_HND *hnd,
+ DOM_SID *sid)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_del_aliasmem(char *desc, SAMR_Q_DEL_ALIASMEM * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_del_aliasmem(char *desc, SAMR_R_DEL_ALIASMEM * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
makes a SAMR_Q_DELETE_DOM_ALIAS structure.
********************************************************************/
BOOL make_samr_q_delete_dom_alias(SAMR_Q_DELETE_DOM_ALIAS * q_c,
- POLICY_HND * hnd)
+ POLICY_HND *hnd)
{
if (q_c == NULL || hnd == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_delete_dom_alias(char *desc, SAMR_Q_DELETE_DOM_ALIAS * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_delete_dom_alias(char *desc, SAMR_R_DELETE_DOM_ALIAS * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
makes a SAMR_Q_QUERY_ALIASMEM structure.
********************************************************************/
BOOL make_samr_q_query_aliasmem(SAMR_Q_QUERY_ALIASMEM * q_c,
- const POLICY_HND * hnd)
+ const POLICY_HND *hnd)
{
if (q_c == NULL || hnd == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_query_aliasmem(char *desc, SAMR_Q_QUERY_ALIASMEM * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_query_aliasmem(char *desc, SAMR_R_QUERY_ALIASMEM * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
uint32 i;
uint32 ptr_sid[MAX_LOOKUP_SIDS];
makes a SAMR_Q_LOOKUP_NAMES structure.
********************************************************************/
BOOL make_samr_q_lookup_names(SAMR_Q_LOOKUP_NAMES * q_u,
- const POLICY_HND * pol, uint32 flags,
+ const POLICY_HND *pol, uint32 flags,
uint32 num_names, char **name)
{
uint32 i;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_lookup_names(char *desc, SAMR_Q_LOOKUP_NAMES * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
uint32 i;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_lookup_names(char *desc, SAMR_R_LOOKUP_NAMES * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
uint32 i;
fstring tmp;
makes a SAMR_Q_DELETE_DOM_USER structure.
********************************************************************/
BOOL make_samr_q_delete_dom_user(SAMR_Q_DELETE_DOM_USER * q_c,
- POLICY_HND * hnd)
+ POLICY_HND *hnd)
{
if (q_c == NULL || hnd == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_delete_dom_user(char *desc, SAMR_Q_DELETE_DOM_USER * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_delete_dom_user(char *desc, SAMR_R_DELETE_DOM_USER * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL make_samr_q_open_user(SAMR_Q_OPEN_USER * q_u,
- const POLICY_HND * pol,
+ const POLICY_HND *pol,
uint32 access_mask, uint32 rid)
{
if (q_u == NULL)
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_open_user(char *desc, SAMR_Q_OPEN_USER * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_open_user(char *desc, SAMR_R_OPEN_USER * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL make_samr_q_create_user(SAMR_Q_CREATE_USER * q_u,
- POLICY_HND * pol,
+ POLICY_HND *pol,
const char *name,
uint32 acb_info, uint32 access_mask)
{
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_create_user(char *desc, SAMR_Q_CREATE_USER * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_create_user(char *desc, SAMR_R_CREATE_USER * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
makes a SAMR_Q_QUERY_USERINFO structure.
********************************************************************/
BOOL make_samr_q_query_userinfo(SAMR_Q_QUERY_USERINFO * q_u,
- POLICY_HND * hnd, uint16 switch_value)
+ POLICY_HND *hnd, uint16 switch_value)
{
if (q_u == NULL || hnd == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_query_userinfo(char *desc, SAMR_Q_QUERY_USERINFO * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a LOGON_HRS structure.
********************************************************************/
static BOOL sam_io_logon_hrs(char *desc, LOGON_HRS * hrs,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (hrs == NULL)
return False;
DEBUG(5, ("make_sam_user_info12\n"));
- if (lm_pwd == NULL)
- {
- ZERO_STRUCT(usr->lm_pwd);
- usr->lm_pwd_active = 0;
- }
- else
- {
- memcpy(usr->lm_pwd, lm_pwd, sizeof(usr->lm_pwd));
- usr->lm_pwd_active = 1;
- }
-
- if (nt_pwd == NULL)
- {
- ZERO_STRUCT(usr->nt_pwd);
- usr->nt_pwd_active = 0;
- }
- else
- {
- memcpy(usr->nt_pwd, nt_pwd, sizeof(usr->nt_pwd));
- usr->nt_pwd_active = 1;
- }
+ usr->lm_pwd_active =
+ Memcpy(usr->lm_pwd, lm_pwd, sizeof(usr->lm_pwd)) ? 1 : 0;
+ usr->nt_pwd_active =
+ Memcpy(usr->nt_pwd, nt_pwd, sizeof(usr->nt_pwd)) ? 1 : 0;
return True;
}
reads or writes a structure.
********************************************************************/
BOOL sam_io_user_info12(char *desc, SAM_USER_INFO_12 * u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL sam_io_user_info10(char *desc, SAM_USER_INFO_10 * usr,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (usr == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL sam_io_user_info11(char *desc, SAM_USER_INFO_11 * usr,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (usr == NULL)
return False;
reads or writes a structure.
********************************************************************/
static BOOL sam_io_user_info24(char *desc, SAM_USER_INFO_24 * usr,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (usr == NULL)
return False;
const NTTIME * pass_last_set_time, /* all zeros */
const NTTIME * pass_can_change_time, /* all zeros */
const NTTIME * pass_must_change_time, /* all zeros */
- const UNISTR2 * user_name,
- const UNISTR2 * full_name,
- const UNISTR2 * home_dir,
- const UNISTR2 * dir_drive,
- const UNISTR2 * log_scr,
- const UNISTR2 * prof_path,
- const UNISTR2 * desc,
- const UNISTR2 * wkstas,
- const UNISTR2 * unk_str,
- const UNISTR2 * mung_dial, uint32 user_rid, /* 0x0000 0000 */
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name, const UNISTR2 *home_dir, const UNISTR2 *dir_drive, const UNISTR2 *log_scr, const UNISTR2 *prof_path, const UNISTR2 *desc, const UNISTR2 *wkstas, const UNISTR2 *unk_str, const UNISTR2 *mung_dial, uint32 user_rid, /* 0x0000 0000 */
uint32 group_rid,
uint32 acb_info,
uint32 unknown_3,
usr->unknown_6 = unknown_6; /* 0x0000 04ec */
usr->padding4 = 0;
- if (hrs)
- {
- memcpy(&(usr->logon_hrs), hrs, sizeof(usr->logon_hrs));
- }
- else
- {
- memset(&(usr->logon_hrs), 0xff, sizeof(usr->logon_hrs));
- }
+ Memcpy(&(usr->logon_hrs), hrs, sizeof(usr->logon_hrs));
return True;
}
usr->unknown_6 = unknown_6; /* 0x0000 04ec */
usr->padding4 = 0;
- if (hrs)
- {
- memcpy(&(usr->logon_hrs), hrs, sizeof(usr->logon_hrs));
- }
- else
- {
- memset(&(usr->logon_hrs), 0xff, sizeof(usr->logon_hrs));
- }
+ Memcpy(&(usr->logon_hrs), hrs, sizeof(usr->logon_hrs));
return True;
}
reads or writes a structure.
********************************************************************/
static BOOL sam_io_user_info23(char *desc, SAM_USER_INFO_23 * usr,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (usr == NULL)
return False;
const NTTIME * pass_last_set_time,
const NTTIME * pass_can_change_time,
const NTTIME * pass_must_change_time,
- const UNISTR2 * user_name,
- const UNISTR2 * full_name,
- const UNISTR2 * home_dir,
- const UNISTR2 * dir_drive,
- const UNISTR2 * log_scr,
- const UNISTR2 * prof_path,
- const UNISTR2 * desc,
- const UNISTR2 * wkstas,
- const UNISTR2 * unk_str,
- const UNISTR2 * mung_dial,
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *desc,
+ const UNISTR2 *wkstas,
+ const UNISTR2 *unk_str,
+ const UNISTR2 *mung_dial,
const uchar lm_pwd[16],
const uchar nt_pwd[16],
uint32 user_rid,
make_uni_hdr(&(usr->hdr_unknown_str), len_unknown_str);
make_uni_hdr(&(usr->hdr_munged_dial), len_munged_dial);
- if (lm_pwd == NULL)
- {
- ZERO_STRUCT(usr->lm_pwd);
- }
- else
- {
- memcpy(usr->lm_pwd, lm_pwd, sizeof(usr->lm_pwd));
- }
- if (nt_pwd == NULL)
- {
- ZERO_STRUCT(usr->nt_pwd);
- }
- else
- {
- memcpy(usr->nt_pwd, nt_pwd, sizeof(usr->nt_pwd));
- }
+ Memcpy(usr->lm_pwd, lm_pwd, sizeof(usr->lm_pwd));
+ Memcpy(usr->nt_pwd, nt_pwd, sizeof(usr->nt_pwd));
usr->user_rid = user_rid;
usr->group_rid = group_rid;
usr->unknown_6 = unknown_6; /* 0x0000 04ec */
usr->padding4 = 0;
- if (hrs)
- {
- memcpy(&(usr->logon_hrs), hrs, sizeof(usr->logon_hrs));
- }
- else
- {
- memset(&(usr->logon_hrs), 0xff, sizeof(usr->logon_hrs));
- }
+ Memcpy(&(usr->logon_hrs), hrs, sizeof(usr->logon_hrs));
return True;
}
usr->unknown_6 = unknown_6; /* 0x0000 04ec */
usr->padding4 = 0;
- if (hrs)
- {
- memcpy(&(usr->logon_hrs), hrs, sizeof(usr->logon_hrs));
- }
- else
- {
- memset(&(usr->logon_hrs), 0xff, sizeof(usr->logon_hrs));
- }
+ Memcpy(&(usr->logon_hrs), hrs, sizeof(usr->logon_hrs));
return True;
}
reads or writes a structure.
********************************************************************/
BOOL sam_io_user_info21(char *desc, SAM_USER_INFO_21 * usr,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (usr == NULL)
return False;
ctr->info.id = (SAM_USER_INFO_11 *) Realloc(NULL,
sizeof
- (*ctr->info.id11));
+ (*ctr->
+ info.
+ id11));
make_sam_user_info11(ctr->info.id11, &expire,
"BROOKFIELDS$", /* name */
0x03ef, /* user rid */
reads or writes a structure.
********************************************************************/
static BOOL samr_io_userinfo_ctr(char *desc, SAM_USERINFO_CTR * ctr,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
BOOL ret;
if (ctr == NULL)
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_query_userinfo(char *desc, SAMR_R_QUERY_USERINFO * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
makes a SAMR_Q_SET_USERINFO structure.
********************************************************************/
BOOL make_samr_q_set_userinfo(SAMR_Q_SET_USERINFO * q_u,
- POLICY_HND * hnd,
+ POLICY_HND *hnd,
uint16 switch_value, void *info)
{
uchar sess_key[16];
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_set_userinfo(char *desc, SAMR_Q_SET_USERINFO * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_set_userinfo(char *desc, SAMR_R_SET_USERINFO * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
makes a SAMR_Q_SET_USERINFO2 structure.
********************************************************************/
BOOL make_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 * q_u,
- POLICY_HND * hnd,
+ POLICY_HND *hnd,
uint16 switch_value, SAM_USERINFO_CTR * ctr)
{
uint8 usr_sess_key[16];
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_set_userinfo2(char *desc, SAMR_Q_SET_USERINFO2 * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_set_userinfo2(char *desc, SAMR_R_SET_USERINFO2 * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_connect(char *desc, SAMR_Q_CONNECT * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_connect(char *desc, SAMR_R_CONNECT * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_connect_anon(char *desc, SAMR_Q_CONNECT_ANON * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_connect_anon(char *desc, SAMR_R_CONNECT_ANON * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_get_dom_pwinfo(char *desc, SAMR_Q_GET_DOM_PWINFO * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_get_dom_pwinfo(char *desc, SAMR_R_GET_DOM_PWINFO * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
reads or writes a SAMR_ENC_PASSWD structure.
********************************************************************/
BOOL samr_io_enc_passwd(char *desc, SAMR_ENC_PASSWD * pwd,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (pwd == NULL)
return False;
reads or writes a SAMR_ENC_HASH structure.
********************************************************************/
BOOL samr_io_enc_hash(char *desc, SAMR_ENC_HASH * hsh,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (hsh == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_chgpasswd_user(char *desc, SAMR_Q_CHGPASSWD_USER * q_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_chgpasswd_user(char *desc, SAMR_R_CHGPASSWD_USER * r_u,
- prs_struct * ps, int depth)
+ prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
/*******************************************************************
makes a structure.
********************************************************************/
-BOOL make_sec_access(SEC_ACCESS *t, uint32 mask)
+BOOL make_sec_access(SEC_ACCESS * t, uint32 mask)
{
+ ZERO_STRUCTP(t);
t->mask = mask;
-
return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL sec_io_access(char *desc, SEC_ACCESS *t, prs_struct *ps, int depth)
+BOOL sec_io_access(char *desc, SEC_ACCESS * t, prs_struct *ps, int depth)
{
- if (t == NULL) return False;
+ if (t == NULL)
+ return False;
prs_debug(ps, depth, desc, "sec_io_access");
depth++;
prs_align(ps);
-
+
prs_uint32("mask", ps, depth, &(t->mask));
return True;
/*******************************************************************
makes a structure.
********************************************************************/
-BOOL make_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag)
+BOOL make_sec_ace(SEC_ACE * t, const DOM_SID *sid, uint8 type,
+ SEC_ACCESS mask, uint8 flag)
{
+ ZERO_STRUCTP(t);
+
t->type = type;
t->flags = flag;
t->size = sid_size(sid) + 8;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL sec_io_ace(char *desc, SEC_ACE *t, prs_struct *ps, int depth)
+BOOL sec_io_ace(char *desc, SEC_ACE * t, prs_struct *ps, int depth)
{
uint32 old_offset;
uint32 offset_ace_size;
- if (t == NULL) return False;
+ if (t == NULL)
+ return False;
prs_debug(ps, depth, desc, "sec_io_ace");
depth++;
prs_align(ps);
-
+
old_offset = ps->offset;
- prs_uint8 ("type ", ps, depth, &(t->type));
- prs_uint8 ("flags", ps, depth, &(t->flags));
- prs_uint16_pre("size ", ps, depth, &(t->size ), &offset_ace_size);
+ prs_uint8("type ", ps, depth, &(t->type));
+ prs_uint8("flags", ps, depth, &(t->flags));
+ prs_uint16_pre("size ", ps, depth, &(t->size), &offset_ace_size);
- sec_io_access ("info ", &t->info, ps, depth);
+ sec_io_access("info ", &t->info, ps, depth);
prs_align(ps);
- smb_io_dom_sid("sid ", &t->sid , ps, depth);
+ smb_io_dom_sid("sid ", &t->sid, ps, depth);
prs_align(ps);
- prs_uint16_post("size ", ps, depth, &t->size, offset_ace_size, old_offset);
+ prs_uint16_post("size ", ps, depth, &t->size, offset_ace_size,
+ old_offset);
return True;
}
/*******************************************************************
makes a structure.
********************************************************************/
-BOOL make_sec_acl(SEC_ACL *t, uint16 revision, int num_aces, SEC_ACE *ace)
+BOOL make_sec_acl(SEC_ACL * t, uint16 revision, int num_aces, SEC_ACE * ace)
{
int i;
+
+ ZERO_STRUCTP(t);
+
t->revision = revision;
t->num_aces = num_aces;
- t->size = 4;
+ t->size = 8;
t->ace = ace;
for (i = 0; i < num_aces; i++)
/*******************************************************************
frees a structure.
********************************************************************/
-void free_sec_acl(SEC_ACL *t)
+void free_sec_acl(SEC_ACL * t)
{
- if (t == NULL) return;
+ if (t == NULL)
+ return;
if (t->ace != NULL)
{
free(t->ace);
first of the xx_io_xx functions that allocates its data structures
for you as it reads them.
********************************************************************/
-BOOL sec_io_acl(char *desc, SEC_ACL *t, prs_struct *ps, int depth)
+BOOL sec_io_acl(char *desc, SEC_ACL * t, prs_struct *ps, int depth)
{
uint32 i;
uint32 old_offset;
uint32 offset_acl_size;
- if (t == NULL) return False;
+ if (t == NULL)
+ return False;
prs_debug(ps, depth, desc, "sec_io_acl");
depth++;
prs_align(ps);
-
+
old_offset = ps->offset;
prs_uint16("revision", ps, depth, &(t->revision));
- prs_uint16_pre("size ", ps, depth, &(t->size ), &offset_acl_size);
- prs_uint32("num_aces ", ps, depth, &(t->num_aces ));
+ prs_uint16_pre("size ", ps, depth, &(t->size), &offset_acl_size);
+ prs_uint32("num_aces ", ps, depth, &(t->num_aces));
if (ps->io && t->num_aces != 0)
{
/* reading */
- t->ace = (SEC_ACE*)malloc(sizeof(t->ace[0]) * t->num_aces);
+ t->ace = (SEC_ACE *) malloc(sizeof(t->ace[0]) * t->num_aces);
ZERO_STRUCTP(t->ace);
- }
+ }
if (t->ace == NULL && t->num_aces != 0)
{
- DEBUG(0,("INVALID ACL\n"));
+ DEBUG(0, ("INVALID ACL\n"));
ps->offset = 0xfffffffe;
return False;
}
for (i = 0; i < MIN(t->num_aces, MAX_SEC_ACES); i++)
{
fstring tmp;
- slprintf(tmp, sizeof(tmp)-1, "ace[%02d]: ", i);
+ slprintf(tmp, sizeof(tmp) - 1, "ace[%02d]: ", i);
sec_io_ace(tmp, &t->ace[i], ps, depth);
}
prs_align(ps);
- prs_uint16_post("size ", ps, depth, &t->size , offset_acl_size, old_offset);
+ prs_uint16_post("size ", ps, depth, &t->size, offset_acl_size,
+ old_offset);
return True;
}
/*******************************************************************
makes a structure
********************************************************************/
-int make_sec_desc(SEC_DESC *t, uint16 revision, uint16 type,
- DOM_SID *owner_sid, DOM_SID *grp_sid,
- SEC_ACL *sacl, SEC_ACL *dacl)
+int make_sec_desc(SEC_DESC * t, uint16 revision, uint16 type,
+ DOM_SID *owner_sid, DOM_SID *grp_sid,
+ SEC_ACL * sacl, SEC_ACL * dacl)
{
uint32 offset;
+ ZERO_STRUCTP(t);
+
t->revision = revision;
- t->type = type;
+ t->type = type;
t->off_owner_sid = 0;
- t->off_grp_sid = 0;
- t->off_sacl = 0;
- t->off_dacl = 0;
+ t->off_grp_sid = 0;
+ t->off_sacl = 0;
+ t->off_dacl = 0;
- t->dacl = dacl;
- t->sacl = sacl;
+ t->dacl = dacl;
+ t->sacl = sacl;
t->owner_sid = owner_sid;
- t->grp_sid = grp_sid;
+ t->grp_sid = grp_sid;
offset = 0x0;
}
t->off_dacl = offset;
offset += dacl->size;
+ offset = ((offset + 3) & ~3);
}
if (sacl != NULL)
}
t->off_sacl = offset;
offset += sacl->size;
+ offset = ((offset + 3) & ~3);
}
if (owner_sid != NULL)
}
t->off_owner_sid = offset;
offset += sid_size(owner_sid);
+ offset = ((offset + 3) & ~3);
}
if (grp_sid != NULL)
/*******************************************************************
frees a structure
********************************************************************/
-void free_sec_desc(SEC_DESC *t)
+void free_sec_desc(SEC_DESC * t)
{
if (t->dacl != NULL)
{
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL sec_io_desc(char *desc, SEC_DESC *t, prs_struct *ps, int depth)
+BOOL sec_io_desc(char *desc, SEC_DESC * t, prs_struct *ps, int depth)
{
#if 0
uint32 off_owner_sid;
- uint32 off_grp_sid ;
- uint32 off_sacl ;
- uint32 off_dacl ;
+ uint32 off_grp_sid;
+ uint32 off_sacl;
+ uint32 off_dacl;
#endif
uint32 old_offset;
- uint32 max_offset = 0; /* after we're done, move offset to end */
+ uint32 max_offset = 0; /* after we're done, move offset to end */
- if (t == NULL) return False;
+ if (t == NULL)
+ return False;
prs_debug(ps, depth, desc, "sec_io_desc");
depth++;
prs_align(ps);
-
+
/* start of security descriptor stored for back-calc offset purposes */
old_offset = ps->offset;
max_offset = old_offset;
- prs_uint16("revision ", ps, depth, &(t->revision ));
- prs_uint16("type ", ps, depth, &(t->type ));
+ prs_uint16("revision ", ps, depth, &(t->revision));
+ prs_uint16("type ", ps, depth, &(t->type));
prs_uint32("off_owner_sid", ps, depth, &(t->off_owner_sid));
- prs_uint32("off_grp_sid ", ps, depth, &(t->off_grp_sid ));
- prs_uint32("off_sacl ", ps, depth, &(t->off_sacl ));
- prs_uint32("off_dacl ", ps, depth, &(t->off_dacl ));
+ prs_uint32("off_grp_sid ", ps, depth, &(t->off_grp_sid));
+ prs_uint32("off_sacl ", ps, depth, &(t->off_sacl));
+ prs_uint32("off_dacl ", ps, depth, &(t->off_dacl));
#if 0
- prs_uint32_pre("off_owner_sid", ps, depth, &(t->off_owner_sid), &off_owner_sid);
- prs_uint32_pre("off_grp_sid ", ps, depth, &(t->off_grp_sid ), &off_grp_sid );
- prs_uint32_pre("off_sacl ", ps, depth, &(t->off_sacl ), &off_sacl );
- prs_uint32_pre("off_dacl ", ps, depth, &(t->off_dacl ), &off_dacl );
+ prs_uint32_pre("off_owner_sid", ps, depth, &(t->off_owner_sid),
+ &off_owner_sid);
+ prs_uint32_pre("off_grp_sid ", ps, depth, &(t->off_grp_sid),
+ &off_grp_sid);
+ prs_uint32_pre("off_sacl ", ps, depth, &(t->off_sacl), &off_sacl);
+ prs_uint32_pre("off_dacl ", ps, depth, &(t->off_dacl), &off_dacl);
#endif
max_offset = MAX(max_offset, ps->offset);
if (IS_BITS_SET_ALL(t->type, SEC_DESC_DACL_PRESENT))
{
#if 0
- prs_uint32_post("off_dacl ", ps, depth, &(t->off_dacl ), off_dacl , ps->offset - old_offset);
+ prs_uint32_post("off_dacl ", ps, depth, &(t->off_dacl),
+ off_dacl, ps->offset - old_offset);
#endif
ps->offset = old_offset + t->off_dacl;
if (ps->io)
{
/* reading */
- t->dacl = (SEC_ACL*)malloc(sizeof(*t->dacl));
+ t->dacl = (SEC_ACL *) malloc(sizeof(*t->dacl));
ZERO_STRUCTP(t->dacl);
}
if (t->dacl == NULL)
{
- DEBUG(0,("INVALID DACL\n"));
+ DEBUG(0, ("INVALID DACL\n"));
ps->offset = 0xfffffffe;
return False;
}
- sec_io_acl ("dacl" , t->dacl , ps, depth);
+ sec_io_acl("dacl", t->dacl, ps, depth);
prs_align(ps);
}
#if 0
else
{
- prs_uint32_post("off_dacl ", ps, depth, &(t->off_dacl ), off_dacl , 0);
+ prs_uint32_post("off_dacl ", ps, depth, &(t->off_dacl),
+ off_dacl, 0);
}
#endif
if (IS_BITS_SET_ALL(t->type, SEC_DESC_SACL_PRESENT))
{
#if 0
- prs_uint32_post("off_sacl ", ps, depth, &(t->off_sacl ), off_sacl , ps->offset - old_offset);
+ prs_uint32_post("off_sacl ", ps, depth, &(t->off_sacl),
+ off_sacl, ps->offset - old_offset);
#endif
ps->offset = old_offset + t->off_sacl;
if (ps->io)
{
/* reading */
- t->sacl = (SEC_ACL*)malloc(sizeof(*t->sacl));
+ t->sacl = (SEC_ACL *) malloc(sizeof(*t->sacl));
ZERO_STRUCTP(t->sacl);
}
if (t->sacl == NULL)
{
- DEBUG(0,("INVALID SACL\n"));
+ DEBUG(0, ("INVALID SACL\n"));
ps->offset = 0xfffffffe;
return False;
}
- sec_io_acl ("sacl" , t->sacl , ps, depth);
+ sec_io_acl("sacl", t->sacl, ps, depth);
prs_align(ps);
}
#if 0
else
{
- prs_uint32_post("off_sacl ", ps, depth, &(t->off_sacl ), off_sacl , 0);
+ prs_uint32_post("off_sacl ", ps, depth, &(t->off_sacl),
+ off_sacl, 0);
}
#endif
max_offset = MAX(max_offset, ps->offset);
#if 0
- prs_uint32_post("off_owner_sid", ps, depth, &(t->off_owner_sid), off_owner_sid, ps->offset - old_offset);
+ prs_uint32_post("off_owner_sid", ps, depth, &(t->off_owner_sid),
+ off_owner_sid, ps->offset - old_offset);
#endif
if (t->off_owner_sid != 0)
{
if (ps->io)
{
ps->offset = old_offset + t->off_owner_sid;
- }
+ }
if (ps->io)
{
/* reading */
- t->owner_sid = (DOM_SID*)malloc(sizeof(*t->owner_sid));
+ t->owner_sid =
+ (DOM_SID *)malloc(sizeof(*t->owner_sid));
ZERO_STRUCTP(t->owner_sid);
}
if (t->owner_sid == NULL)
{
- DEBUG(0,("INVALID OWNER SID\n"));
+ DEBUG(0, ("INVALID OWNER SID\n"));
ps->offset = 0xfffffffe;
return False;
}
- smb_io_dom_sid("owner_sid ", t->owner_sid , ps, depth);
+ smb_io_dom_sid("owner_sid ", t->owner_sid, ps, depth);
prs_align(ps);
}
max_offset = MAX(max_offset, ps->offset);
#if 0
- prs_uint32_post("off_grp_sid ", ps, depth, &(t->off_grp_sid ), off_grp_sid , ps->offset - old_offset);
+ prs_uint32_post("off_grp_sid ", ps, depth, &(t->off_grp_sid),
+ off_grp_sid, ps->offset - old_offset);
#endif
if (t->off_grp_sid != 0)
{
if (ps->io)
{
/* reading */
- t->grp_sid = (DOM_SID*)malloc(sizeof(*t->grp_sid));
+ t->grp_sid = (DOM_SID *)malloc(sizeof(*t->grp_sid));
ZERO_STRUCTP(t->grp_sid);
}
if (t->grp_sid == NULL)
{
- DEBUG(0,("INVALID GROUP SID\n"));
+ DEBUG(0, ("INVALID GROUP SID\n"));
ps->offset = 0xfffffffe;
return False;
}
/*******************************************************************
creates a SEC_DESC_BUF structure.
********************************************************************/
-BOOL make_sec_desc_buf(SEC_DESC_BUF *buf, int len, SEC_DESC *data)
+BOOL make_sec_desc_buf(SEC_DESC_BUF * buf, int len, SEC_DESC * data)
{
ZERO_STRUCTP(buf);
/* max buffer size (allocated size) */
buf->max_len = len;
- buf->undoc = 0;
+ buf->undoc = 0;
buf->len = data != NULL ? len : 0;
buf->sec = data;
/*******************************************************************
frees a SEC_DESC_BUF structure.
********************************************************************/
-void free_sec_desc_buf(SEC_DESC_BUF *buf)
+void free_sec_desc_buf(SEC_DESC_BUF * buf)
{
- if (buf == NULL) return;
+ if (buf == NULL)
+ return;
if (buf->sec != NULL)
{
free_sec_desc(buf->sec);
/*******************************************************************
reads or writes a SEC_DESC_BUF structure.
********************************************************************/
-BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF *sec, prs_struct *ps, int depth)
+BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF * sec, prs_struct *ps,
+ int depth)
{
uint32 off_len;
uint32 off_max_len;
uint32 old_offset;
uint32 size;
- if (sec == NULL) return False;
+ if (sec == NULL)
+ return False;
prs_debug(ps, depth, desc, "sec_io_desc_buf");
depth++;
prs_align(ps);
-
+
prs_uint32_pre("max_len", ps, depth, &(sec->max_len), &off_max_len);
- prs_uint32 ("undoc ", ps, depth, &(sec->undoc ));
- prs_uint32_pre("len ", ps, depth, &(sec->len ), &off_len);
+ prs_uint32("undoc ", ps, depth, &(sec->undoc));
+ prs_uint32_pre("len ", ps, depth, &(sec->len), &off_len);
old_offset = ps->offset;
if (sec->len != 0 && ps->io)
{
/* reading */
- sec->sec = (SEC_DESC*)malloc(sizeof(*sec->sec));
+ sec->sec = (SEC_DESC *) malloc(sizeof(*sec->sec));
ZERO_STRUCTP(sec->sec);
if (sec->sec == NULL)
{
- DEBUG(0,("INVALID SEC_DESC\n"));
+ DEBUG(0, ("INVALID SEC_DESC\n"));
ps->offset = 0xfffffffe;
return False;
}
}
prs_align(ps);
-
+
size = ps->offset - old_offset - 8;
- prs_uint32_post("max_len", ps, depth, &(sec->max_len), off_max_len, size == 0 ? sec->max_len : size + 8);
- prs_uint32_post("len ", ps, depth, &(sec->len ), off_len , size == 0 ? 0 : size + 8);
+ prs_uint32_post("max_len", ps, depth, &(sec->max_len), off_max_len,
+ size == 0 ? sec->max_len : size + 8);
+ prs_uint32_post("len ", ps, depth, &(sec->len), off_len,
+ size == 0 ? 0 : size + 8);
ps->offset = old_offset + size + 8;
return True;
}
-
makes a SHARE_INFO_1 structure
********************************************************************/
static BOOL make_srv_share_info_1(SHARE_INFO_1 * sh1,
- const char *net_name, uint32 type,
- const char *remark)
+ const char *net_name, uint32 type,
+ const char *remark)
{
if (sh1 == NULL)
return False;
q_n->share_level = share_level;
q_n->preferred_len = preferred_len;
- memcpy(&(q_n->enum_hnd), hnd, sizeof(*hnd));
+ q_n->enum_hnd = *hnd;
return True;
}
q_n->sess_level = sess_level;
q_n->preferred_len = preferred_len;
- memcpy(&(q_n->enum_hnd), hnd, sizeof(*hnd));
+ q_n->enum_hnd = *hnd;
return True;
}
q_n->conn_level = conn_level;
q_n->preferred_len = preferred_len;
- memcpy(&(q_n->enum_hnd), hnd, sizeof(*hnd));
+ q_n->enum_hnd = *hnd;
return True;
}
q_n->tprt_level = tprt_level;
q_n->preferred_len = preferred_len;
- memcpy(&(q_n->enum_hnd), hnd, sizeof(*hnd));
+ q_n->enum_hnd = *hnd;
return True;
}
q_n->file_level = file_level;
q_n->preferred_len = preferred_len;
- memcpy(&(q_n->enum_hnd), hnd, sizeof(*hnd));
+ q_n->enum_hnd = *hnd;
return True;
}
/*******************************************************************
make_svc_q_open_sc_man
********************************************************************/
-BOOL make_svc_q_open_sc_man(SVC_Q_OPEN_SC_MAN *q_u,
- const char *server, const char *database,
- uint32 des_access)
+BOOL make_svc_q_open_sc_man(SVC_Q_OPEN_SC_MAN * q_u,
+ const char *server, const char *database,
+ uint32 des_access)
{
- DEBUG(5,("make_svc_q_open_sc_man\n"));
+ DEBUG(5, ("make_svc_q_open_sc_man\n"));
make_buf_unistr2(&(q_u->uni_srv_name), &(q_u->ptr_srv_name), server);
- make_buf_unistr2(&(q_u->uni_db_name ), &(q_u->ptr_db_name), database);
+ make_buf_unistr2(&(q_u->uni_db_name), &(q_u->ptr_db_name), database);
q_u->des_access = des_access;
return True;
/*******************************************************************
reads or writes a SVC_Q_OPEN_SC_MAN structure.
********************************************************************/
-BOOL svc_io_q_open_sc_man(char *desc, SVC_Q_OPEN_SC_MAN *q_u, prs_struct *ps, int depth)
+BOOL svc_io_q_open_sc_man(char *desc, SVC_Q_OPEN_SC_MAN * q_u, prs_struct *ps,
+ int depth)
{
- if (q_u == NULL) return False;
+ if (q_u == NULL)
+ return False;
prs_debug(ps, depth, desc, "svc_io_q_open_sc_man");
depth++;
prs_align(ps);
prs_uint32("ptr_srv_name", ps, depth, &(q_u->ptr_srv_name));
- smb_io_unistr2("", &(q_u->uni_srv_name), q_u->ptr_srv_name, ps, depth);
+ smb_io_unistr2("", &(q_u->uni_srv_name), q_u->ptr_srv_name, ps,
+ depth);
prs_align(ps);
prs_uint32("ptr_db_name", ps, depth, &(q_u->ptr_db_name));
- smb_io_unistr2("", &(q_u->uni_db_name), q_u->ptr_db_name, ps, depth);
+ smb_io_unistr2("", &(q_u->uni_db_name), q_u->ptr_db_name, ps, depth);
prs_align(ps);
prs_uint32("des_access", ps, depth, &(q_u->des_access));
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL svc_io_r_open_sc_man(char *desc, SVC_R_OPEN_SC_MAN *r_u, prs_struct *ps, int depth)
+BOOL svc_io_r_open_sc_man(char *desc, SVC_R_OPEN_SC_MAN * r_u, prs_struct *ps,
+ int depth)
{
- if (r_u == NULL) return False;
+ if (r_u == NULL)
+ return False;
prs_debug(ps, depth, desc, "svc_io_r_open_sc_man");
depth++;
/*******************************************************************
make_svc_q_open_service
********************************************************************/
-BOOL make_svc_q_open_service(SVC_Q_OPEN_SERVICE *q_u,
- POLICY_HND *hnd,
- const char *server,
- uint32 des_access)
+BOOL make_svc_q_open_service(SVC_Q_OPEN_SERVICE * q_u,
+ POLICY_HND *hnd,
+ const char *server, uint32 des_access)
{
- DEBUG(5,("make_svc_q_open_service\n"));
+ DEBUG(5, ("make_svc_q_open_service\n"));
- memcpy(&(q_u->scman_pol), hnd, sizeof(q_u->scman_pol));
- make_unistr2(&(q_u->uni_svc_name), server, strlen(server)+1);
+ q_u->scman_pol = *hnd;
+ make_unistr2(&(q_u->uni_svc_name), server, strlen(server) + 1);
q_u->des_access = des_access;
/*******************************************************************
reads or writes a SVC_Q_OPEN_SERVICE structure.
********************************************************************/
-BOOL svc_io_q_open_service(char *desc, SVC_Q_OPEN_SERVICE *q_u, prs_struct *ps, int depth)
+BOOL svc_io_q_open_service(char *desc, SVC_Q_OPEN_SERVICE * q_u,
+ prs_struct *ps, int depth)
{
- if (q_u == NULL) return False;
+ if (q_u == NULL)
+ return False;
prs_debug(ps, depth, desc, "svc_io_q_open_service");
depth++;
smb_io_pol_hnd("", &(q_u->scman_pol), ps, depth);
prs_align(ps);
- smb_io_unistr2("", &(q_u->uni_svc_name), 1, ps, depth);
+ smb_io_unistr2("", &(q_u->uni_svc_name), 1, ps, depth);
prs_align(ps);
prs_uint32("des_access", ps, depth, &(q_u->des_access));
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL svc_io_r_open_service(char *desc, SVC_R_OPEN_SERVICE *r_u, prs_struct *ps, int depth)
+BOOL svc_io_r_open_service(char *desc, SVC_R_OPEN_SERVICE * r_u,
+ prs_struct *ps, int depth)
{
- if (r_u == NULL) return False;
+ if (r_u == NULL)
+ return False;
prs_debug(ps, depth, desc, "svc_io_r_open_service");
depth++;
/*******************************************************************
makes an SVC_Q_STOP_SERVICE structure.
********************************************************************/
-BOOL make_svc_q_stop_service(SVC_Q_STOP_SERVICE *q_c, POLICY_HND *hnd,
- uint32 unk)
+BOOL make_svc_q_stop_service(SVC_Q_STOP_SERVICE * q_c, POLICY_HND *hnd,
+ uint32 unk)
{
- if (q_c == NULL || hnd == NULL) return False;
+ if (q_c == NULL || hnd == NULL)
+ return False;
- DEBUG(5,("make_svc_q_stop_service\n"));
+ DEBUG(5, ("make_svc_q_stop_service\n"));
- memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
+ q_c->pol = *hnd;
q_c->unknown = unk;
return True;
/*******************************************************************
reads or writes a SVC_Q_STOP_SERVICE structure.
********************************************************************/
-BOOL svc_io_q_stop_service(char *desc, SVC_Q_STOP_SERVICE *q_s, prs_struct *ps, int depth)
+BOOL svc_io_q_stop_service(char *desc, SVC_Q_STOP_SERVICE * q_s,
+ prs_struct *ps, int depth)
{
- if (q_s == NULL) return False;
+ if (q_s == NULL)
+ return False;
prs_debug(ps, depth, desc, "svc_io_q_stop_service");
depth++;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL svc_io_r_stop_service(char *desc, SVC_R_STOP_SERVICE *r_s, prs_struct *ps, int depth)
+BOOL svc_io_r_stop_service(char *desc, SVC_R_STOP_SERVICE * r_s,
+ prs_struct *ps, int depth)
{
- if (r_s == NULL) return False;
+ if (r_s == NULL)
+ return False;
prs_debug(ps, depth, desc, "svc_io_r_stop_service");
depth++;
/*******************************************************************
makes an SVC_Q_START_SERVICE structure.
********************************************************************/
-BOOL make_svc_q_start_service(SVC_Q_START_SERVICE *q_c, POLICY_HND *hnd,
- uint32 argc,
- char **argv)
+BOOL make_svc_q_start_service(SVC_Q_START_SERVICE * q_c, POLICY_HND *hnd,
+ uint32 argc, char **argv)
{
uint32 i;
- if (q_c == NULL || hnd == NULL) return False;
+ if (q_c == NULL || hnd == NULL)
+ return False;
- DEBUG(5,("make_svc_q_start_service\n"));
+ DEBUG(5, ("make_svc_q_start_service\n"));
- memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
+ q_c->pol = *hnd;
q_c->argc = argc;
q_c->ptr_args = 1;
q_c->argc2 = argc;
for (i = 0; i < argc; i++)
{
- size_t len_argv = argv[i] != NULL ? strlen(argv[i])+1 : 0;
+ size_t len_argv = argv[i] != NULL ? strlen(argv[i]) + 1 : 0;
q_c->ptr_argv[i] = argv[i] != NULL ? 1 : 0;
make_unistr2(&(q_c->argv[i]), argv[i], len_argv);
}
/*******************************************************************
reads or writes a SVC_Q_START_SERVICE structure.
********************************************************************/
-BOOL svc_io_q_start_service(char *desc, SVC_Q_START_SERVICE *q_s, prs_struct *ps, int depth)
+BOOL svc_io_q_start_service(char *desc, SVC_Q_START_SERVICE * q_s,
+ prs_struct *ps, int depth)
{
- if (q_s == NULL) return False;
+ if (q_s == NULL)
+ return False;
prs_debug(ps, depth, desc, "svc_io_q_start_service");
depth++;
smb_io_pol_hnd("", &(q_s->pol), ps, depth);
prs_align(ps);
- prs_uint32("argc ", ps, depth, &(q_s->argc ));
+ prs_uint32("argc ", ps, depth, &(q_s->argc));
prs_uint32("ptr_args", ps, depth, &(q_s->ptr_args));
if (q_s->ptr_args != 0)
for (i = 0; i < q_s->argc2; i++)
{
- prs_uint32("", ps, depth, &(q_s->ptr_argv[i]));
+ prs_uint32("", ps, depth, &(q_s->ptr_argv[i]));
}
for (i = 0; i < q_s->argc2; i++)
{
- smb_io_unistr2("", &(q_s->argv[i]), q_s->ptr_argv[i], ps, depth);
+ smb_io_unistr2("", &(q_s->argv[i]), q_s->ptr_argv[i],
+ ps, depth);
prs_align(ps);
}
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL svc_io_r_start_service(char *desc, SVC_R_START_SERVICE *r_s, prs_struct *ps, int depth)
+BOOL svc_io_r_start_service(char *desc, SVC_R_START_SERVICE * r_s,
+ prs_struct *ps, int depth)
{
- if (r_s == NULL) return False;
+ if (r_s == NULL)
+ return False;
prs_debug(ps, depth, desc, "svc_io_r_start_service");
depth++;
/*******************************************************************
make_svc_query_svc_cfg
********************************************************************/
-BOOL make_svc_query_svc_cfg(QUERY_SERVICE_CONFIG *q_u,
- uint32 service_type, uint32 start_type,
- uint32 error_control,
- char* bin_path_name, char* load_order_grp,
- uint32 tag_id,
- char* dependencies, char* service_start_name,
- char* disp_name)
+BOOL make_svc_query_svc_cfg(QUERY_SERVICE_CONFIG * q_u,
+ uint32 service_type, uint32 start_type,
+ uint32 error_control,
+ char *bin_path_name, char *load_order_grp,
+ uint32 tag_id,
+ char *dependencies, char *service_start_name,
+ char *disp_name)
{
- DEBUG(5,("make_svc_query_svc_cfg\n"));
+ DEBUG(5, ("make_svc_query_svc_cfg\n"));
q_u->service_type = service_type;
q_u->start_type = start_type;
q_u->error_control = error_control;
- make_buf_unistr2(&(q_u->uni_bin_path_name ), &(q_u->ptr_bin_path_name ), bin_path_name );
- make_buf_unistr2(&(q_u->uni_load_order_grp ), &(q_u->ptr_load_order_grp ), load_order_grp );
+ make_buf_unistr2(&(q_u->uni_bin_path_name), &(q_u->ptr_bin_path_name),
+ bin_path_name);
+ make_buf_unistr2(&(q_u->uni_load_order_grp),
+ &(q_u->ptr_load_order_grp), load_order_grp);
q_u->tag_id = tag_id;
- make_buf_unistr2(&(q_u->uni_dependencies ), &(q_u->ptr_dependencies ), dependencies );
- make_buf_unistr2(&(q_u->uni_service_start_name), &(q_u->ptr_service_start_name), service_start_name);
- make_buf_unistr2(&(q_u->uni_display_name ), &(q_u->ptr_display_name ), disp_name );
+ make_buf_unistr2(&(q_u->uni_dependencies), &(q_u->ptr_dependencies),
+ dependencies);
+ make_buf_unistr2(&(q_u->uni_service_start_name),
+ &(q_u->ptr_service_start_name), service_start_name);
+ make_buf_unistr2(&(q_u->uni_display_name), &(q_u->ptr_display_name),
+ disp_name);
return True;
}
/*******************************************************************
reads or writes a QUERY_SERVICE_CONFIG structure.
********************************************************************/
-BOOL svc_io_query_svc_cfg(char *desc, QUERY_SERVICE_CONFIG *q_u, prs_struct *ps, int depth)
+BOOL svc_io_query_svc_cfg(char *desc, QUERY_SERVICE_CONFIG * q_u,
+ prs_struct *ps, int depth)
{
- if (q_u == NULL) return False;
+ if (q_u == NULL)
+ return False;
prs_debug(ps, depth, desc, "svc_io_query_svc_cfg");
depth++;
prs_align(ps);
- prs_uint32("service_type ", ps, depth, &(q_u->service_type ));
- prs_uint32("start_type ", ps, depth, &(q_u->start_type ));
- prs_uint32("error_control ", ps, depth, &(q_u->error_control ));
- prs_uint32("ptr_bin_path_name ", ps, depth, &(q_u->ptr_bin_path_name ));
- prs_uint32("ptr_load_order_grp ", ps, depth, &(q_u->ptr_load_order_grp ));
- prs_uint32("tag_id ", ps, depth, &(q_u->tag_id ));
- prs_uint32("ptr_dependencies ", ps, depth, &(q_u->ptr_dependencies ));
- prs_uint32("ptr_service_start_name", ps, depth, &(q_u->ptr_service_start_name));
- prs_uint32("ptr_display_name ", ps, depth, &(q_u->ptr_display_name ));
+ prs_uint32("service_type ", ps, depth, &(q_u->service_type));
+ prs_uint32("start_type ", ps, depth, &(q_u->start_type));
+ prs_uint32("error_control ", ps, depth,
+ &(q_u->error_control));
+ prs_uint32("ptr_bin_path_name ", ps, depth,
+ &(q_u->ptr_bin_path_name));
+ prs_uint32("ptr_load_order_grp ", ps, depth,
+ &(q_u->ptr_load_order_grp));
+ prs_uint32("tag_id ", ps, depth, &(q_u->tag_id));
+ prs_uint32("ptr_dependencies ", ps, depth,
+ &(q_u->ptr_dependencies));
+ prs_uint32("ptr_service_start_name", ps, depth,
+ &(q_u->ptr_service_start_name));
+ prs_uint32("ptr_display_name ", ps, depth,
+ &(q_u->ptr_display_name));
- smb_io_unistr2("uni_bin_path_name ", &(q_u->uni_bin_path_name ), q_u->ptr_bin_path_name , ps, depth);
+ smb_io_unistr2("uni_bin_path_name ", &(q_u->uni_bin_path_name),
+ q_u->ptr_bin_path_name, ps, depth);
prs_align(ps);
- smb_io_unistr2("uni_load_order_grp ", &(q_u->uni_load_order_grp ), q_u->ptr_load_order_grp , ps, depth);
+ smb_io_unistr2("uni_load_order_grp ", &(q_u->uni_load_order_grp),
+ q_u->ptr_load_order_grp, ps, depth);
prs_align(ps);
- smb_io_unistr2("uni_dependencies ", &(q_u->uni_dependencies ), q_u->ptr_dependencies , ps, depth);
+ smb_io_unistr2("uni_dependencies ", &(q_u->uni_dependencies),
+ q_u->ptr_dependencies, ps, depth);
prs_align(ps);
- smb_io_unistr2("uni_service_start_name", &(q_u->uni_service_start_name), q_u->ptr_service_start_name, ps, depth);
+ smb_io_unistr2("uni_service_start_name",
+ &(q_u->uni_service_start_name),
+ q_u->ptr_service_start_name, ps, depth);
prs_align(ps);
- smb_io_unistr2("uni_display_name ", &(q_u->uni_display_name ), q_u->ptr_display_name , ps, depth);
+ smb_io_unistr2("uni_display_name ", &(q_u->uni_display_name),
+ q_u->ptr_display_name, ps, depth);
prs_align(ps);
return True;
/*******************************************************************
makes an SVC_Q_ENUM_SVCS_STATUS structure.
********************************************************************/
-BOOL make_svc_q_enum_svcs_status(SVC_Q_ENUM_SVCS_STATUS *q_c, POLICY_HND *hnd,
- uint32 service_type, uint32 service_state,
- uint32 buf_size, uint32 resume_hnd )
+BOOL make_svc_q_enum_svcs_status(SVC_Q_ENUM_SVCS_STATUS * q_c,
+ POLICY_HND *hnd, uint32 service_type,
+ uint32 service_state, uint32 buf_size,
+ uint32 resume_hnd)
{
- if (q_c == NULL || hnd == NULL) return False;
+ if (q_c == NULL || hnd == NULL)
+ return False;
- DEBUG(5,("make_svc_q_enum_svcs_status\n"));
+ DEBUG(5, ("make_svc_q_enum_svcs_status\n"));
- memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
+ q_c->pol = *hnd;
q_c->service_type = service_type;
q_c->service_state = service_state;
q_c->buf_size = buf_size;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL svc_io_q_enum_svcs_status(char *desc, SVC_Q_ENUM_SVCS_STATUS *q_u, prs_struct *ps, int depth)
+BOOL svc_io_q_enum_svcs_status(char *desc, SVC_Q_ENUM_SVCS_STATUS * q_u,
+ prs_struct *ps, int depth)
{
- if (q_u == NULL) return False;
+ if (q_u == NULL)
+ return False;
prs_debug(ps, depth, desc, "svc_io_q_enum_svcs_status");
depth++;
prs_align(ps);
- smb_io_pol_hnd("", &(q_u->pol), ps, depth);
+ smb_io_pol_hnd("", &(q_u->pol), ps, depth);
prs_align(ps);
- prs_uint32("service_type ", ps, depth, &(q_u->service_type ));
+ prs_uint32("service_type ", ps, depth, &(q_u->service_type));
prs_uint32("service_state", ps, depth, &(q_u->service_state));
- prs_uint32("buf_size ", ps, depth, &(q_u->buf_size ));
- smb_io_enum_hnd("resume_hnd", &(q_u->resume_hnd), ps, depth);
+ prs_uint32("buf_size ", ps, depth, &(q_u->buf_size));
+ smb_io_enum_hnd("resume_hnd", &(q_u->resume_hnd), ps, depth);
return True;
}
/*******************************************************************
makes an SVC_R_ENUM_SVCS_STATUS structure.
********************************************************************/
-BOOL make_svc_r_enum_svcs_status(SVC_R_ENUM_SVCS_STATUS *r_c,
- ENUM_SRVC_STATUS *svcs, uint32 more_buf_size,
- uint32 num_svcs, ENUM_HND *resume_hnd,
- uint32 dos_status)
+BOOL make_svc_r_enum_svcs_status(SVC_R_ENUM_SVCS_STATUS * r_c,
+ ENUM_SRVC_STATUS * svcs,
+ uint32 more_buf_size, uint32 num_svcs,
+ ENUM_HND * resume_hnd, uint32 dos_status)
{
- if (r_c == NULL) return False;
+ if (r_c == NULL)
+ return False;
- DEBUG(5,("make_svc_r_enum_svcs_status\n"));
+ DEBUG(5, ("make_svc_r_enum_svcs_status\n"));
- r_c->svcs = svcs;
+ r_c->svcs = svcs;
r_c->more_buf_size = more_buf_size;
- r_c->num_svcs = num_svcs;
- memcpy(&(r_c->resume_hnd), resume_hnd, sizeof(ENUM_HND));
+ r_c->num_svcs = num_svcs;
+ r_c->resume_hnd = *resume_hnd;
r_c->dos_status = dos_status;
return True;
ARGH!
********************************************************************/
-BOOL svc_io_r_enum_svcs_status(char *desc, SVC_R_ENUM_SVCS_STATUS *svc, prs_struct *ps, int depth)
+BOOL svc_io_r_enum_svcs_status(char *desc, SVC_R_ENUM_SVCS_STATUS * svc,
+ prs_struct *ps, int depth)
{
uint32 i;
- if (svc == NULL) return False;
+ if (svc == NULL)
+ return False;
prs_debug(ps, depth, desc, "svc_io_r_enum_svcs_status");
depth++;
prs_align(ps);
-
+
/*
* format is actually as laid out in SVC_R_ENUM_SVCS_STATUS.
* the reason for all the jumping about, which is horrible
prs_uint32("more_buf_size", ps, depth, &(svc->more_buf_size));
prs_uint32("num_svcs", ps, depth, &(svc->num_svcs));
- smb_io_enum_hnd("resume_hnd", &(svc->resume_hnd), ps, depth);
+ smb_io_enum_hnd("resume_hnd", &(svc->resume_hnd), ps, depth);
prs_uint32("dos_status", ps, depth, &(svc->dos_status));
new_offset = ps->offset;
ps->offset = buf_offset;
- svc->svcs = (ENUM_SRVC_STATUS*)Realloc(NULL,
- svc->num_svcs * sizeof(ENUM_SRVC_STATUS));
+ svc->svcs = (ENUM_SRVC_STATUS *) Realloc(NULL,
+ svc->num_svcs *
+ sizeof
+ (ENUM_SRVC_STATUS));
if (svc->svcs == NULL)
{
- DEBUG(0,("svc_io_r_enum_svcs_status: Realloc failed\n"));
+ DEBUG(0,
+ ("svc_io_r_enum_svcs_status: Realloc failed\n"));
ps->offset = 0x7fffffff;
return False;
}
- memset(svc->svcs, 0, svc->num_svcs * sizeof(ENUM_SRVC_STATUS));
+ memset(svc->svcs, 0,
+ svc->num_svcs * sizeof(ENUM_SRVC_STATUS));
for (i = 0; i < svc->num_svcs; i++)
{
prs_uint32("srvc_offset", ps, depth, &srvc_offset);
prs_uint32("disp_offset", ps, depth, &disp_offset);
- svc_io_svc_status("status", &svc->svcs[i].status, ps, depth);
+ svc_io_svc_status("status", &svc->svcs[i].status, ps,
+ depth);
old_offset = ps->offset;
ps->offset = buf_offset + srvc_offset;
- slprintf(name, sizeof(name)-1, "srvc[%02d]", i);
- smb_io_unistr(name, &svc->svcs[i].uni_srvc_name, ps, depth);
+ slprintf(name, sizeof(name) - 1, "srvc[%02d]", i);
+ smb_io_unistr(name, &svc->svcs[i].uni_srvc_name, ps,
+ depth);
ps->offset = buf_offset + disp_offset;
- slprintf(name, sizeof(name)-1, "disp[%02d]", i);
- smb_io_unistr(name, &svc->svcs[i].uni_disp_name, ps, depth);
+ slprintf(name, sizeof(name) - 1, "disp[%02d]", i);
+ smb_io_unistr(name, &svc->svcs[i].uni_disp_name, ps,
+ depth);
ps->offset = old_offset;
}
uint32 old_buf_offset;
uint32 srvc_offset = 9 * sizeof(uint32) * svc->num_svcs;
- prs_uint32_pre("buf_size", ps, depth, &svc->buf_size, &buf_offset);
+ prs_uint32_pre("buf_size", ps, depth, &svc->buf_size,
+ &buf_offset);
old_buf_offset = ps->offset;
srvc_offset += old_buf_offset;
prs_uint32("srvc_offset", ps, depth, &srvc_offset);
srvc_offset += old_buf_offset;
- slprintf(name, sizeof(name)-1, "srvc[%02d]", i);
+ slprintf(name, sizeof(name) - 1, "srvc[%02d]", i);
old_offset = ps->offset;
ps->offset = srvc_offset;
- smb_io_unistr(name, &svc->svcs[i].uni_srvc_name, ps, depth);
+ smb_io_unistr(name, &svc->svcs[i].uni_srvc_name, ps,
+ depth);
srvc_offset = ps->offset;
ps->offset = old_offset;
prs_uint32("disp_offset", ps, depth, &srvc_offset);
srvc_offset += old_buf_offset;
- slprintf(name, sizeof(name)-1, "disp[%02d]", i);
+ slprintf(name, sizeof(name) - 1, "disp[%02d]", i);
old_offset = ps->offset;
ps->offset = srvc_offset;
- smb_io_unistr(name, &svc->svcs[i].uni_disp_name, ps, depth);
+ smb_io_unistr(name, &svc->svcs[i].uni_disp_name, ps,
+ depth);
srvc_offset = ps->offset;
ps->offset = old_offset;
* store status info
*/
- svc_io_svc_status("status", &svc->svcs[i].status, ps, depth);
+ svc_io_svc_status("status", &svc->svcs[i].status, ps,
+ depth);
}
- prs_uint32_post("buf_size", ps, depth, &svc->buf_size, buf_offset, srvc_offset - buf_offset - sizeof(uint32));
+ prs_uint32_post("buf_size", ps, depth, &svc->buf_size,
+ buf_offset,
+ srvc_offset - buf_offset - sizeof(uint32));
ps->offset = srvc_offset;
prs_uint32("more_buf_size", ps, depth, &(svc->more_buf_size));
prs_uint32("num_svcs", ps, depth, &(svc->num_svcs));
- smb_io_enum_hnd("resume_hnd", &(svc->resume_hnd), ps, depth);
+ smb_io_enum_hnd("resume_hnd", &(svc->resume_hnd), ps, depth);
prs_uint32("dos_status", ps, depth, &(svc->dos_status));
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL svc_io_svc_status(char *desc, SVC_STATUS *svc, prs_struct *ps, int depth)
+BOOL svc_io_svc_status(char *desc, SVC_STATUS * svc, prs_struct *ps,
+ int depth)
{
- if (svc == NULL) return False;
+ if (svc == NULL)
+ return False;
prs_debug(ps, depth, desc, "svc_io_svc_status");
depth++;
prs_uint32("current_state", ps, depth, &(svc->current_state));
prs_uint32("controls_accepted", ps, depth, &(svc->controls_accepted));
prs_uint32("win32_exit_code", ps, depth, &(svc->win32_exit_code));
- prs_uint32("svc_specific_exit_code", ps, depth, &(svc->svc_specific_exit_code));
+ prs_uint32("svc_specific_exit_code", ps, depth,
+ &(svc->svc_specific_exit_code));
prs_uint32("check_point", ps, depth, &(svc->check_point));
prs_uint32("wait_hint", ps, depth, &(svc->wait_hint));
/*******************************************************************
makes an SVC_Q_QUERY_SVC_CONFIG structure.
********************************************************************/
-BOOL make_svc_q_query_svc_config(SVC_Q_QUERY_SVC_CONFIG *q_c, POLICY_HND *hnd,
- uint32 buf_size)
+BOOL make_svc_q_query_svc_config(SVC_Q_QUERY_SVC_CONFIG * q_c,
+ POLICY_HND *hnd, uint32 buf_size)
{
- if (q_c == NULL || hnd == NULL) return False;
+ if (q_c == NULL || hnd == NULL)
+ return False;
- DEBUG(5,("make_svc_q_query_svc_config\n"));
+ DEBUG(5, ("make_svc_q_query_svc_config\n"));
- memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
+ q_c->pol = *hnd;
q_c->buf_size = buf_size;
return True;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL svc_io_q_query_svc_config(char *desc, SVC_Q_QUERY_SVC_CONFIG *q_u, prs_struct *ps, int depth)
+BOOL svc_io_q_query_svc_config(char *desc, SVC_Q_QUERY_SVC_CONFIG * q_u,
+ prs_struct *ps, int depth)
{
- if (q_u == NULL) return False;
+ if (q_u == NULL)
+ return False;
prs_debug(ps, depth, desc, "svc_io_q_query_svc_config");
depth++;
prs_align(ps);
- smb_io_pol_hnd("", &(q_u->pol), ps, depth);
+ smb_io_pol_hnd("", &(q_u->pol), ps, depth);
prs_align(ps);
prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
/*******************************************************************
makes an SVC_R_QUERY_SVC_CONFIG structure.
********************************************************************/
-BOOL make_svc_r_query_svc_config(SVC_R_QUERY_SVC_CONFIG *r_c,
- QUERY_SERVICE_CONFIG *cfg,
- uint32 buf_size)
+BOOL make_svc_r_query_svc_config(SVC_R_QUERY_SVC_CONFIG * r_c,
+ QUERY_SERVICE_CONFIG * cfg, uint32 buf_size)
{
- if (r_c == NULL) return False;
+ if (r_c == NULL)
+ return False;
- DEBUG(5,("make_svc_r_query_svc_config\n"));
+ DEBUG(5, ("make_svc_r_query_svc_config\n"));
- r_c->cfg = cfg;
+ r_c->cfg = cfg;
r_c->buf_size = buf_size;
return True;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL svc_io_r_query_svc_config(char *desc, SVC_R_QUERY_SVC_CONFIG *r_u, prs_struct *ps, int depth)
+BOOL svc_io_r_query_svc_config(char *desc, SVC_R_QUERY_SVC_CONFIG * r_u,
+ prs_struct *ps, int depth)
{
- if (r_u == NULL) return False;
+ if (r_u == NULL)
+ return False;
prs_debug(ps, depth, desc, "svc_io_r_query_svc_config");
depth++;
prs_align(ps);
- svc_io_query_svc_cfg("cfg", r_u->cfg, ps, depth);
+ svc_io_query_svc_cfg("cfg", r_u->cfg, ps, depth);
prs_uint32("buf_size", ps, depth, &(r_u->buf_size));
- prs_uint32("status ", ps, depth, &(r_u->status ));
+ prs_uint32("status ", ps, depth, &(r_u->status));
return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL svc_io_q_query_disp_name(char *desc, SVC_Q_QUERY_DISP_NAME *q_u, prs_struct *ps, int depth)
+BOOL svc_io_q_query_disp_name(char *desc, SVC_Q_QUERY_DISP_NAME * q_u,
+ prs_struct *ps, int depth)
{
- if (q_u == NULL) return False;
+ if (q_u == NULL)
+ return False;
prs_debug(ps, depth, desc, "svc_io_q_query_disp_name");
depth++;
prs_align(ps);
- smb_io_pol_hnd("", &(q_u->scman_pol), ps, depth);
+ smb_io_pol_hnd("", &(q_u->scman_pol), ps, depth);
prs_align(ps);
- smb_io_unistr2("uni_svc_name", &(q_u->uni_svc_name), 1, ps, depth);
+ smb_io_unistr2("uni_svc_name", &(q_u->uni_svc_name), 1, ps, depth);
prs_align(ps);
prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL svc_io_r_query_disp_name(char *desc, SVC_R_QUERY_DISP_NAME *r_u, prs_struct *ps, int depth)
+BOOL svc_io_r_query_disp_name(char *desc, SVC_R_QUERY_DISP_NAME * r_u,
+ prs_struct *ps, int depth)
{
- if (r_u == NULL) return False;
+ if (r_u == NULL)
+ return False;
prs_debug(ps, depth, desc, "svc_io_r_query_disp_name");
depth++;
prs_align(ps);
- smb_io_unistr2("uni_disp_name", &(r_u->uni_disp_name), 1, ps, depth);
+ smb_io_unistr2("uni_disp_name", &(r_u->uni_disp_name), 1, ps, depth);
prs_align(ps);
prs_uint32("buf_size", ps, depth, &(r_u->buf_size));
- prs_uint32("status ", ps, depth, &(r_u->status ));
+ prs_uint32("status ", ps, depth, &(r_u->status));
return True;
}
/*******************************************************************
makes an SVC_Q_CLOSE structure.
********************************************************************/
-BOOL make_svc_q_close(SVC_Q_CLOSE *q_c, POLICY_HND *hnd)
+BOOL make_svc_q_close(SVC_Q_CLOSE * q_c, POLICY_HND *hnd)
{
- if (q_c == NULL || hnd == NULL) return False;
+ if (q_c == NULL || hnd == NULL)
+ return False;
- DEBUG(5,("make_svc_q_close\n"));
+ DEBUG(5, ("make_svc_q_close\n"));
- memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
+ q_c->pol = *hnd;
return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL svc_io_q_close(char *desc, SVC_Q_CLOSE *q_u, prs_struct *ps, int depth)
+BOOL svc_io_q_close(char *desc, SVC_Q_CLOSE * q_u, prs_struct *ps, int depth)
{
- if (q_u == NULL) return False;
+ if (q_u == NULL)
+ return False;
prs_debug(ps, depth, desc, "svc_io_q_close");
depth++;
prs_align(ps);
- smb_io_pol_hnd("", &(q_u->pol), ps, depth);
+ smb_io_pol_hnd("", &(q_u->pol), ps, depth);
prs_align(ps);
return True;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL svc_io_r_close(char *desc, SVC_R_CLOSE *r_u, prs_struct *ps, int depth)
+BOOL svc_io_r_close(char *desc, SVC_R_CLOSE * r_u, prs_struct *ps, int depth)
{
- if (r_u == NULL) return False;
+ if (r_u == NULL)
+ return False;
prs_debug(ps, depth, desc, "svc_io_r_close");
depth++;
prs_align(ps);
- smb_io_pol_hnd("", &(r_u->pol), ps, depth);
+ smb_io_pol_hnd("", &(r_u->pol), ps, depth);
prs_align(ps);
prs_uint32("status", ps, depth, &(r_u->status));
/*******************************************************************
makes an SVC_Q_CHANGE_SVC_CONFIG structure.
********************************************************************/
-BOOL make_svc_q_change_svc_config(SVC_Q_CHANGE_SVC_CONFIG *q_u, POLICY_HND *hnd,
- uint32 service_type, uint32 start_type,
- uint32 unknown_0,
- uint32 error_control,
- char* bin_path_name, char* load_order_grp,
- uint32 tag_id,
- char* dependencies, char* service_start_name,
- char* password,
- char* disp_name)
+BOOL make_svc_q_change_svc_config(SVC_Q_CHANGE_SVC_CONFIG * q_u,
+ POLICY_HND *hnd, uint32 service_type,
+ uint32 start_type, uint32 unknown_0,
+ uint32 error_control, char *bin_path_name,
+ char *load_order_grp, uint32 tag_id,
+ char *dependencies,
+ char *service_start_name, char *password,
+ char *disp_name)
{
- if (q_u == NULL || hnd == NULL) return False;
+ if (q_u == NULL || hnd == NULL)
+ return False;
- DEBUG(5,("make_svc_q_change_svc_config\n"));
+ DEBUG(5, ("make_svc_q_change_svc_config\n"));
- memcpy(&(q_u->pol), hnd, sizeof(q_u->pol));
+ q_u->pol = *hnd;
q_u->service_type = service_type;
q_u->start_type = start_type;
q_u->unknown_0 = unknown_0;
q_u->error_control = error_control;
- make_buf_unistr2(&(q_u->uni_bin_path_name ), &(q_u->ptr_bin_path_name ), bin_path_name );
- make_buf_unistr2(&(q_u->uni_load_order_grp ), &(q_u->ptr_load_order_grp ), load_order_grp );
+ make_buf_unistr2(&(q_u->uni_bin_path_name), &(q_u->ptr_bin_path_name),
+ bin_path_name);
+ make_buf_unistr2(&(q_u->uni_load_order_grp),
+ &(q_u->ptr_load_order_grp), load_order_grp);
q_u->tag_id = tag_id;
- make_buf_unistr2(&(q_u->uni_dependencies ), &(q_u->ptr_dependencies ), dependencies );
- make_buf_unistr2(&(q_u->uni_service_start_name), &(q_u->ptr_service_start_name), service_start_name);
- make_buf_string2(&(q_u->str_password ), &(q_u->ptr_password ), password );
- make_buf_unistr2(&(q_u->uni_display_name ), &(q_u->ptr_display_name ), disp_name );
+ make_buf_unistr2(&(q_u->uni_dependencies), &(q_u->ptr_dependencies),
+ dependencies);
+ make_buf_unistr2(&(q_u->uni_service_start_name),
+ &(q_u->ptr_service_start_name), service_start_name);
+ make_buf_string2(&(q_u->str_password), &(q_u->ptr_password),
+ password);
+ make_buf_unistr2(&(q_u->uni_display_name), &(q_u->ptr_display_name),
+ disp_name);
return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL svc_io_q_change_svc_config(char *desc, SVC_Q_CHANGE_SVC_CONFIG *q_u, prs_struct *ps, int depth)
+BOOL svc_io_q_change_svc_config(char *desc, SVC_Q_CHANGE_SVC_CONFIG * q_u,
+ prs_struct *ps, int depth)
{
- if (q_u == NULL) return False;
+ if (q_u == NULL)
+ return False;
prs_debug(ps, depth, desc, "svc_io_q_change_svc_config");
depth++;
prs_align(ps);
- smb_io_pol_hnd("", &(q_u->pol), ps, depth);
+ smb_io_pol_hnd("", &(q_u->pol), ps, depth);
prs_align(ps);
- prs_uint32("service_type ", ps, depth, &(q_u->service_type ));
- prs_uint32("start_type ", ps, depth, &(q_u->start_type ));
- prs_uint32("unknown_0 ", ps, depth, &(q_u->unknown_0 ));
- prs_uint32("error_control ", ps, depth, &(q_u->error_control ));
- prs_uint32("ptr_bin_path_name ", ps, depth, &(q_u->ptr_bin_path_name ));
- smb_io_unistr2("uni_bin_path_name ", &(q_u->uni_bin_path_name ), q_u->ptr_bin_path_name , ps, depth);
+ prs_uint32("service_type ", ps, depth, &(q_u->service_type));
+ prs_uint32("start_type ", ps, depth, &(q_u->start_type));
+ prs_uint32("unknown_0 ", ps, depth, &(q_u->unknown_0));
+ prs_uint32("error_control ", ps, depth,
+ &(q_u->error_control));
+ prs_uint32("ptr_bin_path_name ", ps, depth,
+ &(q_u->ptr_bin_path_name));
+ smb_io_unistr2("uni_bin_path_name ", &(q_u->uni_bin_path_name),
+ q_u->ptr_bin_path_name, ps, depth);
prs_align(ps);
- prs_uint32("ptr_load_order_grp ", ps, depth, &(q_u->ptr_load_order_grp ));
- smb_io_unistr2("uni_load_order_grp ", &(q_u->uni_load_order_grp ), q_u->ptr_load_order_grp , ps, depth);
+ prs_uint32("ptr_load_order_grp ", ps, depth,
+ &(q_u->ptr_load_order_grp));
+ smb_io_unistr2("uni_load_order_grp ", &(q_u->uni_load_order_grp),
+ q_u->ptr_load_order_grp, ps, depth);
prs_align(ps);
- prs_uint32("tag_id ", ps, depth, &(q_u->tag_id ));
- prs_uint32("ptr_dependencies ", ps, depth, &(q_u->ptr_dependencies ));
- smb_io_unistr2("uni_dependencies ", &(q_u->uni_dependencies ), q_u->ptr_dependencies , ps, depth);
+ prs_uint32("tag_id ", ps, depth, &(q_u->tag_id));
+ prs_uint32("ptr_dependencies ", ps, depth,
+ &(q_u->ptr_dependencies));
+ smb_io_unistr2("uni_dependencies ", &(q_u->uni_dependencies),
+ q_u->ptr_dependencies, ps, depth);
prs_align(ps);
- prs_uint32("ptr_service_start_name", ps, depth, &(q_u->ptr_service_start_name));
- smb_io_unistr2("uni_service_start_name", &(q_u->uni_service_start_name), q_u->ptr_service_start_name, ps, depth);
+ prs_uint32("ptr_service_start_name", ps, depth,
+ &(q_u->ptr_service_start_name));
+ smb_io_unistr2("uni_service_start_name",
+ &(q_u->uni_service_start_name),
+ q_u->ptr_service_start_name, ps, depth);
prs_align(ps);
- prs_uint32("ptr_password ", ps, depth, &(q_u->ptr_password ));
+ prs_uint32("ptr_password ", ps, depth, &(q_u->ptr_password));
- smb_io_string2("str_password ", &(q_u->str_password ), q_u->ptr_display_name , ps, depth);
+ smb_io_string2("str_password ", &(q_u->str_password),
+ q_u->ptr_display_name, ps, depth);
prs_align(ps);
- prs_uint32("ptr_display_name ", ps, depth, &(q_u->ptr_display_name ));
- smb_io_unistr2("uni_display_name ", &(q_u->uni_display_name ), q_u->ptr_display_name , ps, depth);
+ prs_uint32("ptr_display_name ", ps, depth,
+ &(q_u->ptr_display_name));
+ smb_io_unistr2("uni_display_name ", &(q_u->uni_display_name),
+ q_u->ptr_display_name, ps, depth);
prs_align(ps);
return True;
/*******************************************************************
makes an SVC_R_CHANGE_SVC_CONFIG structure.
********************************************************************/
-BOOL make_svc_r_change_svc_config(SVC_R_CHANGE_SVC_CONFIG *r_c,
- uint32 unknown_0, uint32 status)
+BOOL make_svc_r_change_svc_config(SVC_R_CHANGE_SVC_CONFIG * r_c,
+ uint32 unknown_0, uint32 status)
{
- if (r_c == NULL) return False;
+ if (r_c == NULL)
+ return False;
- DEBUG(5,("make_svc_r_change_svc_config\n"));
+ DEBUG(5, ("make_svc_r_change_svc_config\n"));
r_c->unknown_0 = unknown_0;
r_c->status = status;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL svc_io_r_change_svc_config(char *desc, SVC_R_CHANGE_SVC_CONFIG *r_u, prs_struct *ps, int depth)
+BOOL svc_io_r_change_svc_config(char *desc, SVC_R_CHANGE_SVC_CONFIG * r_u,
+ prs_struct *ps, int depth)
{
- if (r_u == NULL) return False;
+ if (r_u == NULL)
+ return False;
prs_debug(ps, depth, desc, "svc_io_r_change_svc_config");
depth++;
prs_align(ps);
prs_uint32("unknown_0", ps, depth, &(r_u->unknown_0));
- prs_uint32("status ", ps, depth, &(r_u->status ));
+ prs_uint32("status ", ps, depth, &(r_u->status));
return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL svc_io_q_unknown_3(char *desc, SVC_Q_UNKNOWN_3 *q_u,
+BOOL svc_io_q_unknown_3(char *desc, SVC_Q_UNKNOWN_3 * q_u,
prs_struct *ps, int depth)
{
- if (q_u == NULL) return False;
+ if (q_u == NULL)
+ return False;
prs_debug(ps, depth, desc, "svc_io_q_unknown_3");
depth++;
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL svc_io_r_unknown_3(char *desc, SVC_R_UNKNOWN_3 *r_u,
+BOOL svc_io_r_unknown_3(char *desc, SVC_R_UNKNOWN_3 * r_u,
prs_struct *ps, int depth)
{
- if (r_u == NULL) return False;
+ if (r_u == NULL)
+ return False;
prs_debug(ps, depth, desc, "svc_io_r_unknown_3");
depth++;
char *dev = strdup(name);
if (dev != NULL)
{
- if (set_policy_state(cache, hnd, NULL, (void*)dev))
+ if (set_policy_state(cache, hnd, NULL, (void *)dev))
{
- DEBUG(3,("Registry setting policy name=%s\n", name));
+ DEBUG(3, ("Registry setting policy name=%s\n", name));
return True;
}
free(dev);
}
- DEBUG(3,("Error setting policy name=%s\n", name));
+ DEBUG(3, ("Error setting policy name=%s\n", name));
return False;
}
#endif
static BOOL get_policy_reg_name(struct policy_cache *cache, POLICY_HND *hnd,
fstring name)
{
- char *dev = (char*)get_policy_state_info(cache, hnd);
+ char *dev = (char *)get_policy_state_info(cache, hnd);
if (dev != NULL)
{
fstrcpy(name, dev);
- DEBUG(5,("getting policy reg name=%s\n", name));
+ DEBUG(5, ("getting policy reg name=%s\n", name));
return True;
}
- DEBUG(3,("Error getting policy reg name\n"));
+ DEBUG(3, ("Error getting policy reg name\n"));
return False;
}
/*******************************************************************
api_reg_close
********************************************************************/
-static BOOL api_reg_close( rpcsrv_struct *p, prs_struct *data,
- prs_struct *rdata )
+static BOOL api_reg_close(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
- REG_Q_CLOSE q_r;
- REG_R_CLOSE r_u;
- ZERO_STRUCT(q_r);
- ZERO_STRUCT(r_u);
-
- /* grab the reg unknown 1 */
- if (!reg_io_q_close("", &q_r, data, 0))
+ REG_Q_CLOSE q_r;
+ REG_R_CLOSE r_u;
+ ZERO_STRUCT(q_r);
+ ZERO_STRUCT(r_u);
+
+ /* grab the reg unknown 1 */
+ if (!reg_io_q_close("", &q_r, data, 0))
{
return False;
}
-
- memcpy(&r_u.pol, &q_r.pol, sizeof(POLICY_HND));
-
- /* construct reply. always indicate success */
- r_u.status = _reg_close(&r_u.pol);
-
- /* store the response in the SMB stream */
- return reg_io_r_close("", &r_u, rdata, 0);
-}
+ r_u.pol = q_r.pol;
+
+ /* construct reply. always indicate success */
+ r_u.status = _reg_close(&r_u.pol);
+
+ /* store the response in the SMB stream */
+ return reg_io_r_close("", &r_u, rdata, 0);
+}
/*******************************************************************
api_reg_open
********************************************************************/
-static BOOL api_reg_open( rpcsrv_struct *p, prs_struct *data,
- prs_struct *rdata )
+static BOOL api_reg_open(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
- REG_Q_OPEN_HKLM q_u;
- REG_R_OPEN_HKLM r_u;
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- /* grab the reg open */
- if (!reg_io_q_open_hklm("", &q_u, data, 0))
+ REG_Q_OPEN_HKLM q_u;
+ REG_R_OPEN_HKLM r_u;
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ /* grab the reg open */
+ if (!reg_io_q_open_hklm("", &q_u, data, 0))
{
return False;
}
-
- r_u.status = _reg_open(&r_u.pol, q_u.access_mask);
-
- /* store the response in the SMB stream */
- return reg_io_r_open_hklm("", &r_u, rdata, 0);
+ r_u.status = _reg_open(&r_u.pol, q_u.access_mask);
+
+ /* store the response in the SMB stream */
+ return reg_io_r_open_hklm("", &r_u, rdata, 0);
}
/*******************************************************************
api_reg_open_entry
********************************************************************/
-static BOOL api_reg_open_entry( rpcsrv_struct *p, prs_struct *data,
- prs_struct *rdata )
+static BOOL api_reg_open_entry(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
uint32 status;
-
+
POLICY_HND entry_pol;
REG_Q_OPEN_ENTRY q_u;
- REG_R_OPEN_ENTRY r_u;
+ REG_R_OPEN_ENTRY r_u;
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
}
/* construct reply. */
- status = _reg_open_entry(&q_u.pol,&q_u.uni_name,q_u.unknown_0,q_u.access_mask,&entry_pol);
-
+ status =
+ _reg_open_entry(&q_u.pol, &q_u.uni_name, q_u.unknown_0,
+ q_u.access_mask, &entry_pol);
+
make_reg_r_open_entry(&r_u, &entry_pol, status);
/* store the response in the SMB stream */
- return reg_io_r_open_entry("", &r_u, rdata, 0);
+ return reg_io_r_open_entry("", &r_u, rdata, 0);
}
/*******************************************************************
api_reg_info
********************************************************************/
-static BOOL api_reg_info( rpcsrv_struct *p, prs_struct *data,
- prs_struct *rdata )
+static BOOL api_reg_info(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
REG_R_INFO r_u;
REG_Q_INFO q_u;
ZERO_STRUCT(buf);
- /* grab the reg unknown 0x11*/
+ /* grab the reg unknown 0x11 */
if (!reg_io_q_info("", &q_u, data, 0))
{
return False;
make_reg_r_info(&r_u, &type, &buf, status);
/* store the response in the SMB stream */
- return reg_io_r_info("", &r_u, rdata, 0);
+ return reg_io_r_info("", &r_u, rdata, 0);
}
/*******************************************************************
array of \PIPE\reg operations
********************************************************************/
-static const struct api_struct api_reg_cmds[] =
-{
- { "REG_CLOSE" , REG_CLOSE , api_reg_close },
- { "REG_OPEN_ENTRY" , REG_OPEN_ENTRY , api_reg_open_entry },
- { "REG_OPEN" , REG_OPEN_HKLM , api_reg_open },
- { "REG_INFO" , REG_INFO , api_reg_info },
- { NULL, 0 , NULL }
+static const struct api_struct api_reg_cmds[] = {
+ {"REG_CLOSE", REG_CLOSE, api_reg_close},
+ {"REG_OPEN_ENTRY", REG_OPEN_ENTRY, api_reg_open_entry},
+ {"REG_OPEN", REG_OPEN_HKLM, api_reg_open},
+ {"REG_INFO", REG_INFO, api_reg_info},
+ {NULL, 0, NULL}
};
/*******************************************************************
receives a reg pipe and responds.
********************************************************************/
-BOOL api_reg_rpc(rpcsrv_struct *p)
+BOOL api_reg_rpc(rpcsrv_struct * p)
{
return api_rpcTNP(p, "api_reg_rpc", api_reg_cmds);
}
-
/*******************************************************************
api_samr_close_hnd
********************************************************************/
-static BOOL api_samr_close_hnd( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_close_hnd(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_CLOSE_HND q_u;
SAMR_R_CLOSE_HND r_u;
return False;
}
r_u.status = _samr_close(&q_u.pol);
- memcpy(&r_u.pol, &q_u.pol, sizeof(q_u.pol));
+ r_u.pol = q_u.pol;
return samr_io_r_close_hnd("", &r_u, rdata, 0);
}
/*******************************************************************
api_samr_unknown_2d
********************************************************************/
-static BOOL api_samr_unknown_2d( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_unknown_2d(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_UNKNOWN_2D q_u;
SAMR_R_UNKNOWN_2D r_u;
/*******************************************************************
api_samr_open_domain
********************************************************************/
-static BOOL api_samr_open_domain( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_open_domain(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_OPEN_DOMAIN q_u;
SAMR_R_OPEN_DOMAIN r_u;
r_u.status = _samr_open_domain(&q_u.connect_pol, q_u.flags,
- &q_u.dom_sid.sid,
- &r_u.domain_pol);
+ &q_u.dom_sid.sid, &r_u.domain_pol);
return samr_io_r_open_domain("", &r_u, rdata, 0);
}
/*******************************************************************
api_samr_usrdom_pwinfo
********************************************************************/
-static BOOL api_samr_get_usrdom_pwinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_get_usrdom_pwinfo(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_GET_USRDOM_PWINFO q_u;
SAMR_R_GET_USRDOM_PWINFO r_u;
r_u.status = _samr_get_usrdom_pwinfo(&q_u.user_pol,
- &r_u.unknown_0, &r_u.unknown_1,
- &r_u.unknown_2);
+ &r_u.unknown_0, &r_u.unknown_1,
+ &r_u.unknown_2);
return samr_io_r_get_usrdom_pwinfo("", &r_u, rdata, 0);
}
/*******************************************************************
api_samr_query_sec_obj
********************************************************************/
-static BOOL api_samr_query_sec_obj( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_sec_obj(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_QUERY_SEC_OBJ q_u;
SAMR_R_QUERY_SEC_OBJ r_u;
{
return False;
}
- r_u.ptr = 1; /* man, we don't have any choice! NT bombs otherwise! */
+ r_u.ptr = 1; /* man, we don't have any choice! NT bombs otherwise! */
return samr_io_r_query_sec_obj("", &r_u, rdata, 0);
}
/*******************************************************************
api_samr_enum_dom_users
********************************************************************/
-static BOOL api_samr_enum_dom_users( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_enum_dom_users(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_ENUM_DOM_USERS q_e;
SAMR_R_ENUM_DOM_USERS r_e;
r_e.status = _samr_enum_dom_users(&q_e.pol, &q_e.start_idx,
- q_e.acb_mask, q_e.unknown_1, q_e.max_size,
- &r_e.sam, &r_e.uni_acct_name,
- &num_entries);
+ q_e.acb_mask, q_e.unknown_1,
+ q_e.max_size, &r_e.sam,
+ &r_e.uni_acct_name, &num_entries);
make_samr_r_enum_dom_users(&r_e, q_e.start_idx, num_entries);
/*******************************************************************
api_samr_add_groupmem
********************************************************************/
-static BOOL api_samr_add_groupmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_add_groupmem(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_ADD_GROUPMEM q_e;
SAMR_R_ADD_GROUPMEM r_e;
/*******************************************************************
api_samr_del_groupmem
********************************************************************/
-static BOOL api_samr_del_groupmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_del_groupmem(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_DEL_GROUPMEM q_e;
SAMR_R_DEL_GROUPMEM r_e;
/*******************************************************************
api_samr_add_aliasmem
********************************************************************/
-static BOOL api_samr_add_aliasmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_add_aliasmem(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_ADD_ALIASMEM q_e;
SAMR_R_ADD_ALIASMEM r_e;
/*******************************************************************
api_samr_del_aliasmem
********************************************************************/
-static BOOL api_samr_del_aliasmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_del_aliasmem(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_DEL_ALIASMEM q_e;
SAMR_R_DEL_ALIASMEM r_e;
/*******************************************************************
api_samr_enum_domains
********************************************************************/
-static BOOL api_samr_enum_domains( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_enum_domains(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_ENUM_DOMAINS q_e;
SAMR_R_ENUM_DOMAINS r_e;
r_e.status = _samr_enum_domains(&q_e.pol, &q_e.start_idx,
- q_e.max_size,
- &r_e.sam, &r_e.uni_dom_name,
- &num_entries);
+ q_e.max_size,
+ &r_e.sam, &r_e.uni_dom_name,
+ &num_entries);
make_samr_r_enum_domains(&r_e, q_e.start_idx, num_entries);
/*******************************************************************
api_samr_enum_dom_groups
********************************************************************/
-static BOOL api_samr_enum_dom_groups( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_enum_dom_groups(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_ENUM_DOM_GROUPS q_e;
SAMR_R_ENUM_DOM_GROUPS r_e;
r_e.status = _samr_enum_dom_groups(&q_e.pol, &q_e.start_idx,
- q_e.max_size,
- &r_e.sam, &r_e.uni_grp_name,
- &num_entries);
+ q_e.max_size,
+ &r_e.sam, &r_e.uni_grp_name,
+ &num_entries);
make_samr_r_enum_dom_groups(&r_e, q_e.start_idx, num_entries);
/*******************************************************************
api_samr_enum_dom_aliases
********************************************************************/
-static BOOL api_samr_enum_dom_aliases( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_enum_dom_aliases(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_ENUM_DOM_ALIASES q_e;
SAMR_R_ENUM_DOM_ALIASES r_e;
r_e.status = _samr_enum_dom_aliases(&q_e.pol, &q_e.start_idx,
- q_e.max_size,
- &r_e.sam, &r_e.uni_grp_name,
- &num_entries);
+ q_e.max_size,
+ &r_e.sam, &r_e.uni_grp_name,
+ &num_entries);
make_samr_r_enum_dom_aliases(&r_e, q_e.start_idx, num_entries);
/*******************************************************************
api_samr_query_dispinfo
********************************************************************/
-static BOOL api_samr_query_dispinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_dispinfo(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_QUERY_DISPINFO q_e;
SAMR_R_QUERY_DISPINFO r_e;
}
status = _samr_query_dispinfo(&q_e.domain_pol,
- q_e.switch_level,
- q_e.start_idx,
- q_e.max_entries,
- q_e.max_size,
- &data_size,
- &num_entries,
- &ctr);
+ q_e.switch_level,
+ q_e.start_idx,
+ q_e.max_entries,
+ q_e.max_size,
+ &data_size, &num_entries, &ctr);
make_samr_r_query_dispinfo(&r_e, num_entries, data_size,
q_e.switch_level, &ctr, status);
/*******************************************************************
api_samr_delete_dom_user
********************************************************************/
-static BOOL api_samr_delete_dom_user( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_delete_dom_user(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_DELETE_DOM_USER q_u;
SAMR_R_DELETE_DOM_USER r_u;
}
r_u.status = _samr_delete_dom_user(&q_u.user_pol);
- memcpy(&r_u.pol, &q_u.user_pol, sizeof(q_u.user_pol));
+ r_u.pol = q_u.user_pol;
return samr_io_r_delete_dom_user("", &r_u, rdata, 0);
}
/*******************************************************************
api_samr_delete_dom_group
********************************************************************/
-static BOOL api_samr_delete_dom_group( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_delete_dom_group(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_DELETE_DOM_GROUP q_u;
SAMR_R_DELETE_DOM_GROUP r_u;
}
r_u.status = _samr_delete_dom_group(&q_u.group_pol);
- memcpy(&r_u.pol, &q_u.group_pol, sizeof(q_u.group_pol));
+ r_u.pol = q_u.group_pol;
return samr_io_r_delete_dom_group("", &r_u, rdata, 0);
}
/*******************************************************************
api_samr_query_groupmem
********************************************************************/
-static BOOL api_samr_query_groupmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_groupmem(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_QUERY_GROUPMEM q_u;
SAMR_R_QUERY_GROUPMEM r_u;
return False;
}
- status = _samr_query_groupmem(&q_u.group_pol,
- &num_rids, &rid, &attr);
+ status = _samr_query_groupmem(&q_u.group_pol, &num_rids, &rid, &attr);
make_samr_r_query_groupmem(&r_u, num_rids, rid, attr, status);
ret = samr_io_r_query_groupmem("", &r_u, rdata, 0);
samr_free_r_query_groupmem(&r_u);
/*******************************************************************
api_samr_query_groupinfo
********************************************************************/
-static BOOL api_samr_set_groupinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_set_groupinfo(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_SET_GROUPINFO q_e;
SAMR_R_SET_GROUPINFO r_e;
/*******************************************************************
api_samr_query_groupinfo
********************************************************************/
-static BOOL api_samr_query_groupinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_groupinfo(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_QUERY_GROUPINFO q_e;
SAMR_R_QUERY_GROUPINFO r_e;
ZERO_STRUCT(q_e);
ZERO_STRUCT(r_e);
ZERO_STRUCT(ctr);
-
+
if (!samr_io_q_query_groupinfo("", &q_e, data, 0))
{
return False;
/*******************************************************************
api_samr_query_aliasinfo
********************************************************************/
-static BOOL api_samr_query_aliasinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_aliasinfo(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_QUERY_ALIASINFO q_e;
SAMR_R_QUERY_ALIASINFO r_e;
ZERO_STRUCT(q_e);
ZERO_STRUCT(r_e);
ZERO_STRUCT(ctr);
-
+
if (!samr_io_q_query_aliasinfo("", &q_e, data, 0))
{
return False;
/*******************************************************************
api_samr_query_useraliases
********************************************************************/
-static BOOL api_samr_query_useraliases( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_useraliases(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_QUERY_USERALIASES q_u;
SAMR_R_QUERY_USERALIASES r_u;
}
status = _samr_query_useraliases(&q_u.pol, q_u.ptr_sid, q_u.sid,
- &num_rids, &rid);
+ &num_rids, &rid);
samr_free_q_query_useraliases(&q_u);
make_samr_r_query_useraliases(&r_u, num_rids, rid, status);
return samr_io_r_query_useraliases("", &r_u, rdata, 0);
/*******************************************************************
api_samr_delete_dom_alias
********************************************************************/
-static BOOL api_samr_delete_dom_alias( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_delete_dom_alias(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_DELETE_DOM_ALIAS q_u;
SAMR_R_DELETE_DOM_ALIAS r_u;
/*******************************************************************
api_samr_query_aliasmem
********************************************************************/
-static BOOL api_samr_query_aliasmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_aliasmem(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_QUERY_ALIASMEM q_u;
SAMR_R_QUERY_ALIASMEM r_u;
/*******************************************************************
api_samr_lookup_names
********************************************************************/
-static BOOL api_samr_lookup_names( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_lookup_names(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_LOOKUP_NAMES q_u;
SAMR_R_LOOKUP_NAMES r_u;
- uint32 rid [MAX_SAM_ENTRIES];
+ uint32 rid[MAX_SAM_ENTRIES];
uint32 type[MAX_SAM_ENTRIES];
- uint32 num_rids = 0;
+ uint32 num_rids = 0;
uint32 num_types = 0;
- uint32 status = 0;
+ uint32 status = 0;
if (!samr_io_q_lookup_names("", &q_u, data, 0))
{
}
status = _samr_lookup_names(&q_u.pol, q_u.num_names1,
- q_u.flags, q_u.ptr, q_u.uni_name,
- &num_rids, rid, &num_types, type);
+ q_u.flags, q_u.ptr, q_u.uni_name,
+ &num_rids, rid, &num_types, type);
samr_free_q_lookup_names(&q_u);
make_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
return samr_io_r_lookup_names("", &r_u, rdata, 0);
/*******************************************************************
api_samr_chgpasswd_user
********************************************************************/
-static BOOL api_samr_chgpasswd_user( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_chgpasswd_user(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_CHGPASSWD_USER q_u;
SAMR_R_CHGPASSWD_USER r_u;
}
if (q_u.nt_newpass.ptr)
{
- nt_newpass = q_u.nt_newpass.pass;
+ nt_newpass = q_u.nt_newpass.pass;
}
if (q_u.nt_oldhash.ptr)
{
- nt_oldhash = q_u.nt_oldhash.hash;
- }
+ nt_oldhash = q_u.nt_oldhash.hash;
+ }
r_u.status = _samr_chgpasswd_user(&q_u.uni_dest_host,
- &q_u.uni_user_name,
- nt_newpass, nt_oldhash,
- lm_newpass, lm_oldhash);
+ &q_u.uni_user_name,
+ nt_newpass, nt_oldhash,
+ lm_newpass, lm_oldhash);
return samr_io_r_chgpasswd_user("", &r_u, rdata, 0);
}
/*******************************************************************
api_samr_get_dom_pwinfo
********************************************************************/
-static BOOL api_samr_get_dom_pwinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_get_dom_pwinfo(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_GET_DOM_PWINFO q_u;
SAMR_R_GET_DOM_PWINFO r_u;
}
r_u.status = _samr_get_dom_pwinfo(&q_u.uni_srv_name,
- &r_u.unk_0,
- &r_u.unk_1,
- &r_u.unk_2);
+ &r_u.unk_0, &r_u.unk_1, &r_u.unk_2);
return samr_io_r_get_dom_pwinfo("", &r_u, rdata, 0);
}
/*******************************************************************
api_samr_lookup_rids
********************************************************************/
-static BOOL api_samr_lookup_rids( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_lookup_rids(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_LOOKUP_RIDS q_u;
SAMR_R_LOOKUP_RIDS r_u;
}
status = _samr_lookup_rids(&q_u.pol, q_u.num_rids1,
- q_u.flags, q_u.rid,
- &num_names,
- &hdr_names, &uni_names, &types);
+ q_u.flags, q_u.rid,
+ &num_names,
+ &hdr_names, &uni_names, &types);
samr_free_q_lookup_rids(&q_u);
make_samr_r_lookup_rids(&r_u, num_names, hdr_names, uni_names, types);
return samr_io_r_lookup_rids("", &r_u, rdata, 0);
/*******************************************************************
api_samr_open_user
********************************************************************/
-static BOOL api_samr_open_user( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_open_user(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_OPEN_USER q_u;
SAMR_R_OPEN_USER r_u;
}
r_u.status = _samr_open_user(&q_u.domain_pol,
- q_u.access_mask, q_u.user_rid,
- &r_u.user_pol);
+ q_u.access_mask, q_u.user_rid,
+ &r_u.user_pol);
return samr_io_r_open_user("", &r_u, rdata, 0);
}
/*******************************************************************
api_samr_query_userinfo
********************************************************************/
-static BOOL api_samr_query_userinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_userinfo(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_QUERY_USERINFO q_u;
SAMR_R_QUERY_USERINFO r_u;
if (q_u.switch_value == 0x12)
{
- DEBUG(0,("api_samr_query_userinfo: possible password attack (info level 0x12)\n"));
+ DEBUG(0,
+ ("api_samr_query_userinfo: possible password attack (info level 0x12)\n"));
status = NT_STATUS_INVALID_INFO_CLASS;
}
else
{
- status = _samr_query_userinfo(&q_u.pol, q_u.switch_value, &ctr);
+ status =
+ _samr_query_userinfo(&q_u.pol, q_u.switch_value,
+ &ctr);
}
make_samr_r_query_userinfo(&r_u, &ctr, status);
return samr_io_r_query_userinfo("", &r_u, rdata, 0);
/*******************************************************************
api_samr_set_userinfo2
********************************************************************/
-static BOOL api_samr_set_userinfo2( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_set_userinfo2(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_SET_USERINFO2 q_u;
SAMR_R_SET_USERINFO2 r_u;
/*******************************************************************
api_samr_set_userinfo
********************************************************************/
-static BOOL api_samr_set_userinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_set_userinfo(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_SET_USERINFO q_u;
SAMR_R_SET_USERINFO r_u;
/*******************************************************************
api_samr_query_usergroups
********************************************************************/
-static BOOL api_samr_query_usergroups( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_usergroups(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_QUERY_USERGROUPS q_u;
SAMR_R_QUERY_USERGROUPS r_u;
/*******************************************************************
api_samr_create_dom_alias
********************************************************************/
-static BOOL api_samr_create_dom_alias( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_create_dom_alias(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_CREATE_DOM_ALIAS q_u;
SAMR_R_CREATE_DOM_ALIAS r_u;
}
r_u.status = _samr_create_dom_alias(&q_u.dom_pol, &q_u.uni_acct_desc,
- q_u.access_mask,
- &r_u.alias_pol, &r_u.rid);
+ q_u.access_mask,
+ &r_u.alias_pol, &r_u.rid);
return samr_io_r_create_dom_alias("", &r_u, rdata, 0);
}
/*******************************************************************
api_samr_create_dom_group
********************************************************************/
-static BOOL api_samr_create_dom_group( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_create_dom_group(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_CREATE_DOM_GROUP q_u;
SAMR_R_CREATE_DOM_GROUP r_u;
}
r_u.status = _samr_create_dom_group(&q_u.pol,
- &q_u.uni_acct_desc,
- q_u.access_mask,
- &r_u.pol, &r_u.rid);
+ &q_u.uni_acct_desc,
+ q_u.access_mask,
+ &r_u.pol, &r_u.rid);
/* store the response in the SMB stream */
return samr_io_r_create_dom_group("", &r_u, rdata, 0);
/*******************************************************************
api_samr_query_dom_info
********************************************************************/
-static BOOL api_samr_query_dom_info( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_dom_info(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_QUERY_DOMAIN_INFO q_e;
SAMR_R_QUERY_DOMAIN_INFO r_u;
switch_value = q_e.switch_value;
- status = _samr_query_dom_info(&q_e.domain_pol, q_e.switch_value, &ctr);
+ status =
+ _samr_query_dom_info(&q_e.domain_pol, q_e.switch_value, &ctr);
make_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
/* store the response in the SMB stream */
/*******************************************************************
api_samr_create_user
********************************************************************/
-static BOOL api_samr_create_user( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_create_user(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_CREATE_USER q_u;
SAMR_R_CREATE_USER r_u;
}
r_u.status = _samr_create_user(&q_u.domain_pol,
- &q_u.uni_name, q_u.acb_info,
- q_u.access_mask,
- &r_u.user_pol,
- &r_u.unknown_0,
- &r_u.user_rid);
+ &q_u.uni_name, q_u.acb_info,
+ q_u.access_mask,
+ &r_u.user_pol,
+ &r_u.unknown_0, &r_u.user_rid);
return samr_io_r_create_user("", &r_u, rdata, 0);
}
/*******************************************************************
api_samr_connect_anon
********************************************************************/
-static BOOL api_samr_connect_anon( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_connect_anon(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_CONNECT_ANON q_u;
SAMR_R_CONNECT_ANON r_u;
}
r_u.status = _samr_connect_anon(NULL,
- q_u.access_mask,
- &r_u.connect_pol);
+ q_u.access_mask, &r_u.connect_pol);
return samr_io_r_connect_anon("", &r_u, rdata, 0);
}
/*******************************************************************
api_samr_connect
********************************************************************/
-static BOOL api_samr_connect( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_connect(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_CONNECT q_u;
SAMR_R_CONNECT r_u;
}
r_u.status = _samr_connect(&q_u.uni_srv_name,
- q_u.access_mask,
- &r_u.connect_pol);
+ q_u.access_mask, &r_u.connect_pol);
return samr_io_r_connect("", &r_u, rdata, 0);
}
/*******************************************************************
api_samr_open_alias
********************************************************************/
-static BOOL api_samr_open_alias( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-
+static BOOL api_samr_open_alias(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_OPEN_ALIAS q_u;
SAMR_R_OPEN_ALIAS r_u;
}
- r_u.status = _samr_open_alias(&q_u.dom_pol, q_u.unknown_0, q_u.rid_alias, &r_u.pol);
+ r_u.status =
+ _samr_open_alias(&q_u.dom_pol, q_u.unknown_0, q_u.rid_alias,
+ &r_u.pol);
/* store the response in the SMB stream */
return samr_io_r_open_alias("", &r_u, rdata, 0);
/*******************************************************************
api_samr_open_group
********************************************************************/
-static BOOL api_samr_open_group( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-
+static BOOL api_samr_open_group(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_OPEN_GROUP q_u;
SAMR_R_OPEN_GROUP r_u;
}
r_u.status = _samr_open_group(&q_u.domain_pol, q_u.access_mask,
- q_u.rid_group, &r_u.pol);
+ q_u.rid_group, &r_u.pol);
return samr_io_r_open_group("", &r_u, rdata, 0);
}
/*******************************************************************
api_samr_lookup_domain
********************************************************************/
-static BOOL api_samr_lookup_domain( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_lookup_domain(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SAMR_Q_LOOKUP_DOMAIN q_u;
SAMR_R_LOOKUP_DOMAIN r_u;
return False;
}
- status = _samr_lookup_domain(&q_u.connect_pol, &q_u.uni_domain, &dom_sid);
+ status =
+ _samr_lookup_domain(&q_u.connect_pol, &q_u.uni_domain,
+ &dom_sid);
make_samr_r_lookup_domain(&r_u, &dom_sid, status);
/* store the response in the SMB stream */
/*******************************************************************
array of \PIPE\samr operations
********************************************************************/
-static const struct api_struct api_samr_cmds [] =
-{
- { "SAMR_CLOSE_HND" , SAMR_CLOSE_HND , api_samr_close_hnd },
- { "SAMR_CONNECT" , SAMR_CONNECT , api_samr_connect },
- { "SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON , api_samr_connect_anon },
- { "SAMR_ENUM_DOMAINS" , SAMR_ENUM_DOMAINS , api_samr_enum_domains },
- { "SAMR_ENUM_DOM_USERS" , SAMR_ENUM_DOM_USERS , api_samr_enum_dom_users },
- { "SAMR_ENUM_DOM_GROUPS" , SAMR_ENUM_DOM_GROUPS , api_samr_enum_dom_groups },
- { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
- { "SAMR_QUERY_USERALIASES", SAMR_QUERY_USERALIASES, api_samr_query_useraliases},
- { "SAMR_QUERY_ALIASMEM" , SAMR_QUERY_ALIASMEM , api_samr_query_aliasmem },
- { "SAMR_QUERY_GROUPMEM" , SAMR_QUERY_GROUPMEM , api_samr_query_groupmem },
- { "SAMR_ADD_ALIASMEM" , SAMR_ADD_ALIASMEM , api_samr_add_aliasmem },
- { "SAMR_DEL_ALIASMEM" , SAMR_DEL_ALIASMEM , api_samr_del_aliasmem },
- { "SAMR_ADD_GROUPMEM" , SAMR_ADD_GROUPMEM , api_samr_add_groupmem },
- { "SAMR_DEL_GROUPMEM" , SAMR_DEL_GROUPMEM , api_samr_del_groupmem },
- { "SAMR_DELETE_DOM_USER" , SAMR_DELETE_DOM_USER , api_samr_delete_dom_user },
- { "SAMR_DELETE_DOM_GROUP" , SAMR_DELETE_DOM_GROUP , api_samr_delete_dom_group },
- { "SAMR_DELETE_DOM_ALIAS" , SAMR_DELETE_DOM_ALIAS , api_samr_delete_dom_alias },
- { "SAMR_CREATE_DOM_GROUP" , SAMR_CREATE_DOM_GROUP , api_samr_create_dom_group },
- { "SAMR_CREATE_DOM_ALIAS" , SAMR_CREATE_DOM_ALIAS , api_samr_create_dom_alias },
- { "SAMR_LOOKUP_NAMES" , SAMR_LOOKUP_NAMES , api_samr_lookup_names },
- { "SAMR_OPEN_USER" , SAMR_OPEN_USER , api_samr_open_user },
- { "SAMR_QUERY_USERINFO" , SAMR_QUERY_USERINFO , api_samr_query_userinfo },
- { "SAMR_SET_USERINFO" , SAMR_SET_USERINFO , api_samr_set_userinfo },
- { "SAMR_SET_USERINFO2" , SAMR_SET_USERINFO2 , api_samr_set_userinfo2 },
- { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
- { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
- { "SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo },
- { "SAMR_QUERY_DISPINFO3" , SAMR_QUERY_DISPINFO3 , api_samr_query_dispinfo },
- { "SAMR_QUERY_DISPINFO4" , SAMR_QUERY_DISPINFO4 , api_samr_query_dispinfo },
- { "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo },
- { "SAMR_QUERY_GROUPINFO" , SAMR_QUERY_GROUPINFO , api_samr_query_groupinfo },
- { "SAMR_SET_GROUPINFO" , SAMR_SET_GROUPINFO , api_samr_set_groupinfo },
- { "SAMR_CREATE_USER" , SAMR_CREATE_USER , api_samr_create_user },
- { "SAMR_LOOKUP_RIDS" , SAMR_LOOKUP_RIDS , api_samr_lookup_rids },
- { "SAMR_GET_DOM_PWINFO" , SAMR_GET_DOM_PWINFO , api_samr_get_dom_pwinfo },
- { "SAMR_CHGPASSWD_USER" , SAMR_CHGPASSWD_USER , api_samr_chgpasswd_user },
- { "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias },
- { "SAMR_OPEN_GROUP" , SAMR_OPEN_GROUP , api_samr_open_group },
- { "SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain },
- { "SAMR_UNKNOWN_2D" , SAMR_UNKNOWN_2D , api_samr_unknown_2d },
- { "SAMR_LOOKUP_DOMAIN" , SAMR_LOOKUP_DOMAIN , api_samr_lookup_domain },
- { "SAMR_QUERY_SEC_OBJECT" , SAMR_QUERY_SEC_OBJECT , api_samr_query_sec_obj },
- { "SAMR_GET_USRDOM_PWINFO", SAMR_GET_USRDOM_PWINFO, api_samr_get_usrdom_pwinfo},
- { NULL , 0 , NULL }
+static const struct api_struct api_samr_cmds[] = {
+ {"SAMR_CLOSE_HND", SAMR_CLOSE_HND, api_samr_close_hnd},
+ {"SAMR_CONNECT", SAMR_CONNECT, api_samr_connect},
+ {"SAMR_CONNECT_ANON", SAMR_CONNECT_ANON, api_samr_connect_anon},
+ {"SAMR_ENUM_DOMAINS", SAMR_ENUM_DOMAINS, api_samr_enum_domains},
+ {"SAMR_ENUM_DOM_USERS", SAMR_ENUM_DOM_USERS, api_samr_enum_dom_users},
+
+ {"SAMR_ENUM_DOM_GROUPS", SAMR_ENUM_DOM_GROUPS,
+ api_samr_enum_dom_groups},
+ {"SAMR_ENUM_DOM_ALIASES", SAMR_ENUM_DOM_ALIASES,
+ api_samr_enum_dom_aliases},
+ {"SAMR_QUERY_USERALIASES", SAMR_QUERY_USERALIASES,
+ api_samr_query_useraliases},
+ {"SAMR_QUERY_ALIASMEM", SAMR_QUERY_ALIASMEM, api_samr_query_aliasmem},
+ {"SAMR_QUERY_GROUPMEM", SAMR_QUERY_GROUPMEM, api_samr_query_groupmem},
+ {"SAMR_ADD_ALIASMEM", SAMR_ADD_ALIASMEM, api_samr_add_aliasmem},
+ {"SAMR_DEL_ALIASMEM", SAMR_DEL_ALIASMEM, api_samr_del_aliasmem},
+ {"SAMR_ADD_GROUPMEM", SAMR_ADD_GROUPMEM, api_samr_add_groupmem},
+ {"SAMR_DEL_GROUPMEM", SAMR_DEL_GROUPMEM, api_samr_del_groupmem},
+
+ {"SAMR_DELETE_DOM_USER", SAMR_DELETE_DOM_USER,
+ api_samr_delete_dom_user},
+ {"SAMR_DELETE_DOM_GROUP", SAMR_DELETE_DOM_GROUP,
+ api_samr_delete_dom_group},
+ {"SAMR_DELETE_DOM_ALIAS", SAMR_DELETE_DOM_ALIAS,
+ api_samr_delete_dom_alias},
+ {"SAMR_CREATE_DOM_GROUP", SAMR_CREATE_DOM_GROUP,
+ api_samr_create_dom_group},
+ {"SAMR_CREATE_DOM_ALIAS", SAMR_CREATE_DOM_ALIAS,
+ api_samr_create_dom_alias},
+ {"SAMR_LOOKUP_NAMES", SAMR_LOOKUP_NAMES, api_samr_lookup_names},
+ {"SAMR_OPEN_USER", SAMR_OPEN_USER, api_samr_open_user},
+ {"SAMR_QUERY_USERINFO", SAMR_QUERY_USERINFO, api_samr_query_userinfo},
+ {"SAMR_SET_USERINFO", SAMR_SET_USERINFO, api_samr_set_userinfo},
+ {"SAMR_SET_USERINFO2", SAMR_SET_USERINFO2, api_samr_set_userinfo2},
+
+ {"SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO,
+ api_samr_query_dom_info},
+ {"SAMR_QUERY_USERGROUPS", SAMR_QUERY_USERGROUPS,
+ api_samr_query_usergroups},
+ {"SAMR_QUERY_DISPINFO", SAMR_QUERY_DISPINFO, api_samr_query_dispinfo},
+ {"SAMR_QUERY_DISPINFO3", SAMR_QUERY_DISPINFO3, api_samr_query_dispinfo},
+ {"SAMR_QUERY_DISPINFO4", SAMR_QUERY_DISPINFO4, api_samr_query_dispinfo},
+
+ {"SAMR_QUERY_ALIASINFO", SAMR_QUERY_ALIASINFO,
+ api_samr_query_aliasinfo},
+ {"SAMR_QUERY_GROUPINFO", SAMR_QUERY_GROUPINFO,
+ api_samr_query_groupinfo},
+ {"SAMR_SET_GROUPINFO", SAMR_SET_GROUPINFO, api_samr_set_groupinfo},
+ {"SAMR_CREATE_USER", SAMR_CREATE_USER, api_samr_create_user},
+ {"SAMR_LOOKUP_RIDS", SAMR_LOOKUP_RIDS, api_samr_lookup_rids},
+ {"SAMR_GET_DOM_PWINFO", SAMR_GET_DOM_PWINFO, api_samr_get_dom_pwinfo},
+ {"SAMR_CHGPASSWD_USER", SAMR_CHGPASSWD_USER, api_samr_chgpasswd_user},
+ {"SAMR_OPEN_ALIAS", SAMR_OPEN_ALIAS, api_samr_open_alias},
+ {"SAMR_OPEN_GROUP", SAMR_OPEN_GROUP, api_samr_open_group},
+ {"SAMR_OPEN_DOMAIN", SAMR_OPEN_DOMAIN, api_samr_open_domain},
+ {"SAMR_UNKNOWN_2D", SAMR_UNKNOWN_2D, api_samr_unknown_2d},
+ {"SAMR_LOOKUP_DOMAIN", SAMR_LOOKUP_DOMAIN, api_samr_lookup_domain},
+
+ {"SAMR_QUERY_SEC_OBJECT", SAMR_QUERY_SEC_OBJECT,
+ api_samr_query_sec_obj},
+ {"SAMR_GET_USRDOM_PWINFO", SAMR_GET_USRDOM_PWINFO,
+ api_samr_get_usrdom_pwinfo},
+ {NULL, 0, NULL}
};
/*******************************************************************
receives a samr pipe and responds.
********************************************************************/
-BOOL api_samr_rpc(rpcsrv_struct *p)
+BOOL api_samr_rpc(rpcsrv_struct * p)
{
- return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds);
+ return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds);
}
-
/*******************************************************************
********************************************************************/
-static BOOL api_srv_net_srv_get_info(rpcsrv_struct * p, prs_struct * data,
- prs_struct * rdata)
+static BOOL api_srv_net_srv_get_info(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SRV_Q_NET_SRV_GET_INFO q_n;
SRV_R_NET_SRV_GET_INFO r_n;
/*******************************************************************
********************************************************************/
-static BOOL api_srv_net_file_enum(rpcsrv_struct * p, prs_struct * data,
- prs_struct * rdata)
+static BOOL api_srv_net_file_enum(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SRV_Q_NET_FILE_ENUM q_n;
SRV_R_NET_FILE_ENUM r_n;
q_n.preferred_len, &q_n.enum_hnd,
&(r_n.total_entries), q_n.file_level);
- memcpy(&r_n.enum_hnd, &q_n.enum_hnd, sizeof(r_n.enum_hnd));
+ r_n.enum_hnd = q_n.enum_hnd;
/* store the response in the SMB stream */
ret = srv_io_r_net_file_enum("", &r_n, rdata, 0);
/*******************************************************************
********************************************************************/
-static BOOL api_srv_net_conn_enum(rpcsrv_struct * p, prs_struct * data,
- prs_struct * rdata)
+static BOOL api_srv_net_conn_enum(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SRV_Q_NET_CONN_ENUM q_n;
SRV_R_NET_CONN_ENUM r_n;
q_n.preferred_len, &q_n.enum_hnd,
&(r_n.total_entries), q_n.conn_level);
- memcpy(&r_n.enum_hnd, &q_n.enum_hnd, sizeof(r_n.enum_hnd));
+ r_n.enum_hnd = q_n.enum_hnd;
/* store the response in the SMB stream */
return srv_io_r_net_conn_enum("", &r_n, rdata, 0);
/*******************************************************************
********************************************************************/
-static BOOL api_srv_net_sess_enum(rpcsrv_struct * p, prs_struct * data,
- prs_struct * rdata)
+static BOOL api_srv_net_sess_enum(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SRV_Q_NET_SESS_ENUM q_n;
SRV_R_NET_SESS_ENUM r_n;
q_n.preferred_len, &q_n.enum_hnd,
&(r_n.total_entries), q_n.sess_level);
- memcpy(&r_n.enum_hnd, &q_n.enum_hnd, sizeof(r_n.enum_hnd));
+ r_n.enum_hnd = q_n.enum_hnd;
/* store the response in the SMB stream */
return srv_io_r_net_sess_enum("", &r_n, rdata, 0);
/*******************************************************************
********************************************************************/
-static BOOL api_srv_net_share_enum(rpcsrv_struct * p, prs_struct * data,
- prs_struct * rdata)
+static BOOL api_srv_net_share_enum(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SRV_Q_NET_SHARE_ENUM q_n;
SRV_R_NET_SHARE_ENUM r_n;
&(r_n.total_entries),
q_n.share_level);
- memcpy(&r_n.enum_hnd, &q_n.enum_hnd, sizeof(r_n.enum_hnd));
+ r_n.enum_hnd = q_n.enum_hnd;
/* store the response in the SMB stream */
ret = srv_io_r_net_share_enum("", &r_n, rdata, 0);
/*******************************************************************
********************************************************************/
-static BOOL api_srv_net_share_add(rpcsrv_struct * p, prs_struct * data,
- prs_struct * rdata)
+static BOOL api_srv_net_share_add(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SRV_Q_NET_SHARE_ADD q_n;
SRV_R_NET_SHARE_ADD r_n;
/*******************************************************************
********************************************************************/
-static BOOL api_srv_net_share_get_info(rpcsrv_struct * p, prs_struct * data,
- prs_struct * rdata)
+static BOOL api_srv_net_share_get_info(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SRV_Q_NET_SHARE_GET_INFO q_n;
SRV_R_NET_SHARE_GET_INFO r_n;
/*******************************************************************
********************************************************************/
-static BOOL api_srv_net_remote_tod(rpcsrv_struct * p, prs_struct * data,
- prs_struct * rdata)
+static BOOL api_srv_net_remote_tod(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SRV_Q_NET_REMOTE_TOD q_n;
SRV_R_NET_REMOTE_TOD r_n;
/*******************************************************************
api_svc_close
********************************************************************/
-static BOOL api_svc_close( rpcsrv_struct *p, prs_struct *data,
- prs_struct *rdata )
+static BOOL api_svc_close(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SVC_Q_CLOSE q_r;
SVC_R_CLOSE r_u;
return False;
}
- memcpy(&r_u.pol, &q_r.pol, sizeof(POLICY_HND));
+ r_u.pol = q_r.pol;
r_u.status = _svc_close(&r_u.pol);
/* store the response in the SMB stream */
/*******************************************************************
api_svc_open_service
********************************************************************/
-static BOOL api_svc_open_service( rpcsrv_struct *p, prs_struct *data,
- prs_struct *rdata )
+static BOOL api_svc_open_service(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SVC_Q_OPEN_SERVICE q_u;
SVC_R_OPEN_SERVICE r_u;
return False;
}
- r_u.status = _svc_open_service(&q_u.scman_pol,
- &q_u.uni_svc_name,
- q_u.des_access,
- &r_u.pol);
+ r_u.status = _svc_open_service(&q_u.scman_pol,
+ &q_u.uni_svc_name,
+ q_u.des_access, &r_u.pol);
/* store the response in the SMB stream */
return svc_io_r_open_service("", &r_u, rdata, 0);
/*******************************************************************
api_svc_stop_service
********************************************************************/
-static BOOL api_svc_stop_service( rpcsrv_struct *p, prs_struct *data,
- prs_struct *rdata )
+static BOOL api_svc_stop_service(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SVC_Q_STOP_SERVICE q_u;
SVC_R_STOP_SERVICE r_s;
}
r_s.status = _svc_stop_service(&q_u.pol,
- q_u.unknown,
- &r_s.unknown0,
- &r_s.unknown1,
- &r_s.unknown2,
- &r_s.unknown3,
- &r_s.unknown4,
- &r_s.unknown5,
- &r_s.unknown6);
+ q_u.unknown,
+ &r_s.unknown0,
+ &r_s.unknown1,
+ &r_s.unknown2,
+ &r_s.unknown3,
+ &r_s.unknown4,
+ &r_s.unknown5, &r_s.unknown6);
/* store the response in the SMB stream */
return svc_io_r_stop_service("", &r_s, rdata, 0);
/*******************************************************************
api_svc_start_service
********************************************************************/
-static BOOL api_svc_start_service( rpcsrv_struct *p, prs_struct *data,
- prs_struct *rdata )
+static BOOL api_svc_start_service(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SVC_Q_START_SERVICE q_u;
SVC_R_START_SERVICE r_s;
}
r_s.status = _svc_start_service(&q_u.pol,
- q_u.argc,
- q_u.argc2,
- q_u.argv);
+ q_u.argc, q_u.argc2, q_u.argv);
/* store the response in the SMB stream */
return svc_io_r_start_service("", &r_s, rdata, 0);
/*******************************************************************
api_svc_open_sc_man
********************************************************************/
-static BOOL api_svc_open_sc_man( rpcsrv_struct *p, prs_struct *data,
- prs_struct *rdata )
+static BOOL api_svc_open_sc_man(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SVC_Q_OPEN_SC_MAN q_u;
SVC_R_OPEN_SC_MAN r_u;
}
r_u.status = _svc_open_sc_man(&q_u.uni_srv_name,
- &q_u.uni_db_name,
- q_u.des_access,
- &r_u.pol);
+ &q_u.uni_db_name,
+ q_u.des_access, &r_u.pol);
/* store the response in the SMB stream */
return svc_io_r_open_sc_man("", &r_u, rdata, 0);
/*******************************************************************
api_svc_enum_svcs_status
********************************************************************/
-static BOOL api_svc_enum_svcs_status( rpcsrv_struct *p, prs_struct *data,
- prs_struct *rdata )
+static BOOL api_svc_enum_svcs_status(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SVC_Q_ENUM_SVCS_STATUS q_u;
SVC_R_ENUM_SVCS_STATUS r_u;
}
buf_size = q_u.buf_size;
- memcpy(&resume_hnd, &q_u.resume_hnd, sizeof(ENUM_HND));
+ resume_hnd = q_u.resume_hnd;
status = _svc_enum_svcs_status(&q_u.pol,
- q_u.service_type,
- q_u.service_state,
- &buf_size,
- &resume_hnd,
- svcs,
- &more_buf_size,
- &num_svcs);
- make_svc_r_enum_svcs_status(&r_u, svcs, more_buf_size, num_svcs, &resume_hnd, status);
-
+ q_u.service_type,
+ q_u.service_state,
+ &buf_size,
+ &resume_hnd,
+ svcs, &more_buf_size, &num_svcs);
+ make_svc_r_enum_svcs_status(&r_u, svcs, more_buf_size, num_svcs,
+ &resume_hnd, status);
+
/* store the response in the SMB stream */
return svc_io_r_enum_svcs_status("", &r_u, rdata, 0);
}
/*******************************************************************
api_svc_query_disp_name
********************************************************************/
-static BOOL api_svc_query_disp_name( rpcsrv_struct *p, prs_struct *data,
- prs_struct *rdata )
+static BOOL api_svc_query_disp_name(rpcsrv_struct * p, prs_struct *data,
+ prs_struct *rdata)
{
SVC_Q_QUERY_DISP_NAME q_u;
SVC_R_QUERY_DISP_NAME r_u;
}
r_u.status = _svc_query_disp_name(&q_u.scman_pol,
- &q_u.uni_svc_name,
- q_u.buf_size,
- &r_u.uni_disp_name,
- &r_u.buf_size);
+ &q_u.uni_svc_name,
+ q_u.buf_size,
+ &r_u.uni_disp_name, &r_u.buf_size);
/* store the response in the SMB stream */
return svc_io_r_query_disp_name("", &r_u, rdata, 0);
/*******************************************************************
api_svc_unknown_3
********************************************************************/
-static BOOL api_svc_unknown_3(rpcsrv_struct *p, prs_struct *data,
+static BOOL api_svc_unknown_3(rpcsrv_struct * p, prs_struct *data,
prs_struct *rdata)
{
SVC_Q_UNKNOWN_3 q_u;
/*******************************************************************
array of \PIPE\svcctl operations
********************************************************************/
-static const struct api_struct api_svc_cmds[] =
-{
- { "SVC_CLOSE" , SVC_CLOSE , api_svc_close },
- { "SVC_OPEN_SC_MAN" , SVC_OPEN_SC_MAN , api_svc_open_sc_man },
- { "SVC_OPEN_SERVICE" , SVC_OPEN_SERVICE , api_svc_open_service },
- { "SVC_ENUM_SVCS_STATUS", SVC_ENUM_SVCS_STATUS, api_svc_enum_svcs_status },
- { "SVC_QUERY_DISP_NAME" , SVC_QUERY_DISP_NAME , api_svc_query_disp_name },
- { "SVC_START_SERVICE" , SVC_START_SERVICE , api_svc_start_service },
- { "SVC_STOP_SERVICE" , SVC_STOP_SERVICE , api_svc_stop_service },
- { "SVC_UNKNOWN_3" , SVC_UNKNOWN_3 , api_svc_unknown_3 },
- { NULL , 0 , NULL }
+static const struct api_struct api_svc_cmds[] = {
+ {"SVC_CLOSE", SVC_CLOSE, api_svc_close},
+ {"SVC_OPEN_SC_MAN", SVC_OPEN_SC_MAN, api_svc_open_sc_man},
+ {"SVC_OPEN_SERVICE", SVC_OPEN_SERVICE, api_svc_open_service},
+
+ {"SVC_ENUM_SVCS_STATUS", SVC_ENUM_SVCS_STATUS,
+ api_svc_enum_svcs_status},
+ {"SVC_QUERY_DISP_NAME", SVC_QUERY_DISP_NAME, api_svc_query_disp_name},
+ {"SVC_START_SERVICE", SVC_START_SERVICE, api_svc_start_service},
+ {"SVC_STOP_SERVICE", SVC_STOP_SERVICE, api_svc_stop_service},
+ {"SVC_UNKNOWN_3", SVC_UNKNOWN_3, api_svc_unknown_3},
+ {NULL, 0, NULL}
};
/*******************************************************************
receives a svcctl pipe and responds.
********************************************************************/
-BOOL api_svcctl_rpc(rpcsrv_struct *p)
+BOOL api_svcctl_rpc(rpcsrv_struct * p)
{
return api_rpcTNP(p, "api_svc_rpc", api_svc_cmds);
}
-
#if 0
static BOOL tdb_lookup_user_als(TDB_CONTEXT * tdb,
- const DOM_SID * sid,
- uint32 * num_rids, uint32 ** rids)
+ const DOM_SID *sid,
+ uint32 *num_rids, uint32 **rids)
{
prs_struct key;
prs_struct data;
static BOOL tdb_lookup_user_grps(TDB_CONTEXT * tdb,
uint32 rid,
- uint32 * num_gids, DOM_GID ** gids)
+ uint32 *num_gids, DOM_GID ** gids)
{
prs_struct key;
prs_struct data;
}
static BOOL tdb_store_user_als(TDB_CONTEXT * tdb,
- const DOM_SID * sid,
- uint32 num_rids, uint32 * rids)
+ const DOM_SID *sid,
+ uint32 num_rids, uint32 *rids)
{
prs_struct key;
prs_struct data;
return False;
}
- memcpy(usr.lm_pwd, lm_pwd, sizeof(usr.lm_pwd));
- memcpy(usr.nt_pwd, nt_pwd, sizeof(usr.nt_pwd));
+ Memcpy(usr.lm_pwd, lm_pwd, sizeof(usr.lm_pwd));
+ Memcpy(usr.nt_pwd, nt_pwd, sizeof(usr.nt_pwd));
if (!tdb_store_user(tdb, &usr))
{
{
SAM_USER_INFO_21 usr;
BOOL ret;
-
+
UNISTR2 *uni_user_name;
UNISTR2 *uni_full_name;
UNISTR2 *uni_home_dir;
return False;
}
- uni_user_name = choose_unistr2( &usr21->uni_user_name, &usr.uni_user_name);
- uni_full_name = choose_unistr2( &usr21->uni_full_name, &usr.uni_full_name);
- uni_home_dir = choose_unistr2( &usr21->uni_home_dir, &usr.uni_home_dir);
- uni_dir_drive = choose_unistr2( &usr21->uni_dir_drive, &usr.uni_dir_drive);
- uni_logon_script = choose_unistr2( &usr21->uni_logon_script, &usr.uni_logon_script);
- uni_profile_path = choose_unistr2( &usr21->uni_profile_path, &usr.uni_profile_path);
- uni_acct_desc = choose_unistr2( &usr21->uni_acct_desc, &usr.uni_acct_desc);
- uni_workstations = choose_unistr2( &usr21->uni_workstations, &usr.uni_workstations);
- uni_unknown_str = choose_unistr2( &usr21->uni_unknown_str, &usr.uni_unknown_str);
- uni_munged_dial = choose_unistr2( &usr21->uni_munged_dial, &usr.uni_munged_dial);
+ uni_user_name =
+ choose_unistr2(&usr21->uni_user_name, &usr.uni_user_name);
+ uni_full_name =
+ choose_unistr2(&usr21->uni_full_name, &usr.uni_full_name);
+ uni_home_dir =
+ choose_unistr2(&usr21->uni_home_dir, &usr.uni_home_dir);
+ uni_dir_drive =
+ choose_unistr2(&usr21->uni_dir_drive, &usr.uni_dir_drive);
+ uni_logon_script =
+ choose_unistr2(&usr21->uni_logon_script,
+ &usr.uni_logon_script);
+ uni_profile_path =
+ choose_unistr2(&usr21->uni_profile_path,
+ &usr.uni_profile_path);
+ uni_acct_desc =
+ choose_unistr2(&usr21->uni_acct_desc, &usr.uni_acct_desc);
+ uni_workstations =
+ choose_unistr2(&usr21->uni_workstations,
+ &usr.uni_workstations);
+ uni_unknown_str =
+ choose_unistr2(&usr21->uni_unknown_str, &usr.uni_unknown_str);
+ uni_munged_dial =
+ choose_unistr2(&usr21->uni_munged_dial, &usr.uni_munged_dial);
ret = make_sam_user_info21W(&usr,
- &usr21->logon_time,
- &usr21->logoff_time,
- &usr21->kickoff_time,
- &usr21->pass_last_set_time,
- &usr21->pass_can_change_time,
- &usr21->pass_must_change_time,
- uni_user_name,
- uni_full_name,
- uni_home_dir,
- uni_dir_drive,
- uni_logon_script,
- uni_profile_path,
- uni_acct_desc,
- uni_workstations,
- uni_unknown_str,
- uni_munged_dial,
- usr.lm_pwd, usr.nt_pwd,
- usr.user_rid,
- usr21->group_rid,
- usr21->acb_info,
- usr21->unknown_3,
- usr21->logon_divs,
- &usr21->logon_hrs,
- usr21->unknown_5, usr21->unknown_6);
+ &usr21->logon_time,
+ &usr21->logoff_time,
+ &usr21->kickoff_time,
+ &usr21->pass_last_set_time,
+ &usr21->pass_can_change_time,
+ &usr21->pass_must_change_time,
+ uni_user_name,
+ uni_full_name,
+ uni_home_dir,
+ uni_dir_drive,
+ uni_logon_script,
+ uni_profile_path,
+ uni_acct_desc,
+ uni_workstations,
+ uni_unknown_str,
+ uni_munged_dial,
+ usr.lm_pwd, usr.nt_pwd,
+ usr.user_rid,
+ usr21->group_rid,
+ usr21->acb_info,
+ usr21->unknown_3,
+ usr21->logon_divs,
+ &usr21->logon_hrs,
+ usr21->unknown_5, usr21->unknown_6);
unistr2_free(uni_user_name);
unistr2_free(uni_full_name);
{
SAM_USER_INFO_21 usr;
BOOL ret;
-
+
UNISTR2 *uni_user_name;
UNISTR2 *uni_full_name;
UNISTR2 *uni_home_dir;
return False;
}
- uni_user_name = choose_unistr2( &usr23->uni_user_name, &usr.uni_user_name);
- uni_full_name = choose_unistr2( &usr23->uni_full_name, &usr.uni_full_name);
- uni_home_dir = choose_unistr2( &usr23->uni_home_dir, &usr.uni_home_dir);
- uni_dir_drive = choose_unistr2( &usr23->uni_dir_drive, &usr.uni_dir_drive);
- uni_logon_script = choose_unistr2( &usr23->uni_logon_script, &usr.uni_logon_script);
- uni_profile_path = choose_unistr2( &usr23->uni_profile_path, &usr.uni_profile_path);
- uni_acct_desc = choose_unistr2( &usr23->uni_acct_desc, &usr.uni_acct_desc);
- uni_workstations = choose_unistr2( &usr23->uni_workstations, &usr.uni_workstations);
- uni_unknown_str = choose_unistr2( &usr23->uni_unknown_str, &usr.uni_unknown_str);
- uni_munged_dial = choose_unistr2( &usr23->uni_munged_dial, &usr.uni_munged_dial);
+ uni_user_name =
+ choose_unistr2(&usr23->uni_user_name, &usr.uni_user_name);
+ uni_full_name =
+ choose_unistr2(&usr23->uni_full_name, &usr.uni_full_name);
+ uni_home_dir =
+ choose_unistr2(&usr23->uni_home_dir, &usr.uni_home_dir);
+ uni_dir_drive =
+ choose_unistr2(&usr23->uni_dir_drive, &usr.uni_dir_drive);
+ uni_logon_script =
+ choose_unistr2(&usr23->uni_logon_script,
+ &usr.uni_logon_script);
+ uni_profile_path =
+ choose_unistr2(&usr23->uni_profile_path,
+ &usr.uni_profile_path);
+ uni_acct_desc =
+ choose_unistr2(&usr23->uni_acct_desc, &usr.uni_acct_desc);
+ uni_workstations =
+ choose_unistr2(&usr23->uni_workstations,
+ &usr.uni_workstations);
+ uni_unknown_str =
+ choose_unistr2(&usr23->uni_unknown_str, &usr.uni_unknown_str);
+ uni_munged_dial =
+ choose_unistr2(&usr23->uni_munged_dial, &usr.uni_munged_dial);
ret = make_sam_user_info21W(&usr,
- &usr23->logon_time,
- &usr23->logoff_time,
- &usr23->kickoff_time,
- &usr23->pass_last_set_time,
- &usr23->pass_can_change_time,
- &usr23->pass_must_change_time,
- uni_user_name,
- uni_full_name,
- uni_home_dir,
- uni_dir_drive,
- uni_logon_script,
- uni_profile_path,
- uni_acct_desc,
- uni_workstations,
- uni_unknown_str,
- uni_munged_dial,
- lm_pwd, nt_pwd,
- usr.user_rid,
- usr23->group_rid,
- usr23->acb_info,
- usr.unknown_3,
- usr23->logon_divs,
- &usr23->logon_hrs,
- usr23->unknown_5, usr23->unknown_6);
+ &usr23->logon_time,
+ &usr23->logoff_time,
+ &usr23->kickoff_time,
+ &usr23->pass_last_set_time,
+ &usr23->pass_can_change_time,
+ &usr23->pass_must_change_time,
+ uni_user_name,
+ uni_full_name,
+ uni_home_dir,
+ uni_dir_drive,
+ uni_logon_script,
+ uni_profile_path,
+ uni_acct_desc,
+ uni_workstations,
+ uni_unknown_str,
+ uni_munged_dial,
+ lm_pwd, nt_pwd,
+ usr.user_rid,
+ usr23->group_rid,
+ usr23->acb_info,
+ usr.unknown_3,
+ usr23->logon_divs,
+ &usr23->logon_hrs,
+ usr23->unknown_5, usr23->unknown_6);
unistr2_free(uni_user_name);
unistr2_free(uni_full_name);
samr_reply_get_usrdom_pwinfo
********************************************************************/
uint32 _samr_get_usrdom_pwinfo(const POLICY_HND *user_pol,
- uint16 * unknown_0,
- uint16 *unknown_1,
- uint32 * unknown_2)
+ uint16 *unknown_0,
+ uint16 *unknown_1, uint32 *unknown_2)
{
uint32 rid;
TDB_CONTEXT *tdb = NULL;
samr_reply_query_usergroups
********************************************************************/
uint32 _samr_query_usergroups(const POLICY_HND *pol,
- uint32 * num_groups, DOM_GID ** gids)
+ uint32 *num_groups, DOM_GID ** gids)
{
#if 0
uint32 rid;
samr_reply_query_useraliases
********************************************************************/
uint32 _samr_query_useraliases(const POLICY_HND *domain_pol,
- const uint32 * ptr_sid, const DOM_SID2 * sid,
- uint32 * num_aliases, uint32 ** rid)
+ const uint32 *ptr_sid, const DOM_SID2 * sid,
+ uint32 *num_aliases, uint32 **rid)
{
#if 0
TDB_CONTEXT *tdb = NULL;
TDB_CONTEXT *tdb_usr = NULL;
SAM_USER_INFO_21 usr;
- DEBUG(10,("_samr_query_userinfo: %d\n", __LINE__));
+ DEBUG(10, ("_samr_query_userinfo: %d\n", __LINE__));
/* find the policy handle. open a policy on it. */
if (!get_tdbsam(get_global_hnd_cache(), pol, &tdb_usr))
for (i = 0; i < new_pw.uni_str_len; i++)
{
- new_pw.buffer[i] = SVAL(buf, i*2);
+ new_pw.buffer[i] = SVAL(buf, i * 2);
}
nt_lm_owf_genW(&new_pw, nt_hash, lm_hash);
for (i = 0; i < new_pw.uni_str_len; i++)
{
- new_pw.buffer[i] = SVAL(buf, i*2);
+ new_pw.buffer[i] = SVAL(buf, i * 2);
}
nt_lm_owf_genW(&new_pw, nt_hash, lm_hash);
if (!set_user_info_12(tdb_usr, id12))
{
- DEBUG(10, ("_samr_set_userinfo 0x12 failed\n"));
+ DEBUG(10,
+ ("_samr_set_userinfo 0x12 failed\n"));
return NT_STATUS_ACCESS_DENIED;
}
break;
}
static void create_user_info_21(SAM_USER_INFO_21 * usr,
- const UNISTR2 * uni_user_name,
+ const UNISTR2 *uni_user_name,
uint16 acb_info, uint32 user_rid,
uint32 group_rid)
{
_samr_create_user
********************************************************************/
uint32 _samr_create_user(const POLICY_HND *domain_pol,
- const UNISTR2 * uni_username,
+ const UNISTR2 *uni_username,
uint16 acb_info, uint32 access_mask,
POLICY_HND *user_pol,
- uint32 * unknown_0, uint32 * user_rid)
+ uint32 *unknown_0, uint32 *user_rid)
{
DOM_SID dom_sid;
DOM_SID usr_sid;
uint32 *als_rids = NULL;
#endif
+ POSIX_ID id;
+
(*unknown_0) = 0x30;
(*user_rid) = 0x0;
}
sid_to_string(riddb, &dom_sid);
- safe_strcat(riddb, "/dom.tdb", sizeof(riddb)-1);
+ safe_strcat(riddb, "/dom.tdb", sizeof(riddb) - 1);
status1 = _samr_lookup_names(domain_pol, 1, 0x3e8, 1, uni_username,
&num_rids, &rid, &num_types, &type);
for (i = 0; i < n_groups; i++)
{
- if (surs_unixid_to_sam_sid(groups[i],
- SID_NAME_ALIAS,
- &grp_sid, True))
+ id.id = groups[i];
+ id.type = SURS_POSIX_GID_AS_ALS;
+
+ if (surs_unixid_to_sam_sid(&id, &grp_sid, True))
{
uint32 grp_rid = 0xffffffff;
if (!sid_split_rid(&grp_sid, &grp_rid))
num_alss++;
}
}
- if (surs_unixid_to_sam_sid(groups[i],
- SID_NAME_DOM_GRP,
- &grp_sid, True))
+
+ id.id = groups[i];
+ id.type = SURS_POSIX_GID_AS_GRP;
+
+ if (surs_unixid_to_sam_sid(&id, &grp_sid, True))
{
uint32 grp_rid = 0xffffffff;
if (!sid_split_rid(&grp_sid, &grp_rid))
#endif
}
- tdb_dom = tdb_open(passdb_path(riddb),0,0,O_RDWR, 600);
+ tdb_dom = tdb_open(passdb_path(riddb), 0, 0, O_RDWR, 600);
if (tdb_dom == NULL || tdb_writelock(tdb_dom) != 0)
{
tdb_close(tdb_dom);
sid_copy(&sid, &usr_sid);
/* create a User SID for the unix user */
- if (!surs_unixid_to_sam_sid(pass->pw_uid, SID_NAME_USER, &usr_sid,
- True))
+ id.id = pass->pw_uid;
+ id.type = SURS_POSIX_UID_AS_USR;
+
+ if (!surs_unixid_to_sam_sid(&id, &usr_sid, True))
{
DEBUG(0, ("create user: unix uid %d to RID failed\n",
pass->pw_uid));
sid_copy(&sid, &grp_sid);
/* create a Group SID for the unix user */
- if (!surs_unixid_to_sam_sid
- (pass->pw_gid, SID_NAME_DOM_GRP, &grp_sid, True))
+ id.id = pass->pw_gid;
+ id.type = SURS_POSIX_GID_AS_GRP;
+
+ if (!surs_unixid_to_sam_sid(&id, &grp_sid, True))
{
DEBUG(0, ("create user: unix uid %d to RID failed\n",
pass->pw_uid));
gotstart = 1;
}
+ if( $0 ~ /^hash_element/ ) {
+ gotstart = 1;
+ }
+
+ if( $0 ~ /^SMB_STRUCT_DIRENT/ ) {
+ gotstart = 1;
+ }
+
if( $0 ~ /^UNISTR2|^LOCAL_GRP|^DOMAIN_GRP|^DOM_SID|^SEC_DESC/ ) {
gotstart = 1;
}
gotstart = 1;
}
- if( $0 ~ /^TDB_CONTEXT|^TDB_DATA|^smb_ucs2_t/ ) {
+ if( $0 ~ /^TALLOC_CTX|^TDB_CONTEXT|^TDB_DATA|^smb_ucs2_t|^smb_ucs1_t/ ) {
gotstart = 1;
}
Unix SMB/Netbios implementation.
Version 1.9.
Blocking Locking functions
- Copyright (C) Jeremy Allison 1998
+ Copyright (C) Jeremy Allison 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
extern int DEBUGLEVEL;
extern int Client;
-extern int chain_size;
extern char *OutBuffer;
/****************************************************************************
* of smb_lkrng structs.
*/
- for(i = blr->lock_num; i >= 0; i--) {
+ /*
+ * Ensure we don't do a remove on the lock that just failed,
+ * as under POSIX rules, if we have a lock already there, we
+ * will delete it (and we shouldn't) .....
+ */
+
+ for(i = blr->lock_num - 1; i >= 0; i--) {
int dummy1;
uint32 dummy2;
- if(!large_file_format) {
- count = IVAL(data,SMB_LKLEN_OFFSET(i));
- offset = IVAL(data,SMB_LKOFF_OFFSET(i));
- }
-#ifdef LARGE_SMB_OFF_T
- else {
- count = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(i))) << 32) |
- ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(i)));
- offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32) |
- ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(i)));
- }
-#endif /* LARGE_SMB_OFF_T */
+ BOOL err;
+
+ count = get_lock_count( data, i, large_file_format, &err);
+ offset = get_lock_offset( data, i, large_file_format, &err);
+
+ /*
+ * We know err cannot be set as if it was the lock
+ * request would never have been queued. JRA.
+ */
+
do_unlock(fsp,conn,count,offset,&dummy1,&dummy2);
}
numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
data = smb_buf(outbuf) + 3;
- if(!do_lock( fsp, conn, numtoread, startpos, F_RDLCK, &eclass, &ecode)) {
+ if(!do_lock( fsp, conn, numtoread, startpos, READ_LOCK, &eclass, &ecode)) {
if((errno != EACCES) && (errno != EAGAIN)) {
/*
* We have other than a "can't get lock" POSIX
SSVAL(smb_buf(outbuf),1,nread);
DEBUG(3, ( "process_lockread file = %s, fnum=%d num=%d nread=%d\n",
- fsp->fsp_name, fsp->fnum, numtoread, nread ) );
+ fsp->fsp_name, fsp->fnum, (int)numtoread, (int)nread ) );
send_blocking_reply(outbuf,outsize);
return True;
offset = IVAL(inbuf,smb_vwv3);
errno = 0;
- if (!do_lock(fsp, conn, count, offset, F_WRLCK, &eclass, &ecode)) {
+ if (!do_lock(fsp, conn, count, offset, WRITE_LOCK, &eclass, &ecode)) {
if((errno != EACCES) && (errno != EAGAIN)) {
/*
*/
for(; blr->lock_num < num_locks; blr->lock_num++) {
- if(!large_file_format) {
- count = IVAL(data,SMB_LKLEN_OFFSET(blr->lock_num));
- offset = IVAL(data,SMB_LKOFF_OFFSET(blr->lock_num));
- }
-#ifdef LARGE_SMB_OFF_T
- else {
- count = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(blr->lock_num))) << 32) |
- ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(blr->lock_num)));
- offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(blr->lock_num))) << 32) |
- ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(blr->lock_num)));
- }
-#endif /* LARGE_SMB_OFF_T */
+ BOOL err;
+
+ count = get_lock_count( data, blr->lock_num, large_file_format, &err);
+ offset = get_lock_offset( data, blr->lock_num, large_file_format, &err);
+
+ /*
+ * We know err cannot be set as if it was the lock
+ * request would never have been queued. JRA.
+ */
errno = 0;
- if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK),
+ if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK),
&eclass, &ecode))
break;
}
}
}
+/****************************************************************************
+ Return True if the blocking lock queue has entries.
+*****************************************************************************/
+
+BOOL blocking_locks_pending(void)
+{
+ blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue );
+ return (blr == NULL ? False : True);
+}
+
/****************************************************************************
Process the blocking lock queue. Note that this is only called as root.
*****************************************************************************/
extern int DEBUGLEVEL;
#if ALLOW_CHANGE_PASSWORD
-#define MINPASSWDLENGTH 5
-#define BUFSIZE 512
static int findpty(char **slave)
{
int master;
-#ifndef HAVE_GRANTPT
static fstring line;
DIR *dirp;
- struct dirent *dentry;
char *dpname;
-#endif /* !HAVE_GRANTPT */
#if defined(HAVE_GRANTPT)
- if ((master = sys_open("/dev/ptmx", O_RDWR, 0)) >= 1)
+ /* Try to open /dev/ptmx. If that fails, fall through to old method. */
+ if ((master = sys_open("/dev/ptmx", O_RDWR, 0)) >= 0)
{
grantpt(master);
unlockpt(master);
- *slave = ptsname(master);
+ *slave = (char *)ptsname(master);
if (*slave == NULL)
{
DEBUG(0,
return (master);
}
}
-#else /* HAVE_GRANTPT */
+#endif /* HAVE_GRANTPT */
+
fstrcpy(line, "/dev/ptyXX");
dirp = opendir("/dev");
if (!dirp)
return (-1);
- while ((dentry = readdir(dirp)) != NULL)
+ while ((dpname = readdirname(dirp)) != NULL)
{
- dpname = dentry->d_name;
if (strncmp(dpname, "pty", 3) == 0 && strlen(dpname) == 5)
{
DEBUG(3,
}
}
closedir(dirp);
-#endif /* HAVE_GRANTPT */
return (-1);
}
return (True);
}
-static int expect(int master, char *expected, char *buf)
+static int expect(int master, char *issue, char *expected)
{
- int n, m;
+ pstring buffer;
+ int attempts, timeout, nread, len;
+ BOOL match = False;
- n = 0;
- buf[0] = 0;
- while (1)
+ for (attempts = 0; attempts < 2; attempts++)
{
- if (n >= BUFSIZE - 1)
+ if (!strequal(issue, "."))
{
- return False;
+ if (lp_passwd_chat_debug())
+ DEBUG(100, ("expect: sending [%s]\n", issue));
+
+ write(master, issue, strlen(issue));
}
- /* allow 4 seconds for some output to appear */
- m =
- read_with_timeout(master, buf + n, 1, BUFSIZE - 1 - n,
- 4000);
- if (m < 0)
- return False;
+ if (strequal(expected, "."))
+ return True;
- n += m;
- buf[n] = 0;
+ timeout = 2000;
+ nread = 0;
+ buffer[nread] = 0;
+ while ((len = read_with_timeout(master, buffer + nread, 1,
+ sizeof(buffer) - nread - 1,
+ timeout)) > 0)
{
- pstring s1, s2;
- pstrcpy(s1, buf);
- pstrcpy(s2, expected);
- if (do_match(s1, s2, False))
- return (True);
+ nread += len;
+ buffer[nread] = 0;
+
+ if ((match = unix_do_match(buffer, expected, False)))
+ timeout = 200;
}
+
+ if (lp_passwd_chat_debug())
+ DEBUG(100, ("expect: expected [%s] received [%s]\n",
+ expected, buffer));
+
+ if (match)
+ break;
+
+ if (len < 0)
+ {
+ DEBUG(2, ("expect: %s\n", strerror(errno)));
+ return False;
}
}
-static void pwd_sub(char *buf)
-{
- string_sub(buf, "\\n", "\n");
- string_sub(buf, "\\r", "\r");
- string_sub(buf, "\\s", " ");
- string_sub(buf, "\\t", "\t");
+ return match;
}
-static void writestring(int fd, char *s)
+static void pwd_sub(char *buf)
{
- int l;
-
- l = strlen(s);
- write(fd, s, l);
+ all_string_sub(buf, "\\n", "\n", 0);
+ all_string_sub(buf, "\\r", "\r", 0);
+ all_string_sub(buf, "\\s", " ", 0);
+ all_string_sub(buf, "\\t", "\t", 0);
}
-
-static int talktochild(int master, char *chatsequence)
+static int talktochild(int master, char *seq)
{
- char buf[BUFSIZE];
int count = 0;
- char *ptr = chatsequence;
- fstring chatbuf;
+ fstring issue, expected;
- *buf = 0;
- sleep(1);
+ fstrcpy(issue, ".");
- while (next_token(&ptr, chatbuf, NULL, sizeof(chatbuf)))
+ while (next_token(&seq, expected, NULL, sizeof(expected)))
{
- BOOL ok = True;
+ pwd_sub(expected);
count++;
- pwd_sub(chatbuf);
- if (!strequal(chatbuf, "."))
- ok = expect(master, chatbuf, buf);
-
- if (lp_passwd_chat_debug())
- DEBUG(100,
- ("talktochild: chatbuf=[%s] responsebuf=[%s]\n",
- chatbuf, buf));
- if (!ok)
+ if (!expect(master, issue, expected))
{
- DEBUG(3, ("response %d incorrect\n", count));
- return (False);
+ DEBUG(3, ("Response %d incorrect\n", count));
+ return False;
}
- if (!next_token(&ptr, chatbuf, NULL, sizeof(chatbuf)))
- break;
- pwd_sub(chatbuf);
- if (!strequal(chatbuf, "."))
- writestring(master, chatbuf);
+ if (!next_token(&seq, issue, NULL, sizeof(issue)))
+ fstrcpy(issue, ".");
- if (lp_passwd_chat_debug())
- DEBUG(100, ("talktochild: sendbuf=[%s]\n", chatbuf));
+ pwd_sub(issue);
}
- if (count < 1)
- return (False);
-
- return (True);
+ return (count > 0);
}
return (False);
}
+ /*
+ * We need to temporarily stop CatchChild from eating
+ * SIGCLD signals as it also eats the exit status code. JRA.
+ */
+
+ CatchChildLeaveStatus();
+
if ((pid = fork()) < 0)
{
DEBUG(3,
("Cannot fork() child for password change: %s\n",
name));
close(master);
+ CatchChild();
return (False);
}
kill(pid, SIGKILL); /* be sure to end this process */
}
- if ((wpid = sys_waitpid(pid, &wstat, 0)) < 0)
+ while ((wpid = sys_waitpid(pid, &wstat, 0)) < 0)
+ {
+ if (errno == EINTR)
+ {
+ errno = 0;
+ continue;
+ }
+ break;
+ }
+
+ if (wpid < 0)
{
DEBUG(3, ("The process is no longer waiting!\n\n"));
close(master);
+ CatchChild();
return (False);
}
+ /*
+ * Go back to ignoring children.
+ */
+ CatchChild();
+
close(master);
if (pid != wpid)
dochild(master, slavedev, name, passwordprogram,
as_root);
- if (as_root)
- unbecome_root(False);
+ /*
+ * The child should never return from dochild() ....
+ */
+
+ DEBUG(0,
+ ("chat_with_program: Error: dochild() returned %d\n",
+ chstat));
+ exit(1);
}
if (chstat)
{
pstring passwordprogram;
pstring chatsequence;
- int i;
- int len;
+ size_t i, len;
fstring name;
fstrcpy(name, _name);
/* Take the passed information and test it for minimum criteria */
/* Minimum password length */
- if (strlen(newpass) < MINPASSWDLENGTH) /* too short, must be at least MINPASSWDLENGTH */
+ if (strlen(newpass) < lp_min_passwd_length()) /* too short, must be at least MINPASSWDLENGTH */
{
- DEBUG(2,
- ("Password Change: %s, New password is shorter than MINPASSWDLENGTH\n",
- name));
+ DEBUG(0,
+ ("Password Change: user %s, New password is shorter than minimum password length = %d\n",
+ name, lp_min_passwd_length()));
return (False); /* inform the user */
}
}
}
- string_sub(passwordprogram, "%u", name);
- all_string_sub(passwordprogram, "%o", oldpass, 0);
- all_string_sub(passwordprogram, "%n", newpass, 0);
+ pstring_sub(passwordprogram, "%u", name);
+ /* note that we do NOT substitute the %o and %n in the password program
+ as this would open up a security hole where the user could use
+ a new password containing shell escape characters */
- string_sub(chatsequence, "%u", name);
+ pstring_sub(chatsequence, "%u", name);
all_string_sub(chatsequence, "%o", oldpass, sizeof(pstring));
all_string_sub(chatsequence, "%n", newpass, sizeof(pstring));
return (chat_with_program
BOOL nt_pass_set = (_ntdata != NULL && nthash != NULL);
- if (_lmdata != NULL)
- {
- memcpy(lmdata, _lmdata, sizeof(lmdata));
- }
-
- if (_ntdata != NULL)
- {
- memcpy(ntdata, _ntdata, sizeof(ntdata));
- }
+ Memcpy(lmdata, _lmdata, sizeof(lmdata));
+ Memcpy(ntdata, _ntdata, sizeof(ntdata));
become_root(False);
(*psmbpw) = smbpw = getsmbpwnam(user);
extern int DEBUGLEVEL;
-extern int32 global_oplocks_open;
-
-
/****************************************************************************
run a file if it is a magic script
****************************************************************************/
{
connection_struct *conn = fsp->conn;
+ flush_write_cache(fsp, CLOSE_FLUSH);
+
fsp->open = False;
fsp->is_directory = False;
free((char *)fsp->wbmpx_ptr);
fsp->wbmpx_ptr = NULL;
}
-
-#if WITH_MMAP
- if(fsp->mmap_ptr) {
- munmap(fsp->mmap_ptr,fsp->mmap_size);
- fsp->mmap_ptr = NULL;
- }
-#endif
}
/****************************************************************************
the closing of the connection. In the latter case printing and
magic scripts are not run.
****************************************************************************/
-void close_file(files_struct *fsp, BOOL normal_close)
+
+static int close_normal_file(files_struct *fsp, BOOL normal_close)
{
SMB_DEV_T dev = fsp->fd_ptr->dev;
SMB_INO_T inode = fsp->fd_ptr->inode;
- BOOL last_reference = False;
- BOOL delete_on_close = fsp->fd_ptr->delete_on_close;
+ BOOL last_reference = False;
+ BOOL delete_on_close = fsp->fd_ptr->delete_on_close;
connection_struct *conn = fsp->conn;
+ int err = 0;
remove_pending_lock_requests_by_fid(fsp);
del_share_mode(fsp);
}
- if(fd_attempt_close(fsp) == 0)
+ if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+ release_file_oplock(fsp);
+
+ locking_close_file(fsp);
+
+ if(fd_attempt_close(fsp, &err) == 0)
last_reference = True;
- fsp->fd_ptr = NULL;
+ fsp->fd_ptr = NULL;
if (lp_share_modes(SNUM(conn)))
unlock_share_entry(conn, dev, inode);
}
}
- if(fsp->granted_oplock == True)
- global_oplocks_open--;
-
- fsp->sent_oplock_break = False;
-
- DEBUG(2,("%s closed file %s (numopen=%d)\n",
+ DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
conn->user,fsp->fsp_name,
- conn->num_files_open));
+ conn->num_files_open, err ? strerror(err) : ""));
if (fsp->fsp_name) {
string_free(&fsp->fsp_name);
}
file_free(fsp);
+
+ return err;
}
/****************************************************************************
Close a directory opened by an NT SMB call.
****************************************************************************/
-void close_directory(files_struct *fsp)
+static int close_directory(files_struct *fsp, BOOL normal_close)
{
remove_pending_change_notify_requests_by_fid(fsp);
+ /*
+ * NT can set delete_on_close of the last open
+ * reference to a directory also.
+ */
+
+ if (normal_close && fsp->directory_delete_on_close) {
+ BOOL ok = rmdir_internals(fsp->conn, fsp->fsp_name);
+ DEBUG(5,("close_directory: %s. Delete on close was set - deleting directory %s.\n",
+ fsp->fsp_name, ok ? "succeeded" : "failed" ));
+
+ /*
+ * Ensure we remove any change notify requests that would
+ * now fail as the directory has been deleted.
+ */
+
+ if(ok)
+ remove_pending_change_notify_requests_by_filename(fsp);
+ }
+
/*
* Do the code common to files and directories.
*/
string_free(&fsp->fsp_name);
file_free(fsp);
+
+ return 0;
+}
+
+/****************************************************************************
+ Close a file opened with null permissions in order to read permissions.
+****************************************************************************/
+
+static int close_statfile(files_struct *fsp, BOOL normal_close)
+{
+ close_filestruct(fsp);
+
+ if (fsp->fsp_name)
+ string_free(&fsp->fsp_name);
+
+ file_free(fsp);
+
+ return 0;
}
+/****************************************************************************
+ Close a directory opened by an NT SMB call.
+****************************************************************************/
+
+int close_file(files_struct *fsp, BOOL normal_close)
+{
+ if(fsp->is_directory)
+ return close_directory(fsp, normal_close);
+ else if(fsp->stat_open)
+ return close_statfile(fsp, normal_close);
+ return close_normal_file(fsp, normal_close);
+}
ZERO_STRUCTP(conn);
conn->cnum = i;
- conn->smbd_pid = getpid();
bitmap_set(bmap, i);
num_open++;
- string_init(&conn->user,"");
- string_init(&conn->dirpath,"");
- string_init(&conn->connectpath,"");
- string_init(&conn->origpath,"");
+ string_set(&conn->user,"");
+ string_set(&conn->dirpath,"");
+ string_set(&conn->connectpath,"");
+ string_set(&conn->origpath,"");
DLIST_ADD(Connections, conn);
extern int DEBUGLEVEL;
+#ifdef WITH_UTMP
+static void utmp_yield(pid_t pid, const connection_struct *conn);
+static void utmp_claim(const struct connections_data *crec, const connection_struct *conn);
+#endif
+
/****************************************************************************
delete a connection record
****************************************************************************/
kbuf.dsize = sizeof(key);
tdb_delete(tdb, kbuf);
+
+#ifdef WITH_UTMP
+ if(conn)
+ utmp_yield(key.pid, conn);
+#endif
+
return(True);
}
if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) return False;
+#ifdef WITH_UTMP
+ if (conn)
+ utmp_claim(&crec, conn);
+#endif
+
return True;
}
+
+#ifdef WITH_UTMP
+
+/****************************************************************************
+Reflect connection status in utmp/wtmp files.
+ T.D.Lee@durham.ac.uk September 1999
+
+Hints for porting:
+ o Always attempt to use programmatic interface (pututline() etc.)
+ o The "x" (utmpx/wtmpx; HAVE_UTMPX_H) seems preferable.
+
+OS status:
+ Solaris 2.x: Tested on 2.6 and 2.7; should be OK on other flavours.
+ T.D.Lee@durham.ac.uk
+ HPUX 9.x: Not tested. Appears not to have "x".
+ IRIX 6.5: Not tested. Appears to have "x".
+
+Notes:
+ The 4 byte 'ut_id' component is vital to distinguish connections,
+ of which there could be several hundered or even thousand.
+ Entries seem to be printable characters, with optional NULL pads.
+
+ We need to be distinct from other entries in utmp/wtmp.
+
+ Observed things: therefore avoid them. Add to this list please.
+ From Solaris 2.x (because that's what I have):
+ 'sN' : run-levels; N: [0-9]
+ 'co' : console
+ 'CC' : arbitrary things; C: [a-z]
+ 'rXNN' : rlogin; N: [0-9]; X: [0-9a-z]
+ 'tXNN' : rlogin; N: [0-9]; X: [0-9a-z]
+ '/NNN' : Solaris CDE
+ 'ftpZ' : ftp (Z is the number 255, aka 0377, aka 0xff)
+ Mostly a record uses the same 'ut_id' in both "utmp" and "wtmp",
+ but differences have been seen.
+
+ Arbitrarily I have chosen to use a distinctive 'SM' for the
+ first two bytes.
+
+ The remaining two encode the connection number used in samba locking
+ functions "claim_connection() and "yield_connection()". This seems
+ to be a "nicely behaved" number: starting from 0 then working up
+ looking for an available slot.
+
+****************************************************************************/
+
+#include <utmp.h>
+
+#ifdef HAVE_UTMPX_H
+#include <utmpx.h>
+#endif
+
+static const char *ut_id_encstr =
+ "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+static
+int
+ut_id_encode(int i, char *fourbyte)
+{
+ int nbase;
+
+ fourbyte[0] = 'S';
+ fourbyte[1] = 'M';
+
+/*
+ * Encode remaining 2 bytes from 'i'.
+ * 'ut_id_encstr' is the character set on which modulo arithmetic is done.
+ * Example: digits would produce the base-10 numbers from '001'.
+ */
+ nbase = strlen(ut_id_encstr);
+
+ fourbyte[3] = ut_id_encstr[i % nbase];
+ i /= nbase;
+ fourbyte[2] = ut_id_encstr[i % nbase];
+ i /= nbase;
+
+ return(i); /* 0: good; else overflow */
+}
+
+static int utmp_fill(struct utmp *u, const connection_struct *conn, pid_t pid, int i)
+{
+ struct timeval timeval;
+ int rc;
+
+ pstrcpy(u->ut_user, conn->user);
+ rc = ut_id_encode(i, u->ut_id);
+ slprintf(u->ut_line, 12, "smb/%d", i);
+
+ u->ut_pid = pid;
+
+ gettimeofday(&timeval, NULL);
+ u->ut_time = timeval.tv_sec;
+
+ return(rc);
+}
+
+/* Default path (if possible) */
+#ifdef HAVE_UTMPX_H
+
+# ifdef UTMPX_FILE
+static char *ut_pathname = UTMPX_FILE;
+# else
+static char *ut_pathname = "";
+# endif
+# ifdef WTMPX_FILE
+static char *wt_pathname = WTMPX_FILE;
+# else
+static char *wt_pathname = "";
+# endif
+
+#else /* HAVE_UTMPX_H */
+
+# ifdef UTMP_FILE
+static char *ut_pathname = UTMP_FILE;
+# else
+static char *ut_pathname = "";
+# endif
+# ifdef WTMP_FILE
+static char *wt_pathname = WTMP_FILE;
+# else
+static char *wt_pathname = "";
+# endif
+
+#endif /* HAVE_UTMPX_H */
+
+static void uw_pathname(pstring fname, const char *uw_name)
+{
+ pstring dirname;
+
+ pstrcpy(dirname,lp_utmpdir());
+ trim_string(dirname,"","/");
+
+ /* Given directory: use it */
+ if (dirname != 0 && strlen(dirname) != 0) {
+ pstrcpy(fname, dirname);
+ pstrcat(fname, "/");
+ pstrcat(fname, uw_name);
+ return;
+ }
+
+ /* No given directory: attempt to use default paths */
+ if (uw_name[0] == 'u') {
+ pstrcpy(fname, ut_pathname);
+ return;
+ }
+
+ if (uw_name[0] == 'w') {
+ pstrcpy(fname, wt_pathname);
+ return;
+ }
+
+ pstrcpy(fname, "");
+}
+
+static void utmp_update(const struct utmp *u, const char *host)
+{
+ pstring fname;
+
+#ifdef HAVE_UTMPX_H
+ struct utmpx ux, *uxrc;
+
+ getutmpx(u, &ux);
+ if (host) {
+#if defined(HAVE_UX_UT_SYSLEN)
+ ux.ut_syslen = strlen(host);
+#endif /* defined(HAVE_UX_UT_SYSLEN) */
+ pstrcpy(ux.ut_host, host);
+ }
+
+ uw_pathname(fname, "utmpx");
+ DEBUG(2,("utmp_update: fname:%s\n", fname));
+ if (strlen(fname) != 0) {
+ utmpxname(fname);
+ }
+ uxrc = pututxline(&ux);
+ if (uxrc == NULL) {
+ DEBUG(2,("utmp_update: pututxline() failed\n"));
+ return;
+ }
+
+ uw_pathname(fname, "wtmpx");
+ DEBUG(2,("utmp_update: fname:%s\n", fname));
+ if (strlen(fname) != 0) {
+ updwtmpx(fname, &ux);
+ }
+#else
+ uw_pathname(fname, "utmp");
+ DEBUG(2,("utmp_update: fname:%s\n", fname));
+ if (strlen(fname) != 0) {
+ utmpname(fname);
+ }
+ pututline(u);
+
+ uw_pathname(fname, "wtmp");
+
+ /* *** Hmmm. Appending wtmp (as distinct from overwriting utmp) has
+ me baffled. How is it to be done? *** */
+#endif
+}
+
+static void utmp_yield(pid_t pid, const connection_struct *conn)
+{
+ struct utmp u;
+
+ if (! lp_utmp(SNUM(conn))) {
+ DEBUG(2,("utmp_yield: lp_utmp() NULL\n"));
+ return;
+ }
+
+ DEBUG(2,("utmp_yield: conn: user:%s cnum:%d i:%d\n",
+ conn->user, conn->cnum, i));
+
+ memset((char *)&u, '\0', sizeof(struct utmp));
+ u.ut_type = DEAD_PROCESS;
+ u.ut_exit.e_termination = 0;
+ u.ut_exit.e_exit = 0;
+ if (utmp_fill(&u, conn, pid, conn->cnum) == 0) {
+ utmp_update(&u, NULL);
+ }
+}
+
+static void utmp_claim(const struct connect_record *crec, const connection_struct *conn)
+{
+ struct utmp u;
+
+ if (conn == NULL) {
+ DEBUG(2,("utmp_claim: conn NULL\n"));
+ return;
+ }
+
+ if (! lp_utmp(SNUM(conn))) {
+ DEBUG(2,("utmp_claim: lp_utmp() NULL\n"));
+ return;
+ }
+
+ DEBUG(2,("utmp_claim: conn: user:%s cnum:%d i:%d\n",
+ conn->user, conn->cnum, i));
+ DEBUG(2,("utmp_claim: crec: pid:%d, cnum:%d name:%s addr:%s mach:%s DNS:%s\n",
+ crec->pid, crec->cnum, crec->name, crec->addr, crec->machine, client_connection_name()));
+
+
+ memset((char *)&u, '\0', sizeof(struct utmp));
+ u.ut_type = USER_PROCESS;
+ if (utmp_fill(&u, conn, crec->pid, conn->cnum) == 0) {
+ utmp_update(&u, crec->machine);
+ }
+}
+
+#endif
/****************************************************************************
normalise for DOS usage
****************************************************************************/
-static void disk_norm(SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
+static void disk_norm(BOOL small_query, SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
{
/* check if the disk is beyond the max disk size */
SMB_BIG_UINT maxdisksize = lp_maxdisksize();
/* the -1 should stop applications getting div by 0
errors */
}
-
+
while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512) {
*dfree /= 2;
*dsize /= 2;
*bsize *= 2;
- if (*bsize > WORDMAX) {
- *bsize = WORDMAX;
- if (*dsize > WORDMAX)
- *dsize = WORDMAX;
- if (*dfree > WORDMAX)
- *dfree = WORDMAX;
- break;
+ if(small_query) {
+ /*
+ * Force max to fit in 16 bit fields.
+ */
+ if (*bsize > (WORDMAX*512)) {
+ *bsize = (WORDMAX*512);
+ if (*dsize > WORDMAX)
+ *dsize = WORDMAX;
+ if (*dfree > WORDMAX)
+ *dfree = WORDMAX;
+ break;
+ }
}
}
}
#endif /* STAT_STATFS4 */
-#ifdef STAT_STATVFS /* SVR4 */
+#if defined(STAT_STATVFS) || defined(STAT_STATVFS64) /* SVR4 */
# define CONVERT_BLOCKS(B) \
adjust_blocks ((SMB_BIG_UINT)(B), fsd.f_frsize ? (SMB_BIG_UINT)fsd.f_frsize : (SMB_BIG_UINT)fsd.f_bsize, (SMB_BIG_UINT)512)
/****************************************************************************
return number of 1K blocks available on a path and total number
****************************************************************************/
-static SMB_BIG_UINT disk_free(char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
+
+static SMB_BIG_UINT disk_free(char *path, BOOL small_query,
+ SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
{
int dfree_retval;
SMB_BIG_UINT dfree_q = 0;
SMB_BIG_UINT bsize_q = 0;
SMB_BIG_UINT dsize_q = 0;
+ char *dfree_command;
(*dfree) = (*dsize) = 0;
(*bsize) = 512;
- fsusage(path, dfree, dsize);
+
+ /*
+ * If external disk calculation specified, use it.
+ */
+
+ dfree_command = lp_dfree_command();
+ if (dfree_command && *dfree_command) {
+ pstring line;
+ char *p;
+ FILE *pp;
+
+ slprintf (line, sizeof(pstring) - 1, "%s %s", dfree_command, path);
+ DEBUG (3, ("disk_free: Running command %s\n", line));
+
+ pp = sys_popen(line, "r", False);
+ if (pp) {
+ fgets(line, sizeof(pstring), pp);
+ line[sizeof(pstring)-1] = '\0';
+ if (strlen(line) > 0)
+ line[strlen(line)-1] = '\0';
+
+ DEBUG (3, ("Read input from dfree, \"%s\"\n", line));
+
+ *dsize = (SMB_BIG_UINT)strtoul(line, &p, 10);
+ while (p && *p & isspace(*p))
+ p++;
+ if (p && *p)
+ *dfree = (SMB_BIG_UINT)strtoul(p, &p, 10);
+ while (p && *p & isspace(*p))
+ p++;
+ if (p && *p)
+ *bsize = (SMB_BIG_UINT)strtoul(p, NULL, 10);
+ else
+ *bsize = 1024;
+ sys_pclose (pp);
+ DEBUG (3, ("Parsed output of dfree, dsize=%u, dfree=%u, bsize=%u\n",
+ (unsigned int)*dsize, (unsigned int)*dfree, (unsigned int)*bsize));
+
+ if (!*dsize)
+ *dsize = 2048;
+ if (!*dfree)
+ *dfree = 1024;
+ } else {
+ DEBUG (0, ("disk_free: sys_popen() failed for command %s. Error was : %s\n",
+ line, strerror(errno) ));
+ fsusage(path, dfree, dsize);
+ }
+ } else
+ fsusage(path, dfree, dsize);
if (disk_quotas(path, &bsize_q, &dfree_q, &dsize_q)) {
(*bsize) = bsize_q;
*dfree = MAX(1,*dfree);
}
- disk_norm(bsize,dfree,dsize);
+ disk_norm(small_query,bsize,dfree,dsize);
if ((*bsize) < 1024) {
dfree_retval = (*dfree)/(1024/(*bsize));
/****************************************************************************
wrap it to get filenames right
****************************************************************************/
-SMB_BIG_UINT sys_disk_free(char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
+SMB_BIG_UINT sys_disk_free(char *path, BOOL small_query,
+ SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
{
- return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize));
+ return(disk_free(dos_to_unix(path,False),small_query, bsize,dfree,dsize));
}
This module implements directory related functions for Samba.
*/
-
-
-static uint32 dircounter = 0;
-
-
-#define NUMDIRPTRS 256
-
-
-static struct dptr_struct {
- int pid;
+typedef struct _dptr_struct {
+ struct _dptr_struct *next, *prev;
+ int dnum;
+ uint16 spid;
connection_struct *conn;
- uint32 lastused;
void *ptr;
- BOOL valid;
- BOOL finished;
BOOL expect_close;
char *wcard; /* Field only used for trans2_ searches */
uint16 attr; /* Field only used for trans2_ searches */
char *path;
-}
-dirptrs[NUMDIRPTRS];
+} dptr_struct;
+static struct bitmap *dptr_bmap;
+static dptr_struct *dirptrs;
static int dptrs_open = 0;
+#define INVALID_DPTR_KEY (-3)
+
/****************************************************************************
-initialise the dir array
+ Initialise the dir bitmap.
****************************************************************************/
+
void init_dptrs(void)
{
static BOOL dptrs_init=False;
- int i;
- if (dptrs_init) return;
- for (i=0;i<NUMDIRPTRS;i++)
- {
- dirptrs[i].valid = False;
- dirptrs[i].wcard = NULL;
- dirptrs[i].ptr = NULL;
- string_init(&dirptrs[i].path,"");
- }
+ if (dptrs_init)
+ return;
+
+ dptr_bmap = bitmap_allocate(MAX_DIRECTORY_HANDLES);
+
+ if (!dptr_bmap)
+ exit_server("out of memory in init_dptrs\n");
+
dptrs_init = True;
}
/****************************************************************************
-idle a dptr - the directory is closed but the control info is kept
+ Idle a dptr - the directory is closed but the control info is kept.
****************************************************************************/
-static void dptr_idle(int key)
+
+static void dptr_idle(dptr_struct *dptr)
{
- if (dirptrs[key].valid && dirptrs[key].ptr) {
- DEBUG(4,("Idling dptr key %d\n",key));
+ if (dptr->ptr) {
+ DEBUG(4,("Idling dptr dnum %d\n",dptr->dnum));
dptrs_open--;
- CloseDir(dirptrs[key].ptr);
- dirptrs[key].ptr = NULL;
- }
+ CloseDir(dptr->ptr);
+ dptr->ptr = NULL;
+ }
}
/****************************************************************************
-idle the oldest dptr
+ Idle the oldest dptr.
****************************************************************************/
+
static void dptr_idleoldest(void)
{
- int i;
- uint32 old=dircounter+1;
- int oldi= -1;
- for (i=0;i<NUMDIRPTRS;i++)
- if (dirptrs[i].valid && dirptrs[i].ptr && dirptrs[i].lastused < old) {
- old = dirptrs[i].lastused;
- oldi = i;
+ dptr_struct *dptr;
+
+ /*
+ * Go to the end of the list.
+ */
+ for(dptr = dirptrs; dptr && dptr->next; dptr = dptr->next)
+ ;
+
+ if(!dptr) {
+ DEBUG(0,("No dptrs available to idle ?\n"));
+ return;
+ }
+
+ /*
+ * Idle the oldest pointer.
+ */
+
+ for(; dptr; dptr = dptr->prev) {
+ if (dptr->ptr) {
+ dptr_idle(dptr);
+ return;
}
- if (oldi != -1)
- dptr_idle(oldi);
- else
- DEBUG(0,("No dptrs available to idle??\n"));
+ }
}
/****************************************************************************
-get the dir ptr for a dir index
+ Get the dptr_struct for a dir index.
****************************************************************************/
-static void *dptr_get(int key,uint32 lastused)
-{
- struct dptr_struct *dp = &dirptrs[key];
-
- if (dp->valid) {
- if (lastused) dp->lastused = lastused;
- if (!dp->ptr) {
- if (dptrs_open >= MAX_OPEN_DIRECTORIES)
- dptr_idleoldest();
- DEBUG(4,("Reopening dptr key %d\n",key));
- if ((dp->ptr = OpenDir(dp->conn, dp->path, True)))
- dptrs_open++;
- }
- return(dp->ptr);
- }
- return(NULL);
+
+static dptr_struct *dptr_get(int key, BOOL forclose)
+{
+ dptr_struct *dptr;
+
+ for(dptr = dirptrs; dptr; dptr = dptr->next) {
+ if(dptr->dnum == key) {
+ if (!forclose && !dptr->ptr) {
+ if (dptrs_open >= MAX_OPEN_DIRECTORIES)
+ dptr_idleoldest();
+ DEBUG(4,("Reopening dptr key %d\n",key));
+ if ((dptr->ptr = OpenDir(dptr->conn, dptr->path, True)))
+ dptrs_open++;
+ }
+ DLIST_PROMOTE(dirptrs,dptr);
+ return dptr;
+ }
+ }
+ return(NULL);
+}
+
+/****************************************************************************
+ Get the dptr ptr for a dir index.
+****************************************************************************/
+
+static void *dptr_ptr(int key)
+{
+ dptr_struct *dptr = dptr_get(key, False);
+
+ if (dptr)
+ return(dptr->ptr);
+ return(NULL);
}
/****************************************************************************
-get the dir path for a dir index
+ Get the dir path for a dir index.
****************************************************************************/
+
char *dptr_path(int key)
{
- if (dirptrs[key].valid)
- return(dirptrs[key].path);
+ dptr_struct *dptr = dptr_get(key, False);
+
+ if (dptr)
+ return(dptr->path);
return(NULL);
}
/****************************************************************************
-get the dir wcard for a dir index (lanman2 specific)
+ Get the dir wcard for a dir index (lanman2 specific).
****************************************************************************/
+
char *dptr_wcard(int key)
{
- if (dirptrs[key].valid)
- return(dirptrs[key].wcard);
+ dptr_struct *dptr = dptr_get(key, False);
+
+ if (dptr)
+ return(dptr->wcard);
return(NULL);
}
/****************************************************************************
-set the dir wcard for a dir index (lanman2 specific)
-Returns 0 on ok, 1 on fail.
+ Set the dir wcard for a dir index (lanman2 specific).
+ Returns 0 on ok, 1 on fail.
****************************************************************************/
+
BOOL dptr_set_wcard(int key, char *wcard)
{
- if (dirptrs[key].valid) {
- dirptrs[key].wcard = wcard;
+ dptr_struct *dptr = dptr_get(key, False);
+
+ if (dptr) {
+ dptr->wcard = wcard;
return True;
}
return False;
}
/****************************************************************************
-set the dir attrib for a dir index (lanman2 specific)
-Returns 0 on ok, 1 on fail.
+ Set the dir attrib for a dir index (lanman2 specific).
+ Returns 0 on ok, 1 on fail.
****************************************************************************/
+
BOOL dptr_set_attr(int key, uint16 attr)
{
- if (dirptrs[key].valid) {
- dirptrs[key].attr = attr;
+ dptr_struct *dptr = dptr_get(key, False);
+
+ if (dptr) {
+ dptr->attr = attr;
return True;
}
return False;
}
/****************************************************************************
-get the dir attrib for a dir index (lanman2 specific)
+ Get the dir attrib for a dir index (lanman2 specific)
****************************************************************************/
+
uint16 dptr_attr(int key)
{
- if (dirptrs[key].valid)
- return(dirptrs[key].attr);
+ dptr_struct *dptr = dptr_get(key, False);
+
+ if (dptr)
+ return(dptr->attr);
return(0);
}
/****************************************************************************
-close a dptr
+ Close a dptr (internal func).
+****************************************************************************/
+
+static void dptr_close_internal(dptr_struct *dptr)
+{
+ DEBUG(4,("closing dptr key %d\n",dptr->dnum));
+
+ DLIST_REMOVE(dirptrs, dptr);
+
+ /*
+ * Free the dnum in the bitmap. Remember the dnum value is always
+ * biased by one with respect to the bitmap.
+ */
+
+ if(bitmap_query( dptr_bmap, dptr->dnum - 1) != True) {
+ DEBUG(0,("dptr_close_internal : Error - closing dnum = %d and bitmap not set !\n",
+ dptr->dnum ));
+ }
+
+ bitmap_clear(dptr_bmap, dptr->dnum - 1);
+
+ if (dptr->ptr) {
+ CloseDir(dptr->ptr);
+ dptrs_open--;
+ }
+
+ /* Lanman 2 specific code */
+ if (dptr->wcard)
+ free(dptr->wcard);
+ string_set(&dptr->path,"");
+ free((char *)dptr);
+}
+
+/****************************************************************************
+ Close a dptr given a key.
****************************************************************************/
-void dptr_close(int key)
+
+void dptr_close(int *key)
{
+ dptr_struct *dptr;
+
+ if(*key == INVALID_DPTR_KEY)
+ return;
+
/* OS/2 seems to use -1 to indicate "close all directories" */
- if (key == -1) {
- int i;
- for (i=0;i<NUMDIRPTRS;i++)
- dptr_close(i);
+ if (*key == -1) {
+ dptr_struct *next;
+ for(dptr = dirptrs; dptr; dptr = next) {
+ next = dptr->next;
+ dptr_close_internal(dptr);
+ }
+ *key = INVALID_DPTR_KEY;
return;
}
- if (key < 0 || key >= NUMDIRPTRS) {
- DEBUG(3,("Invalid key %d given to dptr_close\n",key));
+ dptr = dptr_get(*key, True);
+
+ if (!dptr) {
+ DEBUG(0,("Invalid key %d given to dptr_close\n", *key));
return;
}
- if (dirptrs[key].valid) {
- DEBUG(4,("closing dptr key %d\n",key));
- if (dirptrs[key].ptr) {
- CloseDir(dirptrs[key].ptr);
- dptrs_open--;
- }
- /* Lanman 2 specific code */
- if (dirptrs[key].wcard)
- free(dirptrs[key].wcard);
- dirptrs[key].valid = False;
- string_set(&dirptrs[key].path,"");
- }
+ dptr_close_internal(dptr);
+
+ *key = INVALID_DPTR_KEY;
}
/****************************************************************************
-close all dptrs for a cnum
+ Close all dptrs for a cnum.
****************************************************************************/
+
void dptr_closecnum(connection_struct *conn)
{
- int i;
- for (i=0;i<NUMDIRPTRS;i++)
- if (dirptrs[i].valid && dirptrs[i].conn == conn)
- dptr_close(i);
+ dptr_struct *dptr, *next;
+ for(dptr = dirptrs; dptr; dptr = next) {
+ next = dptr->next;
+ if (dptr->conn == conn)
+ dptr_close_internal(dptr);
+ }
}
/****************************************************************************
-idle all dptrs for a cnum
+ Idle all dptrs for a cnum.
****************************************************************************/
+
void dptr_idlecnum(connection_struct *conn)
{
- int i;
- for (i=0;i<NUMDIRPTRS;i++)
- if (dirptrs[i].valid && dirptrs[i].conn == conn && dirptrs[i].ptr)
- dptr_idle(i);
+ dptr_struct *dptr;
+ for(dptr = dirptrs; dptr; dptr = dptr->next) {
+ if (dptr->conn == conn && dptr->ptr)
+ dptr_idle(dptr);
+ }
}
/****************************************************************************
-close a dptr that matches a given path, only if it matches the pid also
+ Close a dptr that matches a given path, only if it matches the spid also.
****************************************************************************/
-void dptr_closepath(char *path,int pid)
+
+void dptr_closepath(char *path,uint16 spid)
{
- int i;
- for (i=0;i<NUMDIRPTRS;i++)
- if (dirptrs[i].valid && pid == dirptrs[i].pid &&
- strequal(dirptrs[i].path,path))
- dptr_close(i);
+ dptr_struct *dptr, *next;
+ for(dptr = dirptrs; dptr; dptr = next) {
+ next = dptr->next;
+ if (spid == dptr->spid && strequal(dptr->path,path))
+ dptr_close_internal(dptr);
+ }
}
/****************************************************************************
- start a directory listing
+ Start a directory listing.
****************************************************************************/
+
static BOOL start_dir(connection_struct *conn,char *directory)
{
- DEBUG(5,("start_dir dir=%s\n",directory));
+ DEBUG(5,("start_dir dir=%s\n",directory));
- if (!check_name(directory,conn))
- return(False);
+ if (!check_name(directory,conn))
+ return(False);
- if (! *directory)
- directory = ".";
-
- conn->dirptr = OpenDir(conn, directory, True);
- if (conn->dirptr) {
- dptrs_open++;
- string_set(&conn->dirpath,directory);
- return(True);
- }
+ if (! *directory)
+ directory = ".";
+
+ conn->dirptr = OpenDir(conn, directory, True);
+ if (conn->dirptr) {
+ dptrs_open++;
+ string_set(&conn->dirpath,directory);
+ return(True);
+ }
- return(False);
+ return(False);
}
+/****************************************************************************
+ Try and close the oldest handle not marked for
+ expect close in the hope that the client has
+ finished with that one.
+****************************************************************************/
+
+static void dptr_close_oldest(BOOL old)
+{
+ dptr_struct *dptr;
+
+ /*
+ * Go to the end of the list.
+ */
+ for(dptr = dirptrs; dptr && dptr->next; dptr = dptr->next)
+ ;
+
+ if(!dptr) {
+ DEBUG(0,("No old dptrs available to close oldest ?\n"));
+ return;
+ }
+
+ /*
+ * If 'old' is true, close the oldest oldhandle dnum (ie. 1 < dnum < 256) that
+ * does not have expect_close set. If 'old' is false, close
+ * one of the new dnum handles.
+ */
+
+ for(; dptr; dptr = dptr->prev) {
+ if ((old && (dptr->dnum < 256) && !dptr->expect_close) ||
+ (!old && (dptr->dnum > 255))) {
+ dptr_close_internal(dptr);
+ return;
+ }
+ }
+}
/****************************************************************************
-create a new dir ptr
+ Create a new dir ptr. If the flag old_handle is true then we must allocate
+ from the bitmap range 0 - 255 as old SMBsearch directory handles are only
+ one byte long. If old_handle is false we allocate from the range
+ 256 - MAX_DIRECTORY_HANDLES. We bias the number we return by 1 to ensure
+ a directory handle is never zero. All the above is folklore taught to
+ me at Andrew's knee.... :-) :-). JRA.
****************************************************************************/
-int dptr_create(connection_struct *conn,char *path, BOOL expect_close,int pid)
+
+int dptr_create(connection_struct *conn,char *path, BOOL old_handle, BOOL expect_close,uint16 spid)
{
- int i;
- uint32 old;
- int oldi;
+ dptr_struct *dptr;
if (!start_dir(conn,path))
return(-2); /* Code to say use a unix error return code. */
if (dptrs_open >= MAX_OPEN_DIRECTORIES)
dptr_idleoldest();
- for (i=0;i<NUMDIRPTRS;i++)
- if (!dirptrs[i].valid)
- break;
- if (i == NUMDIRPTRS) i = -1;
+ dptr = (dptr_struct *)malloc(sizeof(dptr_struct));
+ if(!dptr) {
+ DEBUG(0,("malloc fail in dptr_create.\n"));
+ return -1;
+ }
+
+ ZERO_STRUCTP(dptr);
+
+ if(old_handle) {
+
+ /*
+ * This is an old-style SMBsearch request. Ensure the
+ * value we return will fit in the range 1-255.
+ */
+ dptr->dnum = bitmap_find(dptr_bmap, 0);
- /* as a 2nd option, grab the oldest not marked for expect_close */
- if (i == -1) {
- old=dircounter+1;
- oldi= -1;
- for (i=0;i<NUMDIRPTRS;i++)
- if (!dirptrs[i].expect_close && dirptrs[i].lastused < old) {
- old = dirptrs[i].lastused;
- oldi = i;
+ if(dptr->dnum == -1 || dptr->dnum > 254) {
+
+ /*
+ * Try and close the oldest handle not marked for
+ * expect close in the hope that the client has
+ * finished with that one.
+ */
+
+ dptr_close_oldest(True);
+
+ /* Now try again... */
+ dptr->dnum = bitmap_find(dptr_bmap, 0);
+
+ if(dptr->dnum == -1 || dptr->dnum > 254) {
+ DEBUG(0,("dptr_create: returned %d: Error - all old dirptrs in use ?\n", dptr->dnum));
+ free((char *)dptr);
+ return -1;
}
- i = oldi;
- }
+ }
+ } else {
+
+ /*
+ * This is a new-style trans2 request. Allocate from
+ * a range that will return 256 - MAX_DIRECTORY_HANDLES.
+ */
+
+ dptr->dnum = bitmap_find(dptr_bmap, 255);
+
+ if(dptr->dnum == -1 || dptr->dnum < 255) {
+
+ /*
+ * Try and close the oldest handle close in the hope that
+ * the client has finished with that one. This will only
+ * happen in the case of the Win98 client bug where it leaks
+ * directory handles.
+ */
+
+ dptr_close_oldest(False);
- /* a 3rd option - grab the oldest one */
- if (i == -1) {
- old=dircounter+1;
- oldi= -1;
- for (i=0;i<NUMDIRPTRS;i++)
- if (dirptrs[i].lastused < old) {
- old = dirptrs[i].lastused;
- oldi = i;
+ /* Now try again... */
+ dptr->dnum = bitmap_find(dptr_bmap, 255);
+
+ if(dptr->dnum == -1 || dptr->dnum < 255) {
+ DEBUG(0,("dptr_create: returned %d: Error - all new dirptrs in use ?\n", dptr->dnum));
+ free((char *)dptr);
+ return -1;
}
- i = oldi;
+ }
}
- if (i == -1) {
- DEBUG(0,("Error - all dirptrs in use??\n"));
- return(-1);
- }
+ bitmap_set(dptr_bmap, dptr->dnum);
- if (dirptrs[i].valid)
- dptr_close(i);
+ dptr->dnum += 1; /* Always bias the dnum by one - no zero dnums allowed. */
- dirptrs[i].ptr = conn->dirptr;
- string_set(&dirptrs[i].path,path);
- dirptrs[i].lastused = dircounter++;
- dirptrs[i].finished = False;
- dirptrs[i].conn = conn;
- dirptrs[i].pid = pid;
- dirptrs[i].expect_close = expect_close;
- dirptrs[i].wcard = NULL; /* Only used in lanman2 searches */
- dirptrs[i].attr = 0; /* Only used in lanman2 searches */
- dirptrs[i].valid = True;
+ dptr->ptr = conn->dirptr;
+ string_set(&dptr->path,path);
+ dptr->conn = conn;
+ dptr->spid = spid;
+ dptr->expect_close = expect_close;
+ dptr->wcard = NULL; /* Only used in lanman2 searches */
+ dptr->attr = 0; /* Only used in lanman2 searches */
+
+ DLIST_ADD(dirptrs, dptr);
DEBUG(3,("creating new dirptr %d for path %s, expect_close = %d\n",
- i,path,expect_close));
+ dptr->dnum,path,expect_close));
- return(i);
+ return(dptr->dnum);
}
-#define DPTR_MASK ((uint32)(((uint32)1)<<31))
-
/****************************************************************************
-fill the 5 byte server reserved dptr field
+ Fill the 5 byte server reserved dptr field.
****************************************************************************/
+
BOOL dptr_fill(char *buf1,unsigned int key)
{
unsigned char *buf = (unsigned char *)buf1;
- void *p = dptr_get(key,0);
+ void *p = dptr_ptr(key);
uint32 offset;
if (!p) {
DEBUG(1,("filling null dirptr %d\n",key));
return(True);
}
-
/****************************************************************************
-return True is the offset is at zero
+ Fetch the dir ptr and seek it given the 5 byte server field.
****************************************************************************/
-BOOL dptr_zero(char *buf)
-{
- return((IVAL(buf,1)&~DPTR_MASK) == 0);
-}
-/****************************************************************************
-fetch the dir ptr and seek it given the 5 byte server field
-****************************************************************************/
void *dptr_fetch(char *buf,int *num)
{
unsigned int key = *(unsigned char *)buf;
- void *p = dptr_get(key,dircounter++);
+ void *p = dptr_ptr(key);
uint32 offset;
if (!p) {
DEBUG(3,("fetched null dirptr %d\n",key));
}
/****************************************************************************
-fetch the dir ptr.
+ Fetch the dir ptr.
****************************************************************************/
+
void *dptr_fetch_lanman2(int dptr_num)
{
- void *p = dptr_get(dptr_num,dircounter++);
+ void *p = dptr_ptr(dptr_num);
if (!p) {
DEBUG(3,("fetched null dirptr %d\n",dptr_num));
}
/****************************************************************************
-check a filetype for being valid
+ Check a filetype for being valid.
****************************************************************************/
+
BOOL dir_check_ftype(connection_struct *conn,int mode,SMB_STRUCT_STAT *st,int dirtype)
{
if (((mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0)
}
/****************************************************************************
- get a directory entry
+ Get an 8.3 directory entry.
****************************************************************************/
+
BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname,
SMB_OFF_T *size,int *mode,time_t *date,BOOL check_descend)
{
strequal(conn->dirpath,".") ||
strequal(conn->dirpath,"/"));
- needslash =
- ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
+ needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
if (!conn->dirptr)
return(False);
while (!found)
- {
- dname = ReadDirName(conn->dirptr);
+ {
+ BOOL filename_is_mask = False;
+ dname = ReadDirName(conn->dirptr);
- DEBUG(6,("readdir on dirptr 0x%lx now at offset %d\n",
- (long)conn->dirptr,TellDir(conn->dirptr)));
+ DEBUG(6,("readdir on dirptr 0x%lx now at offset %d\n",
+ (long)conn->dirptr,TellDir(conn->dirptr)));
- if (dname == NULL)
- return(False);
+ if (dname == NULL)
+ return(False);
- pstrcpy(filename,dname);
-
- if ((strcmp(filename,mask) == 0) ||
- (name_map_mangle(filename,True,SNUM(conn)) &&
- mask_match(filename,mask,False,False)))
- {
- if (isrootdir && (strequal(filename,"..") || strequal(filename,".")))
- continue;
-
- pstrcpy(fname,filename);
- *path = 0;
- pstrcpy(path,conn->dirpath);
- if(needslash)
- pstrcat(path,"/");
- pstrcpy(pathreal,path);
- pstrcat(path,fname);
- pstrcat(pathreal,dname);
- if (conn->vfs_ops.stat(dos_to_unix(pathreal, False), &sbuf) != 0)
- {
- DEBUG(5,("Couldn't stat 1 [%s]\n",path));
- continue;
- }
-
- if (check_descend &&
- !strequal(fname,".") && !strequal(fname,".."))
- continue;
+ pstrcpy(filename,dname);
+
+ if ((filename_is_mask = (strcmp(filename,mask) == 0)) ||
+ (name_map_mangle(filename,True,False,SNUM(conn)) &&
+ mask_match(filename,mask,False,False)))
+ {
+ if (isrootdir && (strequal(filename,"..") || strequal(filename,".")))
+ continue;
+
+ pstrcpy(fname,filename);
+ *path = 0;
+ pstrcpy(path,conn->dirpath);
+ if(needslash)
+ pstrcat(path,"/");
+ pstrcpy(pathreal,path);
+ pstrcat(path,fname);
+ pstrcat(pathreal,dname);
+ if (conn->vfs_ops.stat(dos_to_unix(pathreal, False), &sbuf) != 0)
+ {
+ DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) ));
+ continue;
+ }
- *mode = dos_mode(conn,pathreal,&sbuf);
+ *mode = dos_mode(conn,pathreal,&sbuf);
- if (!dir_check_ftype(conn,*mode,&sbuf,dirtype)) {
- DEBUG(5,("[%s] attribs didn't match %x\n",filename,dirtype));
- continue;
- }
+ if (!dir_check_ftype(conn,*mode,&sbuf,dirtype))
+ {
+ DEBUG(5,("[%s] attribs didn't match %x\n",filename,dirtype));
+ continue;
+ }
- *size = sbuf.st_size;
- *date = sbuf.st_mtime;
+ if (!filename_is_mask)
+ {
+ /* Now we can allow the mangled cache to be updated */
+ pstrcpy(filename,dname);
+ name_map_mangle(filename,True,True,SNUM(conn));
+ }
- DEBUG(5,("get_dir_entry found %s fname=%s\n",pathreal,fname));
+ *size = sbuf.st_size;
+ *date = sbuf.st_mtime;
+
+ DEBUG(5,("get_dir_entry found %s fname=%s\n",pathreal,fname));
- found = True;
- }
+ found = True;
}
+ }
return(found);
}
/*******************************************************************
-open a directory
+ Open a directory.
********************************************************************/
+
void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
{
Dir *dirp;
while ((n = vfs_readdirname(conn, p)))
{
- int l = strlen(n)+1;
- pstring zn;
+ int l;
+
+ l = strlen(n)+1;
- pstrcpy(zn, unix_to_dos(n, True));
+ /* Return value of vfs_readdirname has already gone through
+ unix_to_dos() */
/* If it's a vetoed file, pretend it doesn't even exist */
- if (use_veto && conn && IS_VETO_PATH(conn, zn)) continue;
+ if (use_veto && conn && IS_VETO_PATH(conn, n)) continue;
if (used + l > dirp->mallocsize) {
int s = MAX(used+l,used+2000);
dirp->mallocsize = s;
dirp->current = dirp->data;
}
- pstrcpy(dirp->data+used,zn);
+ pstrcpy(dirp->data+used,n);
used += l;
dirp->numentries++;
}
/*******************************************************************
-close a directory
+ Close a directory.
********************************************************************/
+
void CloseDir(void *p)
{
Dir *dirp = (Dir *)p;
}
/*******************************************************************
-read from a directory
+ Read from a directory.
********************************************************************/
+
char *ReadDirName(void *p)
{
char *ret;
/*******************************************************************
-seek a dir
+ Seek a dir.
********************************************************************/
+
BOOL SeekDir(void *p,int pos)
{
Dir *dirp = (Dir *)p;
}
/*******************************************************************
-tell a dir position
+ Tell a dir position.
********************************************************************/
+
int TellDir(void *p)
{
Dir *dirp = (Dir *)p;
return(dirp->pos);
}
+/*******************************************************************************
+ This section manages a global directory cache.
+ (It should probably be split into a separate module. crh)
+********************************************************************************/
-/* -------------------------------------------------------------------------- **
- * This section manages a global directory cache.
- * (It should probably be split into a separate module. crh)
- * -------------------------------------------------------------------------- **
- */
-
-typedef struct
- {
+typedef struct {
ubi_dlNode node;
char *path;
char *name;
char *dname;
int snum;
- } dir_cache_entry;
+} dir_cache_entry;
static ubi_dlNewList( dir_cache );
+/*****************************************************************************
+ Add an entry to the directory cache.
+ Input: path -
+ name -
+ dname -
+ snum -
+ Output: None.
+*****************************************************************************/
+
void DirCacheAdd( char *path, char *name, char *dname, int snum )
- /* ------------------------------------------------------------------------ **
- * Add an entry to the directory cache.
- *
- * Input: path -
- * name -
- * dname -
- * snum -
- *
- * Output: None.
- *
- * ------------------------------------------------------------------------ **
- */
- {
+{
int pathlen;
int namelen;
dir_cache_entry *entry;
while( DIRCACHESIZE < dir_cache->count )
free( ubi_dlRemTail( dir_cache ) );
- } /* DirCacheAdd */
+}
+
+/*****************************************************************************
+ Search for an entry to the directory cache.
+ Input: path -
+ name -
+ snum -
+ Output: The dname string of the located entry, or NULL if the entry was
+ not found.
+ Notes: This uses a linear search, which is is okay because of
+ the small size of the cache. Use a splay tree or hash
+ for large caches.
+*****************************************************************************/
char *DirCacheCheck( char *path, char *name, int snum )
- /* ------------------------------------------------------------------------ **
- * Search for an entry to the directory cache.
- *
- * Input: path -
- * name -
- * snum -
- *
- * Output: The dname string of the located entry, or NULL if the entry was
- * not found.
- *
- * Notes: This uses a linear search, which is is okay because of
- * the small size of the cache. Use a splay tree or hash
- * for large caches.
- *
- * ------------------------------------------------------------------------ **
- */
- {
+{
dir_cache_entry *entry;
for( entry = (dir_cache_entry *)ubi_dlFirst( dir_cache );
}
return(NULL);
- } /* DirCacheCheck */
+}
+
+/*****************************************************************************
+ Remove all cache entries which have an snum that matches the input.
+ Input: snum -
+ Output: None.
+*****************************************************************************/
void DirCacheFlush(int snum)
- /* ------------------------------------------------------------------------ **
- * Remove all cache entries which have an snum that matches the input.
- *
- * Input: snum -
- *
- * Output: None.
- *
- * ------------------------------------------------------------------------ **
- */
{
dir_cache_entry *entry;
ubi_dlNodePtr next;
free( ubi_dlRemThis( dir_cache, entry ) );
entry = (dir_cache_entry *)next;
}
-} /* DirCacheFlush */
-
-/* -------------------------------------------------------------------------- **
- * End of the section that manages the global directory cache.
- * -------------------------------------------------------------------------- **
- */
-
-
+}
/****************************************************************************
change a dos mode to a unix mode
base permission for files:
- everybody gets read bit set
+ if inheriting
+ apply read/write bits from parent directory.
+ else
+ everybody gets read bit set
dos readonly is represented in unix by removing everyone's write bit
dos archive is represented in unix by the user's execute bit
dos system is represented in unix by the group's execute bit
dos hidden is represented in unix by the other's execute bit
- Then apply create mask,
- then add force bits.
+ if !inheriting {
+ Then apply create mask,
+ then add force bits.
+ }
base permission for directories:
dos directory is represented in unix by unix's dir bit and the exec bit
- Then apply create mask,
- then add force bits.
+ if !inheriting {
+ Then apply create mask,
+ then add force bits.
+ }
****************************************************************************/
-mode_t unix_mode(connection_struct *conn,int dosmode)
+mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname)
{
mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
+ mode_t dir_mode = 0; /* Mode of the parent directory if inheriting. */
if ( !IS_DOS_READONLY(dosmode) )
result |= (S_IWUSR | S_IWGRP | S_IWOTH);
-
+
+ if (fname && lp_inherit_perms(SNUM(conn))) {
+ char *dname;
+ SMB_STRUCT_STAT sbuf;
+
+ dname = parent_dirname(fname);
+ DEBUG(2,("unix_mode(%s) inheriting from %s\n",fname,dname));
+ if (dos_stat(dname,&sbuf) != 0) {
+ DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n",fname,dname,strerror(errno)));
+ return(0); /* *** shouldn't happen! *** */
+ }
+
+ /* Save for later - but explicitly remove setuid bit for safety. */
+ dir_mode = sbuf.st_mode & ~S_ISUID;
+ DEBUG(2,("unix_mode(%s) inherit mode %o\n",fname,(int)dir_mode));
+ /* Clear "result" */
+ result = 0;
+ }
+
if (IS_DOS_DIR(dosmode)) {
/* We never make directories read only for the owner as under DOS a user
can always create a file in a read-only directory. */
- result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
- /* Apply directory mask */
- result &= lp_dir_mode(SNUM(conn));
- /* Add in force bits */
- result |= lp_force_dir_mode(SNUM(conn));
+ result |= (S_IFDIR | S_IWUSR);
+
+ if (dir_mode) {
+ /* Inherit mode of parent directory. */
+ result |= dir_mode;
+ } else {
+ /* Provisionally add all 'x' bits */
+ result |= (S_IXUSR | S_IXGRP | S_IXOTH);
+
+ /* Apply directory mask */
+ result &= lp_dir_mask(SNUM(conn));
+ /* Add in force bits */
+ result |= lp_force_dir_mode(SNUM(conn));
+ }
} else {
if (lp_map_archive(SNUM(conn)) && IS_DOS_ARCHIVE(dosmode))
result |= S_IXUSR;
if (lp_map_hidden(SNUM(conn)) && IS_DOS_HIDDEN(dosmode))
result |= S_IXOTH;
-
- /* Apply mode mask */
- result &= lp_create_mode(SNUM(conn));
- /* Add in force bits */
- result |= lp_force_create_mode(SNUM(conn));
+
+ if (dir_mode) {
+ /* Inherit 666 component of parent directory mode */
+ result |= dir_mode
+ & (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
+ } else {
+ /* Apply mode mask */
+ result &= lp_create_mask(SNUM(conn));
+ /* Add in force bits */
+ result |= lp_force_create_mode(SNUM(conn));
+ }
}
return(result);
}
if (dos_mode(conn,fname,st) == dosmode) return(0);
- unixmode = unix_mode(conn,dosmode);
+ unixmode = unix_mode(conn,dosmode,fname);
/* preserve the s bits */
mask |= (S_ISUID | S_ISGID);
}
/* if we previously had any w bits set then leave them alone
- if the new mode is not rdonly */
- if (!IS_DOS_READONLY(dosmode) &&
- (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
- unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
- unixmode |= tmp;
+ whilst adding in the new w bits, if the new mode is not rdonly */
+ if (!IS_DOS_READONLY(dosmode)) {
+ unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
}
return(conn->vfs_ops.chmod(dos_to_unix(fname,False),unixmode));
if (file_utime(conn, fname, ×)) {
DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno)));
+ return False;
}
return(True);
}
-
-
extern int DEBUGLEVEL;
+static BOOL setup_write_cache(files_struct *, SMB_OFF_T);
/****************************************************************************
seek a file. Try to avoid the seek if possible
seek_ret = fsp->conn->vfs_ops.lseek(fsp->fd_ptr->fd,pos+offset,SEEK_SET);
+ /*
+ * We want to maintain the fiction that we can seek
+ * on a fifo for file system purposes. This allows
+ * people to set up UNIX fifo's that feed data to Windows
+ * applications. JRA.
+ */
+
+ if((seek_ret == -1) && (errno == ESPIPE)) {
+ seek_ret = pos+offset;
+ errno = 0;
+ }
+
if((seek_ret == -1) || (seek_ret != pos+offset)) {
DEBUG(0,("seek_file: sys_lseek failed. Error was %s\n", strerror(errno) ));
fsp->pos = -1;
return(fsp->pos);
}
+/****************************************************************************
+ Read from write cache if we can.
+****************************************************************************/
+
+static unsigned int cache_read_hits;
+
+BOOL read_from_write_cache(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n)
+{
+ write_cache *wcp = fsp->wcp;
+
+ if(!wcp)
+ return False;
+
+ if(n > wcp->data_size || pos < wcp->offset || pos + n > wcp->offset + wcp->data_size)
+ return False;
+
+ memcpy(data, wcp->data + (pos - wcp->offset), n);
+
+ cache_read_hits++;
+
+ return True;
+}
+
/****************************************************************************
read from a file
****************************************************************************/
#if USE_READ_PREDICTION
if (!fsp->can_write) {
- ret = read_predict(fsp, fsp->fd_ptr->fd,pos,data,NULL,n);
+ ret = read_predict(fsp->fd_ptr->fd,pos,data,NULL,n);
data += ret;
n -= ret;
}
#endif
-#if WITH_MMAP
- if (fsp->mmap_ptr) {
- SMB_OFF_T num = (fsp->mmap_size > pos) ? (fsp->mmap_size - pos) : 0;
- num = MIN(n,num);
- if (num > 0) {
- memcpy(data,fsp->mmap_ptr+pos,num);
- data += num;
- pos += num;
- n -= num;
- ret += num;
- }
- }
-#endif
+ /*
+ * Serve from write cache if we can.
+ */
+ if(read_from_write_cache(fsp, data, pos, n))
+ return n;
+
+ flush_write_cache(fsp, READ_FLUSH);
if (seek_file(fsp,pos) == -1) {
DEBUG(3,("read_file: Failed to seek to %.0f\n",(double)pos));
return(ret);
}
-
+
if (n > 0) {
readret = fsp->conn->vfs_ops.read(fsp->fd_ptr->fd,data,n);
if (readret > 0) ret += readret;
return(ret);
}
+/* Write cache static counters. */
+
+static unsigned int abutted_writes;
+static unsigned int total_writes;
+static unsigned int non_oplock_writes;
+static unsigned int direct_writes;
+static unsigned int init_writes;
+static unsigned int flushed_writes;
+static unsigned int num_perfect_writes;
+static unsigned int flush_reasons[NUM_FLUSH_REASONS];
+
+/* how many write cache buffers have been allocated */
+static unsigned int allocated_write_caches;
+static unsigned int num_write_caches;
+
+/****************************************************************************
+ *Really* write to a file
+****************************************************************************/
+
+static ssize_t real_write_file(files_struct *fsp,char *data,SMB_OFF_T pos, size_t n)
+{
+ if ((pos != -1) && (seek_file(fsp,pos) == -1))
+ return -1;
+
+ return write_data(fsp->fd_ptr->fd,data,n);
+}
/****************************************************************************
write to a file
****************************************************************************/
-ssize_t write_file(files_struct *fsp,char *data,size_t n)
+ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n)
{
+ write_cache *wcp = fsp->wcp;
+ ssize_t total_written = 0;
+ int write_path = -1;
+
if (!fsp->can_write) {
errno = EPERM;
return(0);
if (!fsp->modified) {
SMB_STRUCT_STAT st;
fsp->modified = True;
+
if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&st) == 0) {
int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st);
if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) {
file_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st);
}
+
+ /*
+ * If this is the first write and we have an exclusive oplock then setup
+ * the write cache.
+ */
+
+ if ((fsp->oplock_type == EXCLUSIVE_OPLOCK) && !wcp) {
+ setup_write_cache(fsp, st.st_size);
+ wcp = fsp->wcp;
+ }
}
}
- return(vfs_write_data(fsp,data,n));
+ total_writes++;
+ if (!fsp->oplock_type) {
+ non_oplock_writes++;
+ }
+
+ /*
+ * If this file is level II oplocked then we need
+ * to grab the shared memory lock and inform all
+ * other files with a level II lock that they need
+ * to flush their read caches. We keep the lock over
+ * the shared memory area whilst doing this.
+ */
+
+ if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) {
+ SMB_DEV_T dev = fsp->fd_ptr->dev;
+ SMB_INO_T inode = fsp->fd_ptr->inode;
+ share_mode_entry *share_list = NULL;
+ pid_t pid = getpid();
+ int token = -1;
+ int num_share_modes = 0;
+ int i;
+
+ if (lock_share_entry(fsp->conn, dev, inode) == False) {
+ DEBUG(0,("write_file: failed to lock share mode entry for file %s.\n", fsp->fsp_name ));
+ }
+
+ num_share_modes = get_share_modes(fsp->conn, dev, inode, &share_list);
+
+ for(i = 0; i < num_share_modes; i++) {
+ share_mode_entry *share_entry = &share_list[i];
+
+ /*
+ * As there could have been multiple writes waiting at the lock_share_entry
+ * gate we may not be the first to enter. Hence the state of the op_types
+ * in the share mode entries may be partly NO_OPLOCK and partly LEVEL_II
+ * oplock. It will do no harm to re-send break messages to those smbd's
+ * that are still waiting their turn to remove their LEVEL_II state, and
+ * also no harm to ignore existing NO_OPLOCK states. JRA.
+ */
+
+ if (share_entry->op_type == NO_OPLOCK)
+ continue;
+
+ /* Paranoia .... */
+ if (EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) {
+ DEBUG(0,("write_file: PANIC. share mode entry %d is an exlusive oplock !\n", i ));
+ abort();
+ }
+
+ /*
+ * Check if this is a file we have open (including the
+ * file we've been called to do write_file on. If so
+ * then break it directly without releasing the lock.
+ */
+
+ if (pid == share_entry->pid) {
+ files_struct *new_fsp = file_find_dit(dev, inode, &share_entry->time);
+
+ /* Paranoia check... */
+ if(new_fsp == NULL) {
+ DEBUG(0,("write_file: PANIC. share mode entry %d is not a local file !\n", i ));
+ abort();
+ }
+ oplock_break_level2(new_fsp, True, token);
+
+ } else {
+
+ /*
+ * This is a remote file and so we send an asynchronous
+ * message.
+ */
+
+ request_oplock_break(share_entry, dev, inode);
+ }
+ }
+
+ free((char *)share_list);
+ unlock_share_entry(fsp->conn, dev, inode);
+ }
+
+ /* Paranoia check... */
+ if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) {
+ DEBUG(0,("write_file: PANIC. File %s still has a level II oplock.\n", fsp->fsp_name));
+ abort();
+ }
+
+ if (total_writes % 500 == 0) {
+ DEBUG(3,("WRITECACHE: initwrites=%u abutted=%u flushes=%u total=%u \
+nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",
+ init_writes, abutted_writes, flushed_writes, total_writes, non_oplock_writes,
+ allocated_write_caches,
+ num_write_caches, direct_writes, num_perfect_writes, cache_read_hits ));
+
+ DEBUG(3,("WRITECACHE: SEEK=%d, READ=%d, WRITE=%d, READRAW=%d, OPLOCK=%d, CLOSE=%d, SYNC=%d\n",
+ flush_reasons[SEEK_FLUSH],
+ flush_reasons[READ_FLUSH],
+ flush_reasons[WRITE_FLUSH],
+ flush_reasons[READRAW_FLUSH],
+ flush_reasons[OPLOCK_RELEASE_FLUSH],
+ flush_reasons[CLOSE_FLUSH],
+ flush_reasons[SYNC_FLUSH] ));
+ }
+
+ if(!wcp) {
+ direct_writes++;
+ return real_write_file(fsp, data, pos, n);
+ }
+
+ DEBUG(9,("write_file(fd=%d pos=%d size=%d) wofs=%d wsize=%d\n",
+ fsp->fd_ptr->fd, (int)pos, (int)n, (int)wcp->offset, (int)wcp->data_size));
+
+ /*
+ * If we have active cache and it isn't contiguous then we flush.
+ * NOTE: There is a small problem with running out of disk ....
+ */
+
+ if (wcp->data_size) {
+
+ BOOL cache_flush_needed = False;
+
+ if ((pos >= wcp->offset) && (pos <= wcp->offset + wcp->data_size)) {
+
+ /*
+ * Start of write overlaps or abutts the existing data.
+ */
+
+ size_t data_used = MIN((wcp->alloc_size - (pos - wcp->offset)), n);
+
+ memcpy(wcp->data + (pos - wcp->offset), data, data_used);
+
+ /*
+ * Update the current buffer size with the new data.
+ */
+
+ if(pos + data_used > wcp->offset + wcp->data_size)
+ wcp->data_size = pos + data_used - wcp->offset;
+
+ /*
+ * If we used all the data then
+ * return here.
+ */
+
+ if(n == data_used)
+ return n;
+ else
+ cache_flush_needed = True;
+
+ /*
+ * Move the start of data forward by the amount used,
+ * cut down the amount left by the same amount.
+ */
+
+ data += data_used;
+ pos += data_used;
+ n -= data_used;
+
+ abutted_writes++;
+ total_written = data_used;
+
+ write_path = 1;
+
+ } else if ((pos < wcp->offset) && (pos + n > wcp->offset) &&
+ (pos + n <= wcp->offset + wcp->alloc_size)) {
+
+ /*
+ * End of write overlaps the existing data.
+ */
+
+ size_t data_used = pos + n - wcp->offset;
+
+ memcpy(wcp->data, data + n - data_used, data_used);
+
+ /*
+ * Update the current buffer size with the new data.
+ */
+
+ if(pos + n > wcp->offset + wcp->data_size)
+ wcp->data_size = pos + n - wcp->offset;
+
+ /*
+ * We don't need to move the start of data, but we
+ * cut down the amount left by the amount used.
+ */
+
+ n -= data_used;
+
+ /*
+ * We cannot have used all the data here.
+ */
+
+ cache_flush_needed = True;
+
+ abutted_writes++;
+ total_written = data_used;
+
+ write_path = 2;
+
+ } else if ( (pos >= wcp->file_size) &&
+ (pos > wcp->offset + wcp->data_size) &&
+ (pos < wcp->offset + wcp->alloc_size) ) {
+
+ /*
+ * Non-contiguous write part of which fits within
+ * the cache buffer and is extending the file.
+ */
+
+ size_t data_used;
+
+ if(pos + n <= wcp->offset + wcp->alloc_size)
+ data_used = n;
+ else
+ data_used = wcp->offset + wcp->alloc_size - pos;
+
+ /*
+ * Fill in the non-continuous area with zeros.
+ */
+
+ memset(wcp->data + wcp->data_size, '\0',
+ pos - (wcp->offset + wcp->data_size) );
+
+ memcpy(wcp->data + (pos - wcp->offset), data, data_used);
+
+ /*
+ * Update the current buffer size with the new data.
+ */
+
+ if(pos + data_used > wcp->offset + wcp->data_size)
+ wcp->data_size = pos + data_used - wcp->offset;
+
+ /*
+ * Update the known file length.
+ */
+
+ wcp->file_size = wcp->offset + wcp->data_size;
+
+#if 0
+ if (set_filelen(fsp->fd_ptr->fd, wcp->file_size) == -1) {
+ DEBUG(0,("write_file: error %s in setting file to length %.0f\n",
+ strerror(errno), (double)wcp->file_size ));
+ return -1;
+ }
+#endif
+
+ /*
+ * If we used all the data then
+ * return here.
+ */
+
+ if(n == data_used)
+ return n;
+ else
+ cache_flush_needed = True;
+
+ /*
+ * Move the start of data forward by the amount used,
+ * cut down the amount left by the same amount.
+ */
+
+ data += data_used;
+ pos += data_used;
+ n -= data_used;
+
+ abutted_writes++;
+ total_written = data_used;
+
+ write_path = 3;
+
+ } else {
+
+ /*
+ * Write is bigger than buffer, or there is no overlap on the
+ * low or high ends.
+ */
+
+ DEBUG(9,("write_file: non cacheable write : fd = %d, pos = %.0f, len = %u, current cache pos = %.0f \
+len = %u\n",fsp->fd_ptr->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size ));
+
+ /*
+ * Update the file size if needed.
+ */
+
+ if(pos + n > wcp->file_size)
+ wcp->file_size = pos + n;
+
+ /*
+ * If write would fit in the cache, and is larger than
+ * the data already in the cache, flush the cache and
+ * preferentially copy the data new data into it. Otherwise
+ * just write the data directly.
+ */
+
+ if ( n <= wcp->alloc_size && n > wcp->data_size) {
+ cache_flush_needed = True;
+ } else {
+ direct_writes++;
+ return real_write_file(fsp, data, pos, n);
+ }
+
+ write_path = 4;
+
+ }
+
+ if(wcp->data_size > wcp->file_size)
+ wcp->file_size = wcp->data_size;
+
+ if (cache_flush_needed) {
+ flushed_writes++;
+
+ DEBUG(3,("WRITE_FLUSH:%d: due to noncontinuous write: fd = %d, size = %.0f, pos = %.0f, \
+n = %u, wcp->offset=%.0f, wcp->data_size=%u\n",
+ write_path, fsp->fd_ptr->fd, (double)wcp->file_size, (double)pos, (unsigned int)n,
+ (double)wcp->offset, (unsigned int)wcp->data_size ));
+
+ flush_write_cache(fsp, WRITE_FLUSH);
+ }
+ }
+
+ /*
+ * If the write request is bigger than the cache
+ * size, write it all out.
+ */
+
+ if (n > wcp->alloc_size ) {
+ if(real_write_file(fsp, data, pos, n) == -1)
+ return -1;
+ direct_writes++;
+ return total_written + n;
+ }
+
+ /*
+ * If there's any data left, cache it.
+ */
+
+ if (n) {
+ if (wcp->data_size) {
+ abutted_writes++;
+ DEBUG(9,("abutted write (%u)\n", abutted_writes));
+ } else {
+ init_writes++;
+ }
+ memcpy(wcp->data+wcp->data_size, data, n);
+ if (wcp->data_size == 0) {
+ wcp->offset = pos;
+ num_write_caches++;
+ }
+ wcp->data_size += n;
+ DEBUG(9,("cache return %u\n", (unsigned int)n));
+ total_written += n;
+ return total_written; /* .... that's a write :) */
+ }
+
+ return total_written;
}
+/****************************************************************************
+ Delete the write cache structure.
+****************************************************************************/
+
+void delete_write_cache(files_struct *fsp)
+{
+ write_cache *wcp;
+
+ if(!fsp)
+ return;
+
+ if(!(wcp = fsp->wcp))
+ return;
+
+ allocated_write_caches--;
+
+ SMB_ASSERT(wcp->data_size == 0);
+
+ free(wcp->data);
+ free(wcp);
+
+ fsp->wcp = NULL;
+}
+
+/****************************************************************************
+ Setup the write cache structure.
+****************************************************************************/
+
+static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T filesize)
+{
+ ssize_t alloc_size = lp_write_cache_size(SNUM(fsp->conn));
+ write_cache *wcp;
+
+ if (allocated_write_caches >= MAX_WRITE_CACHES) return False;
+
+ if(alloc_size == 0 || fsp->wcp)
+ return False;
+
+ if((wcp = (write_cache *)malloc(sizeof(write_cache))) == NULL) {
+ DEBUG(0,("setup_write_cache: malloc fail.\n"));
+ return False;
+ }
+
+ wcp->file_size = filesize;
+ wcp->offset = 0;
+ wcp->alloc_size = alloc_size;
+ wcp->data_size = 0;
+ if((wcp->data = malloc(wcp->alloc_size)) == NULL) {
+ DEBUG(0,("setup_write_cache: malloc fail for buffer size %u.\n",
+ (unsigned int)wcp->alloc_size ));
+ free(wcp);
+ return False;
+ }
+
+ fsp->wcp = wcp;
+ allocated_write_caches++;
+
+ return True;
+}
+
+/****************************************************************************
+ Cope with a size change.
+****************************************************************************/
+
+void set_filelen_write_cache(files_struct *fsp, SMB_OFF_T filesize)
+{
+ if(fsp->wcp) {
+ flush_write_cache(fsp, SIZECHANGE_FLUSH);
+ fsp->wcp->file_size = filesize;
+ }
+}
+
+/*******************************************************************
+ Flush a write cache struct to disk.
+********************************************************************/
+
+ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason)
+{
+ write_cache *wcp = fsp->wcp;
+ size_t data_size;
+
+ if(!wcp || !wcp->data_size)
+ return 0;
+
+ data_size = wcp->data_size;
+ wcp->data_size = 0;
+
+ num_write_caches--;
+
+ flush_reasons[(int)reason]++;
+
+ DEBUG(9,("flushing write cache: fd = %d, off=%.0f, size=%u\n",
+ fsp->fd_ptr->fd, (double)wcp->offset, (unsigned int)data_size));
+
+ if(data_size == wcp->alloc_size)
+ num_perfect_writes++;
+
+ return real_write_file(fsp, wcp->data, wcp->offset, data_size);
+}
/*******************************************************************
sync a file
********************************************************************/
-void sys_sync_file(int fd)
+void sys_fsync_file(connection_struct *conn, files_struct *fsp)
{
#ifdef HAVE_FSYNC
- fsync(fd);
+ if(lp_strict_sync(SNUM(conn)) && fsp->fd_ptr != NULL) {
+ flush_write_cache(fsp, SYNC_FLUSH);
+ conn->vfs_ops.fsync(fsp->fd_ptr->fd);
+ }
#endif
}
Version 1.9.
filename handling routines
Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Jeremy Allison 1999-200
+ Copyright (C) Ying Chen 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
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+/*
+ * New hash table stat cache code added by Ying Chen.
+ */
+
#include "includes.h"
extern int DEBUGLEVEL;
extern BOOL case_preserve;
extern BOOL short_case_preserve;
extern fstring remote_machine;
-extern pstring global_myname;
extern BOOL use_mangled_map;
static BOOL scan_directory(char *path, char *name,connection_struct *conn,BOOL docache);
void print_stat_cache_statistics(void)
{
- double eff = (100.0* (double)global_stat_cache_hits)/(double)global_stat_cache_lookups;
+ double eff;
+
+ if(global_stat_cache_lookups == 0)
+ return;
+
+ eff = (100.0* (double)global_stat_cache_hits)/(double)global_stat_cache_lookups;
DEBUG(0,("stat cache stats: lookups = %d, hits = %d, misses = %d, \
stat cache was %f%% effective.\n", global_stat_cache_lookups,
}
typedef struct {
- ubi_dlNode link;
int name_len;
- pstring orig_name;
- pstring translated_name;
+ char names[2]; /* This is extended via malloc... */
} stat_cache_entry;
-#define MAX_STAT_CACHE_SIZE 50
-
-static ubi_dlList stat_cache = { NULL, (ubi_dlNodePtr)&stat_cache, 0};
+#define INIT_STAT_CACHE_SIZE 512
+static hash_table stat_cache;
/****************************************************************************
Compare a pathname to a name in the stat cache - of a given length.
case.
*****************************************************************************/
+#if 0 /* This function unused?? */
static BOOL stat_name_equal_len( char *stat_name, char *orig_name, int len)
{
BOOL matched = (memcmp( stat_name, orig_name, len) == 0);
return matched;
}
+#endif
/****************************************************************************
Add an entry into the stat cache.
static void stat_cache_add( char *full_orig_name, char *orig_translated_path)
{
stat_cache_entry *scp;
+ stat_cache_entry *found_scp;
pstring orig_name;
pstring translated_path;
int namelen;
+ hash_element *hash_elem;
if (!lp_stat_cache()) return;
* add it.
*/
- for( scp = (stat_cache_entry *)ubi_dlFirst( &stat_cache); scp;
- scp = (stat_cache_entry *)ubi_dlNext( scp )) {
- if((strcmp( scp->orig_name, orig_name) == 0) &&
- (strcmp( scp->translated_name, translated_path) == 0)) {
- /*
- * Name does exist - promote it.
- */
- if( (stat_cache_entry *)ubi_dlFirst( &stat_cache) != scp ) {
- ubi_dlRemThis( &stat_cache, scp);
- ubi_dlAddHead( &stat_cache, scp);
- }
+ if ((hash_elem = hash_lookup(&stat_cache, orig_name))) {
+ found_scp = (stat_cache_entry *)(hash_elem->value);
+ if (strcmp((found_scp->names+found_scp->name_len+1), translated_path) == 0) {
return;
+ } else {
+ hash_remove(&stat_cache, hash_elem);
+ if((scp = (stat_cache_entry *)malloc(sizeof(stat_cache_entry)+2*namelen)) == NULL) {
+ DEBUG(0,("stat_cache_add: Out of memory !\n"));
+ return;
+ }
+ pstrcpy(scp->names, orig_name);
+ pstrcpy((scp->names+namelen+1), translated_path);
+ scp->name_len = namelen;
+ hash_insert(&stat_cache, (char *)scp, orig_name);
}
- }
-
- if((scp = (stat_cache_entry *)malloc(sizeof(stat_cache_entry))) == NULL) {
- DEBUG(0,("stat_cache_add: Out of memory !\n"));
return;
- }
-
- pstrcpy(scp->orig_name, orig_name);
- pstrcpy(scp->translated_name, translated_path);
- scp->name_len = namelen;
+ } else {
- ubi_dlAddHead( &stat_cache, scp);
-
- DEBUG(10,("stat_cache_add: Added entry %s -> %s\n", scp->orig_name, scp->translated_name ));
+ /*
+ * New entry.
+ */
- if(ubi_dlCount(&stat_cache) > lp_stat_cache_size()) {
- scp = (stat_cache_entry *)ubi_dlRemTail( &stat_cache );
- free((char *)scp);
- return;
+ if((scp = (stat_cache_entry *)malloc(sizeof(stat_cache_entry)+2*namelen)) == NULL) {
+ DEBUG(0,("stat_cache_add: Out of memory !\n"));
+ return;
+ }
+ pstrcpy(scp->names, orig_name);
+ pstrcpy(scp->names+namelen+1, translated_path);
+ scp->name_len = namelen;
+ hash_insert(&stat_cache, (char *)scp, orig_name);
}
+
+ DEBUG(5,("stat_cache_add: Added entry %s -> %s\n", scp->names, (scp->names+scp->name_len+1)));
}
/****************************************************************************
Return True if we translated (and did a scuccessful stat on) the entire name.
*****************************************************************************/
-static BOOL stat_cache_lookup(struct connection_struct *conn, char *name,
- char *dirpath, char **start,
- SMB_STRUCT_STAT *pst)
+static BOOL stat_cache_lookup(connection_struct *conn, char *name, char *dirpath,
+ char **start, SMB_STRUCT_STAT *pst)
{
stat_cache_entry *scp;
- stat_cache_entry *longest_hit = NULL;
+ char *trans_name;
pstring chk_name;
int namelen;
+ hash_element *hash_elem;
+ char *sp;
- if (!lp_stat_cache()) return False;
+ if (!lp_stat_cache())
+ return False;
namelen = strlen(name);
if(!case_sensitive)
strupper( chk_name );
- for( scp = (stat_cache_entry *)ubi_dlFirst( &stat_cache); scp;
- scp = (stat_cache_entry *)ubi_dlNext( scp )) {
- if(scp->name_len <= namelen) {
- if(stat_name_equal_len(scp->orig_name, chk_name, scp->name_len)) {
- if((longest_hit == NULL) || (longest_hit->name_len <= scp->name_len))
- longest_hit = scp;
+ while (1) {
+ hash_elem = hash_lookup(&stat_cache, chk_name);
+ if(hash_elem == NULL) {
+ /*
+ * Didn't find it - remove last component for next try.
+ */
+ sp = strrchr(chk_name, '/');
+ if (sp) {
+ *sp = '\0';
+ } else {
+ /*
+ * We reached the end of the name - no match.
+ */
+ global_stat_cache_misses++;
+ return False;
+ }
+ if((*chk_name == '\0') || (strcmp(chk_name, ".") == 0)
+ || (strcmp(chk_name, "..") == 0)) {
+ global_stat_cache_misses++;
+ return False;
}
+ } else {
+ scp = (stat_cache_entry *)(hash_elem->value);
+ global_stat_cache_hits++;
+ trans_name = scp->names+scp->name_len+1;
+ if(conn->vfs_ops.stat(dos_to_unix(trans_name,False), pst) != 0) {
+ /* Discard this entry - it doesn't exist in the filesystem. */
+ hash_remove(&stat_cache, hash_elem);
+ return False;
+ }
+ memcpy(name, trans_name, scp->name_len);
+ *start = &name[scp->name_len];
+ if(**start == '/')
+ ++*start;
+ StrnCpy( dirpath, trans_name, name - (*start));
+ return (namelen == scp->name_len);
}
}
-
- if(longest_hit == NULL) {
- DEBUG(10,("stat_cache_lookup: cache miss on %s\n", name));
- global_stat_cache_misses++;
- return False;
- }
-
- global_stat_cache_hits++;
-
- DEBUG(10,("stat_cache_lookup: cache hit for name %s. %s -> %s\n",
- name, longest_hit->orig_name, longest_hit->translated_name ));
-
- /*
- * longest_hit is the longest match we got in the list.
- * Check it exists - if so, overwrite the original name
- * and then promote it to the top.
- */
-
- if(conn->vfs_ops.stat(dos_to_unix(longest_hit->translated_name,False),
- pst) != 0) {
- /*
- * Discard this entry.
- */
- ubi_dlRemThis( &stat_cache, longest_hit);
- free((char *)longest_hit);
- return False;
- }
-
- memcpy(name, longest_hit->translated_name, longest_hit->name_len);
- if( (stat_cache_entry *)ubi_dlFirst( &stat_cache) != longest_hit ) {
- ubi_dlRemThis( &stat_cache, longest_hit);
- ubi_dlAddHead( &stat_cache, longest_hit);
- }
-
- *start = &name[longest_hit->name_len];
- if(**start == '/')
- ++*start;
-
- StrnCpy( dirpath, longest_hit->translated_name, name - (*start));
-
- return (namelen == longest_hit->name_len);
}
-/****************************************************************************
- this routine converts from the dos and dfs namespace to the unix namespace.
-****************************************************************************/
-BOOL unix_dfs_convert(char *name,connection_struct *conn,
- char *saved_last_component,
- BOOL *bad_path, SMB_STRUCT_STAT *pst)
-{
- pstring local_path;
-
- DEBUG(10,("unix_dfs_convert: %s\n", name));
-
- if (name != NULL &&
- under_dfs(conn, name, local_path, sizeof(local_path)))
- {
- DEBUG(10,("%s is in dfs map.\n", name));
-
- /* check for our own name */
- if (StrCaseCmp(global_myname, name+1) > 0)
- {
- return False;
- }
-
- pstrcpy(name, local_path);
-
- DEBUG(10,("removed name: %s\n", name));
- }
- return unix_convert(name, conn, saved_last_component, bad_path, pst);
-}
-
-
-/*******************************************************************
-reduce a file name, removing .. elements.
-********************************************************************/
-static void unix_clean_name(char *s)
-{
- char *p=NULL;
-
- DEBUG(3,("unix_clean_name [%s]\n",s));
-
- /* remove any double slashes */
- string_sub(s, "//","/");
-
- /* Remove leading ./ characters */
- if(strncmp(s, "./", 2) == 0) {
- trim_string(s, "./", NULL);
- if(*s == 0)
- pstrcpy(s,"./");
- }
-
- while ((p = strstr(s,"/../")) != NULL)
- {
- pstring s1;
-
- *p = 0;
- pstrcpy(s1,p+3);
-
- if ((p=strrchr(s,'/')) != NULL)
- *p = 0;
- else
- *s = 0;
- pstrcat(s,s1);
- }
-
- trim_string(s,NULL,"/..");
-}
/****************************************************************************
This routine is called to convert names from the dos namespace to unix
namespace. It needs to handle any case conversions, mangling, format
as Windows applications depend on ERRbadpath being returned if a component
of a pathname does not exist.
****************************************************************************/
-BOOL unix_convert(char *name,connection_struct *conn,
- char *saved_last_component,
- BOOL *bad_path, SMB_STRUCT_STAT *pst)
+
+BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
+ BOOL *bad_path, SMB_STRUCT_STAT *pst)
{
SMB_STRUCT_STAT st;
char *start, *end;
pstring dirpath;
pstring orig_path;
- int saved_errno;
BOOL component_was_mangled = False;
BOOL name_has_wildcard = False;
#if 0
*dirpath = 0;
*bad_path = False;
if(pst) {
- ZERO_STRUCTP(pst);
+ ZERO_STRUCTP(pst);
}
if(saved_last_component)
for (s=name2 ; *s ; s++)
if (!issafe(*s)) *s = '_';
- pstrcpy(name,(char *)mktemp(name2));
+ pstrcpy(name,(char *)smbd_mktemp(name2));
}
return(True);
}
return(True);
}
- saved_errno = errno;
-
DEBUG(5,("unix_convert begin: name = %s, dirpath = %s, start = %s\n",
name, dirpath, start));
*/
if (case_sensitive && !is_mangled(name) &&
- !lp_strip_dot() && !use_mangled_map && (saved_errno != ENOENT))
+ !lp_strip_dot() && !use_mangled_map)
return(False);
if(strchr(start,'?') || strchr(start,'*'))
return(True);
}
-/*******************************************************************
-reduce a file name, removing .. elements and checking that
-it is below dir in the hierarchy. This uses GetWd() and so must be run
-on the system that has the referenced file system.
-
-widelinks are allowed if widelinks is true
-********************************************************************/
-
-static BOOL reduce_name(char *s,char *dir,BOOL widelinks)
-{
-#ifndef REDUCE_PATHS
- return True;
-#else
- pstring dir2;
- pstring wd;
- pstring base_name;
- pstring newname;
- char *p=NULL;
- BOOL relative = (*s != '/');
-
- *dir2 = *wd = *base_name = *newname = 0;
-
- if (widelinks)
- {
- unix_clean_name(s);
- /* can't have a leading .. */
- if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
- {
- DEBUG(3,("Illegal file name? (%s)\n",s));
- return(False);
- }
-
- if (strlen(s) == 0)
- pstrcpy(s,"./");
-
- return(True);
- }
-
- DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
-
- /* remove any double slashes */
- string_sub(s,"//","/");
-
- pstrcpy(base_name,s);
- p = strrchr(base_name,'/');
-
- if (!p)
- return(True);
-
- if (!dos_GetWd(wd))
- {
- DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
- return(False);
- }
-
- if (dos_ChDir(dir) != 0)
- {
- DEBUG(0,("couldn't chdir to %s\n",dir));
- return(False);
- }
-
- if (!dos_GetWd(dir2))
- {
- DEBUG(0,("couldn't getwd for %s\n",dir));
- dos_ChDir(wd);
- return(False);
- }
-
-
- if (p && (p != base_name))
- {
- *p = 0;
- if (strcmp(p+1,".")==0)
- p[1]=0;
- if (strcmp(p+1,"..")==0)
- *p = '/';
- }
-
- if (dos_ChDir(base_name) != 0)
- {
- dos_ChDir(wd);
- DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name));
- return(False);
- }
-
- if (!dos_GetWd(newname))
- {
- dos_ChDir(wd);
- DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
- return(False);
- }
-
- if (p && (p != base_name))
- {
- pstrcat(newname,"/");
- pstrcat(newname,p+1);
- }
-
- {
- size_t l = strlen(dir2);
- if (dir2[l-1] == '/')
- l--;
-
- if (strncmp(newname,dir2,l) != 0)
- {
- dos_ChDir(wd);
- DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
- return(False);
- }
-
- if (relative)
- {
- if (newname[l] == '/')
- pstrcpy(s,newname + l + 1);
- else
- pstrcpy(s,newname+l);
- }
- else
- pstrcpy(s,newname);
- }
-
- dos_ChDir(wd);
-
- if (strlen(s) == 0)
- pstrcpy(s,"./");
-
- DEBUG(3,("reduced to %s\n",s));
- return(True);
-#endif
-}
/****************************************************************************
check a filename - possibly caling reducename
continue;
pstrcpy(name2,dname);
- if (!name_map_mangle(name2,False,SNUM(conn))) continue;
+ if (!name_map_mangle(name2,False,True,SNUM(conn)))
+ continue;
if ((mangled && mangled_equal(name,name2))
|| fname_equal(name, name2))
CloseDir(cur_dir);
return(False);
}
+
+/*************************************************************************** **
+ * Initializes or clears the stat cache.
+ *
+ * Input: none.
+ * Output: none.
+ *
+ * ************************************************************************** **
+ */
+BOOL reset_stat_cache( void )
+{
+ return hash_table_init( &stat_cache, INIT_STAT_CACHE_SIZE, (compare_function)(strcmp));
+} /* reset_stat_cache */
files_used++;
fsp->fnum = i + FILE_HANDLE_OFFSET;
- string_init(&fsp->fsp_name,"");
+ string_set(&fsp->fsp_name,"");
DLIST_ADD(Files, fsp);
for (fsp=Files;fsp;fsp=next) {
next = fsp->next;
if (fsp->conn == conn && fsp->open) {
- if (fsp->is_directory)
- close_directory(fsp);
- else
- close_file(fsp,False);
+ close_file(fsp,False);
}
}
}
}
/*
- * Ensure that pipe_handle_offset is set correctly.
+ * Ensure that pipe_handle_oppset is set correctly.
*/
set_pipe_handle_offset(real_max_open_files);
}
for (fsp=Files;fsp;fsp=next) {
next=fsp->next;
if ((fsp->vuid == vuid) && fsp->open) {
- if(!fsp->is_directory)
- close_file(fsp,False);
- else
- close_directory(fsp);
+ close_file(fsp,False);
}
}
}
for (fsp=Files;fsp;fsp=next) {
next=fsp->next;
- if (fsp->open && (conn == fsp->conn) && (fsp->fd_ptr != NULL)
- && lp_strict_sync(SNUM(conn))){
- conn->vfs_ops.sync(fsp->fd_ptr->fd);
+ if (fsp->open && (conn == fsp->conn) && (fsp->fd_ptr != NULL)) {
+ conn->vfs_ops.fsync(fsp->fd_ptr->fd);
}
}
}
+
/****************************************************************************
free up a fd_ptr
****************************************************************************/
******************************************************************/
static void copy_trans_params_and_data(char *outbuf, int align,
- prs_struct *rparam, prs_struct *rdata,
- int param_offset, int data_offset,
- int param_len, int data_len)
+ prs_struct *rparam, prs_struct *rdata,
+ int param_offset, int data_offset,
+ int param_len, int data_len)
{
- char *copy_into = smb_buf(outbuf)+1;
+ char *copy_into = smb_buf(outbuf) + 1;
- DEBUG(5,("copy_trans_params_and_data: params[%d..%d] data[%d..%d]\n",
- param_offset, param_offset + param_len,
- data_offset , data_offset + data_len));
+ DEBUG(5, ("copy_trans_params_and_data: params[%d..%d] data[%d..%d]\n",
+ param_offset, param_offset + param_len,
+ data_offset, data_offset + data_len));
- if (param_len) prs_buf_copy(copy_into, rparam, param_offset, param_len);
+ if (param_len)
+ prs_buf_copy(copy_into, rparam, param_offset, param_len);
copy_into += param_len + align;
- if (data_len ) prs_buf_copy(copy_into, rdata , data_offset , data_len);
+ if (data_len)
+ prs_buf_copy(copy_into, rdata, data_offset, data_len);
}
/****************************************************************************
send a trans reply
****************************************************************************/
void send_trans_reply(char *outbuf,
- prs_struct *rdata,
- prs_struct *rparam,
- uint16 *setup, int lsetup, int max_data_ret,
- BOOL pipe_data_outstanding)
+ prs_struct *rdata,
+ prs_struct *rparam,
+ uint16 *setup, int lsetup, int max_data_ret,
+ BOOL pipe_data_outstanding)
{
int i;
- int this_ldata,this_lparam;
- int tot_data=0,tot_param=0;
+ int this_ldata, this_lparam;
+ int tot_data = 0, tot_param = 0;
int align;
- int ldata = rdata ? prs_buf_len(rdata ) : 0;
+ int ldata = rdata ? prs_buf_len(rdata) : 0;
int lparam = rparam ? prs_buf_len(rparam) : 0;
BOOL buffer_too_large = max_data_ret ? ldata > max_data_ret : False;
- DEBUG(10,("send_trans_reply: max_data_ret: %d datalen: %d plen: %d\n",
- max_data_ret, ldata, lparam));
+ DEBUG(10,
+ ("send_trans_reply: max_data_ret: %d datalen: %d plen: %d\n",
+ max_data_ret, ldata, lparam));
if (buffer_too_large)
{
- DEBUG(5,("send_trans_reply: buffer %d too large %d\n", ldata, max_data_ret));
+ DEBUG(5,
+ ("send_trans_reply: buffer %d too large %d\n", ldata,
+ max_data_ret));
ldata = max_data_ret;
}
- this_lparam = MIN(lparam,max_send - (500+lsetup*SIZEOFWORD)); /* hack */
- this_ldata = MIN(ldata,max_send - (500+lsetup*SIZEOFWORD+this_lparam));
+ this_lparam = MIN(lparam, max_send - (500 + lsetup * SIZEOFWORD)); /* hack */
+ this_ldata =
+ MIN(ldata,
+ max_send - (500 + lsetup * SIZEOFWORD + this_lparam));
- align = ((this_lparam)%4);
+ align = ((this_lparam) % 4);
- set_message(outbuf,10+lsetup,1+align+this_ldata+this_lparam,True);
+ set_message(outbuf, 10 + lsetup, 1 + align + this_ldata + this_lparam,
+ True);
if (buffer_too_large || pipe_data_outstanding)
{
{
/* issue a buffer size warning. on a DCE/RPC pipe, expect an SMBreadX... */
SIVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- SIVAL(outbuf, smb_rcls, 0x80000005); /* STATUS_BUFFER_OVERFLOW */
- } else {
+ SIVAL(outbuf, smb_rcls, 0x80000005); /* STATUS_BUFFER_OVERFLOW */
+ }
+ else
+ {
SCVAL(outbuf, smb_rcls, ERRDOS);
SSVAL(outbuf, smb_err, ERRmoredata);
}
}
copy_trans_params_and_data(outbuf, align,
- rparam , rdata,
- tot_param , tot_data,
- this_lparam, this_ldata);
-
- SSVAL(outbuf,smb_vwv0,lparam);
- SSVAL(outbuf,smb_vwv1,ldata);
- SSVAL(outbuf,smb_vwv3,this_lparam);
- SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf)+1,outbuf));
- SSVAL(outbuf,smb_vwv5,0);
- SSVAL(outbuf,smb_vwv6,this_ldata);
- SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+1+this_lparam+align,outbuf));
- SSVAL(outbuf,smb_vwv8,0);
- SSVAL(outbuf,smb_vwv9,lsetup);
-
- for (i=0;i<lsetup;i++)
+ rparam, rdata,
+ tot_param, tot_data,
+ this_lparam, this_ldata);
+
+ SSVAL(outbuf, smb_vwv0, lparam);
+ SSVAL(outbuf, smb_vwv1, ldata);
+ SSVAL(outbuf, smb_vwv3, this_lparam);
+ SSVAL(outbuf, smb_vwv4, smb_offset(smb_buf(outbuf) + 1, outbuf));
+ SSVAL(outbuf, smb_vwv5, 0);
+ SSVAL(outbuf, smb_vwv6, this_ldata);
+ SSVAL(outbuf, smb_vwv7,
+ smb_offset(smb_buf(outbuf) + 1 + this_lparam + align, outbuf));
+ SSVAL(outbuf, smb_vwv8, 0);
+ SSVAL(outbuf, smb_vwv9, lsetup);
+
+ for (i = 0; i < lsetup; i++)
{
- SSVAL(outbuf,smb_vwv10+i*SIZEOFWORD,setup[i]);
+ SSVAL(outbuf, smb_vwv10 + i * SIZEOFWORD, setup[i]);
}
show_msg(outbuf);
- send_smb(Client,outbuf);
+ send_smb(Client, outbuf);
tot_data = this_ldata;
tot_param = this_lparam;
while (tot_data < ldata || tot_param < lparam)
{
- this_lparam = MIN(lparam-tot_param, max_send - 500); /* hack */
- this_ldata = MIN(ldata -tot_data , max_send - (500+this_lparam));
+ this_lparam = MIN(lparam - tot_param, max_send - 500); /* hack */
+ this_ldata =
+ MIN(ldata - tot_data, max_send - (500 + this_lparam));
- align = (this_lparam%4);
+ align = (this_lparam % 4);
- set_message(outbuf,10,1+this_ldata+this_lparam+align,False);
+ set_message(outbuf, 10, 1 + this_ldata + this_lparam + align,
+ False);
copy_trans_params_and_data(outbuf, align,
- rparam , rdata,
- tot_param , tot_data,
- this_lparam, this_ldata);
-
- SSVAL(outbuf,smb_vwv3,this_lparam);
- SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf)+1,outbuf));
- SSVAL(outbuf,smb_vwv5,tot_param);
- SSVAL(outbuf,smb_vwv6,this_ldata);
- SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+1+this_lparam+align,outbuf));
- SSVAL(outbuf,smb_vwv8,tot_data);
- SSVAL(outbuf,smb_vwv9,0);
+ rparam, rdata,
+ tot_param, tot_data,
+ this_lparam, this_ldata);
+
+ SSVAL(outbuf, smb_vwv3, this_lparam);
+ SSVAL(outbuf, smb_vwv4,
+ smb_offset(smb_buf(outbuf) + 1, outbuf));
+ SSVAL(outbuf, smb_vwv5, tot_param);
+ SSVAL(outbuf, smb_vwv6, this_ldata);
+ SSVAL(outbuf, smb_vwv7,
+ smb_offset(smb_buf(outbuf) + 1 + this_lparam + align,
+ outbuf));
+ SSVAL(outbuf, smb_vwv8, tot_data);
+ SSVAL(outbuf, smb_vwv9, 0);
show_msg(outbuf);
- send_smb(Client,outbuf);
+ send_smb(Client, outbuf);
- tot_data += this_ldata;
+ tot_data += this_ldata;
tot_param += this_lparam;
}
}
prs_create(&ps, rdata, rlen, 0, False);
prs_debug_out(&ps, "api_rpc_trans_reply", 200);
send_trans_reply(outbuf, &ps, NULL, NULL, 0, rlen,
- pipe_data_outstanding);
+ pipe_data_outstanding);
}
/****************************************************************************
WaitNamedPipeHandleState
****************************************************************************/
-static BOOL api_WNPHS(char *outbuf, pipes_struct *p, char *param, int mdrcnt)
+static BOOL api_WNPHS(char *outbuf, pipes_struct * p, char *param, int mdrcnt)
{
uint16 priority;
- if (!param) return False;
+ if (!param)
+ return False;
priority = param[0] + (param[1] << 8);
- DEBUG(4,("WaitNamedPipeHandleState priority %x\n", priority));
+ DEBUG(4, ("WaitNamedPipeHandleState priority %x\n", priority));
if (wait_rpc_pipe_hnd_state(p, priority))
{
/****************************************************************************
SetNamedPipeHandleState
****************************************************************************/
-static BOOL api_SNPHS(char *outbuf, pipes_struct *p, char *param, int mdrcnt)
+static BOOL api_SNPHS(char *outbuf, pipes_struct * p, char *param, int mdrcnt)
{
uint16 id;
- if (!param) return False;
+ if (!param)
+ return False;
id = param[0] + (param[1] << 8);
- DEBUG(4,("SetNamedPipeHandleState to code %x\n", id));
+ DEBUG(4, ("SetNamedPipeHandleState to code %x\n", id));
if (set_rpc_pipe_hnd_state(p, id))
{
prs_init(&rparam, 4, 0, False);
rparam.start = 0;
- rparam.end = 4;
+ rparam.end = 4;
/* unsupported */
- SSVAL(rparam.data,0,NERR_notsupported);
- SSVAL(rparam.data,2,0); /* converter word */
+ SSVAL(rparam.data, 0, NERR_notsupported);
+ SSVAL(rparam.data, 2, 0); /* converter word */
- DEBUG(3,("Unsupported API fd command\n"));
+ DEBUG(3, ("Unsupported API fd command\n"));
/* now send the reply */
- send_trans_reply(outbuf, NULL, &rparam, NULL, 0, max_rdata_len, False);
+ send_trans_reply(outbuf, NULL, &rparam, NULL, 0, max_rdata_len,
+ False);
prs_free_data(&rparam);
- return(-1);
+ return (-1);
}
/****************************************************************************
handle remote api calls delivered to a named pipe already opened.
****************************************************************************/
-static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf,
- uint16 *setup,char *data,char *params,
- int suwcnt,int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
+static int api_fd_reply(connection_struct * conn, uint16 vuid, char *outbuf,
+ uint16 *setup, char *data, char *params,
+ int suwcnt, int tdscnt, int tpscnt, int mdrcnt,
+ int mprcnt)
{
- BOOL reply = False;
+ BOOL reply = False;
uint16 pnum;
uint16 subcommand;
pipes_struct *p = NULL;
- DEBUG(5,("api_fd_reply\n"));
+ DEBUG(5, ("api_fd_reply\n"));
/* First find out the name of this file. */
if (suwcnt != 2)
{
- DEBUG(0,("Unexpected named pipe transaction.\n"));
- return(-1);
+ DEBUG(0, ("Unexpected named pipe transaction.\n"));
+ return (-1);
}
/* Get the file handle and hence the file name. */
if (p != NULL)
{
- DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)",
- subcommand, p->name, pnum));
+ DEBUG(3, ("Got API command 0x%x on pipe \"%s\" (pnum %x)",
+ subcommand, p->name, pnum));
/* record maximum data length that can be transmitted in an SMBtrans */
- DEBUG(10,("api_fd_reply: p:%p mdrcnt: %d\n", p, mdrcnt));
+ DEBUG(10, ("api_fd_reply: p:%p mdrcnt: %d\n", p, mdrcnt));
switch (subcommand)
{
char *rdata = NULL;
int rlen = mdrcnt;
reply = readwrite_pipe(p, data, tdscnt,
- &rdata, &rlen,
- &pipe_outstanding);
+ &rdata, &rlen,
+ &pipe_outstanding);
if (reply)
{
- api_rpc_trans_reply(outbuf, rdata, rlen,
- pipe_outstanding);
+ api_rpc_trans_reply(outbuf, rdata,
+ rlen,
+ pipe_outstanding);
}
break;
}
}
else
{
- DEBUG(1,("api_fd_reply: INVALID PIPE HANDLE: %x\n", pnum));
+ DEBUG(1, ("api_fd_reply: INVALID PIPE HANDLE: %x\n", pnum));
}
if (!reply)
/****************************************************************************
handle named pipe commands
****************************************************************************/
-static int named_pipe(connection_struct *conn,uint16 vuid, char *outbuf,char *name,
- uint16 *setup,char *data,char *params,
- int suwcnt,int tdscnt,int tpscnt,
- int msrcnt,int mdrcnt,int mprcnt)
+static int named_pipe(connection_struct * conn, uint16 vuid, char *outbuf,
+ char *name, uint16 *setup, char *data, char *params,
+ int suwcnt, int tdscnt, int tpscnt, int msrcnt,
+ int mdrcnt, int mprcnt)
{
- DEBUG(3,("named pipe command on <%s> name\n", name));
+ DEBUG(3, ("named pipe command on <%s> name\n", name));
- if (strequal(name,"LANMAN"))
+ if (strequal(name, "LANMAN"))
{
- return api_reply(conn,vuid,outbuf,data,params,tdscnt,tpscnt,mdrcnt,mprcnt);
+ return api_reply(conn, vuid, outbuf, data, params, tdscnt,
+ tpscnt, mdrcnt, mprcnt);
}
- if (strequal(name,"WKSSVC") ||
- strequal(name,"SRVSVC") ||
- strequal(name,"WINREG") ||
- strequal(name,"SAMR") ||
- strequal(name,"LSARPC"))
+ if (strequal(name, "WKSSVC") ||
+ strequal(name, "SRVSVC") ||
+ strequal(name, "WINREG") ||
+ strequal(name, "SAMR") || strequal(name, "LSARPC"))
{
- DEBUG(4,("named pipe command from Win95 (wow!)\n"));
- return api_fd_reply(conn,vuid,outbuf,setup,data,params,suwcnt,tdscnt,tpscnt,mdrcnt,mprcnt);
+ DEBUG(4, ("named pipe command from Win95 (wow!)\n"));
+ return api_fd_reply(conn, vuid, outbuf, setup, data, params,
+ suwcnt, tdscnt, tpscnt, mdrcnt, mprcnt);
}
if (strlen(name) < 1)
{
- return api_fd_reply(conn,vuid,outbuf,setup,data,params,suwcnt,tdscnt,tpscnt,mdrcnt,mprcnt);
+ return api_fd_reply(conn, vuid, outbuf, setup, data, params,
+ suwcnt, tdscnt, tpscnt, mdrcnt, mprcnt);
}
if (setup)
{
- DEBUG(3,("unknown named pipe: setup 0x%X setup1=%d\n", (int)setup[0],(int)setup[1]));
+ DEBUG(3,
+ ("unknown named pipe: setup 0x%X setup1=%d\n",
+ (int)setup[0], (int)setup[1]));
}
return 0;
/****************************************************************************
reply to a SMBtrans
****************************************************************************/
-int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int bufsize)
+int reply_trans(connection_struct * conn, char *inbuf, char *outbuf, int size,
+ int bufsize)
{
fstring name;
- int name_offset = 0;
- char *data=NULL,*params=NULL;
- uint16 *setup=NULL;
+ int name_offset = 0;
+ char *data = NULL, *params = NULL;
+ uint16 *setup = NULL;
int outsize = 0;
- uint16 vuid = SVAL(inbuf,smb_uid);
- int tpscnt = SVAL(inbuf,smb_vwv0);
- int tdscnt = SVAL(inbuf,smb_vwv1);
- int mprcnt = SVAL(inbuf,smb_vwv2);
- int mdrcnt = SVAL(inbuf,smb_vwv3);
- int msrcnt = CVAL(inbuf,smb_vwv4);
- BOOL close_on_completion = BITSETW(inbuf+smb_vwv5,0);
- BOOL one_way = BITSETW(inbuf+smb_vwv5,1);
- int pscnt = SVAL(inbuf,smb_vwv9);
- int psoff = SVAL(inbuf,smb_vwv10);
- int dscnt = SVAL(inbuf,smb_vwv11);
- int dsoff = SVAL(inbuf,smb_vwv12);
- int suwcnt = CVAL(inbuf,smb_vwv13);
+ uint16 vuid = SVAL(inbuf, smb_uid);
+ int tpscnt = SVAL(inbuf, smb_vwv0);
+ int tdscnt = SVAL(inbuf, smb_vwv1);
+ int mprcnt = SVAL(inbuf, smb_vwv2);
+ int mdrcnt = SVAL(inbuf, smb_vwv3);
+ int msrcnt = CVAL(inbuf, smb_vwv4);
+ BOOL close_on_completion = BITSETW(inbuf + smb_vwv5, 0);
+ BOOL one_way = BITSETW(inbuf + smb_vwv5, 1);
+ int pscnt = SVAL(inbuf, smb_vwv9);
+ int psoff = SVAL(inbuf, smb_vwv10);
+ int dscnt = SVAL(inbuf, smb_vwv11);
+ int dsoff = SVAL(inbuf, smb_vwv12);
+ int suwcnt = CVAL(inbuf, smb_vwv13);
ZERO_STRUCT(name);
- fstrcpy(name,smb_buf(inbuf));
+ fstrcpy(name, smb_buf(inbuf));
- if (dscnt > tdscnt || pscnt > tpscnt) {
+ if (dscnt > tdscnt || pscnt > tpscnt)
+ {
exit_server("invalid trans parameters\n");
}
-
- if (tdscnt) {
- if((data = (char *)malloc(tdscnt)) == NULL) {
- DEBUG(0,("reply_trans: data malloc fail for %d bytes !\n", tdscnt));
- return(ERROR(ERRDOS,ERRnomem));
- }
- memcpy(data,smb_base(inbuf)+dsoff,dscnt);
+
+ if (tdscnt)
+ {
+ if ((data = (char *)malloc(tdscnt)) == NULL)
+ {
+ DEBUG(0,
+ ("reply_trans: data malloc fail for %d bytes !\n",
+ tdscnt));
+ return (ERROR(ERRDOS, ERRnomem));
+ }
+ memcpy(data, smb_base(inbuf) + dsoff, dscnt);
}
- if (tpscnt) {
- if((params = (char *)malloc(tpscnt)) == NULL) {
- DEBUG(0,("reply_trans: param malloc fail for %d bytes !\n", tpscnt));
- return(ERROR(ERRDOS,ERRnomem));
- }
- memcpy(params,smb_base(inbuf)+psoff,pscnt);
+ if (tpscnt)
+ {
+ if ((params = (char *)malloc(tpscnt)) == NULL)
+ {
+ DEBUG(0,
+ ("reply_trans: param malloc fail for %d bytes !\n",
+ tpscnt));
+ return (ERROR(ERRDOS, ERRnomem));
+ }
+ memcpy(params, smb_base(inbuf) + psoff, pscnt);
}
- if (suwcnt) {
+ if (suwcnt)
+ {
int i;
- if((setup = (uint16 *)malloc(suwcnt*sizeof(uint16))) == NULL) {
- DEBUG(0,("reply_trans: setup malloc fail for %d bytes !\n", suwcnt * sizeof(uint16)));
- return(ERROR(ERRDOS,ERRnomem));
- }
- for (i=0;i<suwcnt;i++)
- setup[i] = SVAL(inbuf,smb_vwv14+i*SIZEOFWORD);
+ if ((setup = (uint16 *)malloc(suwcnt * sizeof(uint16))) ==
+ NULL)
+ {
+ DEBUG(0,
+ ("reply_trans: setup malloc fail for %d bytes !\n",
+ suwcnt * sizeof(uint16)));
+ return (ERROR(ERRDOS, ERRnomem));
+ }
+ for (i = 0; i < suwcnt; i++)
+ setup[i] = SVAL(inbuf, smb_vwv14 + i * SIZEOFWORD);
}
- if (pscnt < tpscnt || dscnt < tdscnt) {
+ if (pscnt < tpscnt || dscnt < tdscnt)
+ {
/* We need to send an interim response then receive the rest
of the parameter/data bytes */
- outsize = set_message(outbuf,0,0,True);
+ outsize = set_message(outbuf, 0, 0, True);
show_msg(outbuf);
- send_smb(Client,outbuf);
+ send_smb(Client, outbuf);
}
/* receive the rest of the trans packet */
- while (pscnt < tpscnt || dscnt < tdscnt) {
+ while (pscnt < tpscnt || dscnt < tdscnt)
+ {
BOOL ret;
- int pcnt,poff,dcnt,doff,pdisp,ddisp;
-
- ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
+ int pcnt, poff, dcnt, doff, pdisp, ddisp;
+
+ ret = receive_next_smb(inbuf, bufsize, SMB_SECONDARY_WAIT);
show_msg(inbuf);
-
+
if ((ret && (CVAL(inbuf, smb_com) != SMBtrans &&
- CVAL(inbuf, smb_com) != SMBtranss)) || !ret)
+ CVAL(inbuf, smb_com) != SMBtranss)) || !ret)
{
- if(ret) {
- DEBUG(0,("reply_trans: Invalid secondary trans packet\n"));
- } else {
- DEBUG(0,("reply_trans: %s in getting secondary trans response.\n",
- (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
+ if (ret)
+ {
+ DEBUG(0,
+ ("reply_trans: Invalid secondary trans packet\n"));
}
- if (params) free(params);
- if (data) free(data);
- if (setup) free(setup);
- return(ERROR(ERRSRV,ERRerror));
+ else
+ {
+ DEBUG(0,
+ ("reply_trans: %s in getting secondary trans response.\n",
+ (smb_read_error ==
+ READ_ERROR) ? "error" : "timeout"));
+ }
+ if (params)
+ free(params);
+ if (data)
+ free(data);
+ if (setup)
+ free(setup);
+ return (ERROR(ERRSRV, ERRerror));
}
- tpscnt = SVAL(inbuf,smb_vwv0);
- tdscnt = SVAL(inbuf,smb_vwv1);
-
- pcnt = SVAL(inbuf,smb_vwv2);
- poff = SVAL(inbuf,smb_vwv3);
- pdisp = SVAL(inbuf,smb_vwv4);
-
- dcnt = SVAL(inbuf,smb_vwv5);
- doff = SVAL(inbuf,smb_vwv6);
- ddisp = SVAL(inbuf,smb_vwv7);
-
+ tpscnt = SVAL(inbuf, smb_vwv0);
+ tdscnt = SVAL(inbuf, smb_vwv1);
+
+ pcnt = SVAL(inbuf, smb_vwv2);
+ poff = SVAL(inbuf, smb_vwv3);
+ pdisp = SVAL(inbuf, smb_vwv4);
+
+ dcnt = SVAL(inbuf, smb_vwv5);
+ doff = SVAL(inbuf, smb_vwv6);
+ ddisp = SVAL(inbuf, smb_vwv7);
+
pscnt += pcnt;
dscnt += dcnt;
-
- if (dscnt > tdscnt || pscnt > tpscnt) {
+
+ if (dscnt > tdscnt || pscnt > tpscnt)
+ {
exit_server("invalid trans parameters\n");
}
-
+
if (pcnt)
- memcpy(params+pdisp,smb_base(inbuf)+poff,pcnt);
+ memcpy(params + pdisp, smb_base(inbuf) + poff, pcnt);
if (dcnt)
- memcpy(data+ddisp,smb_base(inbuf)+doff,dcnt);
+ memcpy(data + ddisp, smb_base(inbuf) + doff, dcnt);
+ }
+
+
+ DEBUG(3, ("trans <%s> data=%d params=%d setup=%d\n",
+ name, tdscnt, tpscnt, suwcnt));
+
+ /*
+ * WinCE wierdness....
+ */
+
+ if (name[0] == '\\' && (StrnCaseCmp(&name[1], local_machine,
+ strlen(local_machine)) == 0))
+ {
+ name_offset = strlen(local_machine) + 1;
}
-
-
- DEBUG(3,("trans <%s> data=%d params=%d setup=%d\n",
- name,tdscnt,tpscnt,suwcnt));
-
- /*
- * WinCE wierdness....
- */
-
- if (name[0] == '\\' && (StrnCaseCmp(&name[1],local_machine,
- strlen(local_machine)) == 0)) {
- name_offset = strlen(local_machine)+1;
- }
-
- if (strncmp(&name[name_offset],"\\PIPE\\",strlen("\\PIPE\\")) == 0) {
- DEBUG(5,("calling named_pipe\n"));
- outsize = named_pipe(conn,vuid,outbuf,
- name+name_offset+strlen("\\PIPE\\"),setup,data,params,
- suwcnt,tdscnt,tpscnt,msrcnt,mdrcnt,mprcnt);
- } else {
- DEBUG(3,("invalid pipe name\n"));
+
+ if (strncmp(&name[name_offset], "\\PIPE\\", strlen("\\PIPE\\")) == 0)
+ {
+ DEBUG(5, ("calling named_pipe\n"));
+ outsize = named_pipe(conn, vuid, outbuf,
+ name + name_offset + strlen("\\PIPE\\"),
+ setup, data, params, suwcnt, tdscnt,
+ tpscnt, msrcnt, mdrcnt, mprcnt);
+ }
+ else
+ {
+ DEBUG(3, ("invalid pipe name\n"));
outsize = 0;
}
-
- if (data) free(data);
- if (params) free(params);
- if (setup) free(setup);
-
+
+ if (data)
+ free(data);
+ if (params)
+ free(params);
+ if (setup)
+ free(setup);
+
if (close_on_completion)
- close_cnum(conn,vuid);
+ close_cnum(conn, vuid);
if (one_way)
- return(-1);
-
+ return (-1);
+
if (outsize == 0)
- return(ERROR(ERRSRV,ERRnosupport));
-
- return(outsize);
+ return (ERROR(ERRSRV, ERRnosupport));
+
+ return (outsize);
}
/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Inter-process communication and named pipe handling
- Copyright (C) Andrew Tridgell 1992-2000
-
- SMB Version handling
- Copyright (C) John H Terpstra 1995-2000
-
- Copyright (C) Luke Kenneth Casson Leighton 1996-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.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Inter-process communication and named pipe handling
+ Copyright (C) Andrew Tridgell 1992-2000
+
+ SMB Version handling
+ Copyright (C) John H Terpstra 1995-2000
+
+ Copyright (C) Luke Kenneth Casson Leighton 1996-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.
*/
/*
This file handles the named pipe and mailslot calls
#define CHECK_TYPES 0
extern int DEBUGLEVEL;
+extern int max_send;
extern fstring local_machine;
extern fstring global_myworkgroup;
extern int Client;
extern int smb_read_error;
-extern uint32 global_client_caps;
-static BOOL api_Unsupported(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len);
-static BOOL api_TooSmall(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len);
+static BOOL api_Unsupported(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt, int mprcnt,
+ char **rdata, char **rparam, int *rdata_len,
+ int *rparam_len);
+static BOOL api_TooSmall(connection_struct * conn, uint16 vuid, char *param,
+ char *data, int mdrcnt, int mprcnt, char **rdata,
+ char **rparam, int *rdata_len, int *rparam_len);
-static int CopyExpanded(connection_struct *conn, const vuser_key *key,
- int snum, char** dst, char* src, int* n)
+static int CopyExpanded(connection_struct * conn, const vuser_key * key,
+ int snum, char **dst, char *src, int *n)
{
pstring buf;
int l;
user_struct *vuser;
- if (!src || !dst || !n || !(*dst)) return(0);
+ if (!src || !dst || !n || !(*dst))
+ return (0);
- StrnCpy(buf,src,sizeof(buf)/2);
- string_sub(buf,"%S",lp_servicename(snum));
+ StrnCpy(buf, src, sizeof(buf) / 2);
+ pstring_sub(buf, "%S", lp_servicename(snum));
vuser = get_valid_user_struct(key);
- standard_sub(conn,vuser, buf);
+ standard_sub(conn, vuser, buf);
vuid_free_user_struct(vuser);
- StrnCpy(*dst,buf,*n);
+ StrnCpy(*dst, buf, *n);
l = strlen(*dst) + 1;
(*dst) += l;
(*n) -= l;
return l;
}
-static int CopyAndAdvance(char** dst, char* src, int* n)
+static int CopyAndAdvance(char **dst, char *src, int *n)
{
- int l;
- if (!src || !dst || !n || !(*dst)) return(0);
- StrnCpy(*dst,src,*n);
- l = strlen(*dst) + 1;
- (*dst) += l;
- (*n) -= l;
- return l;
+ int l;
+ if (!src || !dst || !n || !(*dst))
+ return (0);
+ StrnCpy(*dst, src, *n - 1);
+ l = strlen(*dst) + 1;
+ (*dst) += l;
+ (*n) -= l;
+ return l;
}
-static int StrlenExpanded(connection_struct *conn,
- const vuser_key *key, int snum, char* s)
+static int StrlenExpanded(connection_struct * conn,
+ const vuser_key * key, int snum, char *s)
{
user_struct *vuser;
pstring buf;
- if (!s) return(0);
- StrnCpy(buf,s,sizeof(buf)/2);
- string_sub(buf,"%S",lp_servicename(snum));
+ if (!s)
+ return (0);
+ StrnCpy(buf, s, sizeof(buf) / 2);
+ pstring_sub(buf, "%S", lp_servicename(snum));
vuser = get_valid_user_struct(key);
- standard_sub(conn,vuser, buf);
+ standard_sub(conn, vuser, buf);
vuid_free_user_struct(vuser);
return strlen(buf) + 1;
}
-static char* Expand(connection_struct *conn, const vuser_key *key, int snum, char* s)
+static char *Expand(connection_struct * conn, const vuser_key * key, int snum,
+ char *s)
{
user_struct *vuser;
static pstring buf;
- if (!s) return(NULL);
- StrnCpy(buf,s,sizeof(buf)/2);
- string_sub(buf,"%S",lp_servicename(snum));
+ if (!s)
+ return (NULL);
+ StrnCpy(buf, s, sizeof(buf) / 2);
+ pstring_sub(buf, "%S", lp_servicename(snum));
vuser = get_valid_user_struct(key);
- standard_sub(conn,vuser, buf);
+ standard_sub(conn, vuser, buf);
return &buf[0];
}
/*******************************************************************
check a API string for validity when we only need to check the prefix
******************************************************************/
-static BOOL prefix_ok(char *str,char *prefix)
+static BOOL prefix_ok(char *str, char *prefix)
{
- return(strncmp(str,prefix,strlen(prefix)) == 0);
+ return (strncmp(str, prefix, strlen(prefix)) == 0);
}
-struct pack_desc {
- char* format; /* formatstring for structure */
- char* subformat; /* subformat for structure */
- char* base; /* baseaddress of buffer */
- int buflen; /* remaining size for fixed part; on init: length of base */
- int subcount; /* count of substructures */
- char* structbuf; /* pointer into buffer for remaining fixed part */
- int stringlen; /* remaining size for variable part */
- char* stringbuf; /* pointer into buffer for remaining variable part */
- int neededlen; /* total needed size */
- int usedlen; /* total used size (usedlen <= neededlen and usedlen <= buflen) */
- char* curpos; /* current position; pointer into format or subformat */
- int errcode;
+struct pack_desc
+{
+ char *format; /* formatstring for structure */
+ char *subformat; /* subformat for structure */
+ char *base; /* baseaddress of buffer */
+ int buflen; /* remaining size for fixed part; on init: length of base */
+ int subcount; /* count of substructures */
+ char *structbuf; /* pointer into buffer for remaining fixed part */
+ int stringlen; /* remaining size for variable part */
+ char *stringbuf; /* pointer into buffer for remaining variable part */
+ int neededlen; /* total needed size */
+ int usedlen; /* total used size (usedlen <= neededlen and usedlen <= buflen) */
+ char *curpos; /* current position; pointer into format or subformat */
+ int errcode;
};
-static int get_counter(char** p)
+static int get_counter(char **p)
{
- int i, n;
- if (!p || !(*p)) return(1);
- if (!isdigit((int)**p)) return 1;
- for (n = 0;;) {
- i = **p;
- if (isdigit(i))
- n = 10 * n + (i - '0');
- else
- return n;
- (*p)++;
- }
+ int i, n;
+ if (!p || !(*p))
+ return (1);
+ if (!isdigit((int)**p))
+ return 1;
+ for (n = 0;;)
+ {
+ i = **p;
+ if (isdigit(i))
+ n = 10 * n + (i - '0');
+ else
+ return n;
+ (*p)++;
+ }
}
-static int getlen(char* p)
+static int getlen(char *p)
{
- int n = 0;
- if (!p) return(0);
- while (*p) {
- switch( *p++ ) {
- case 'W': /* word (2 byte) */
- n += 2;
- break;
- case 'N': /* count of substructures (word) at end */
- n += 2;
- break;
- case 'D': /* double word (4 byte) */
- case 'z': /* offset to zero terminated string (4 byte) */
- case 'l': /* offset to user data (4 byte) */
- n += 4;
- break;
- case 'b': /* offset to data (with counter) (4 byte) */
- n += 4;
- get_counter(&p);
- break;
- case 'B': /* byte (with optional counter) */
- n += get_counter(&p);
- break;
- }
- }
- return n;
+ int n = 0;
+ if (!p)
+ return (0);
+ while (*p)
+ {
+ switch (*p++)
+ {
+ case 'W': /* word (2 byte) */
+ n += 2;
+ break;
+ case 'N': /* count of substructures (word) at end */
+ n += 2;
+ break;
+ case 'D': /* double word (4 byte) */
+ case 'z': /* offset to zero terminated string (4 byte) */
+ case 'l': /* offset to user data (4 byte) */
+ n += 4;
+ break;
+ case 'b': /* offset to data (with counter) (4 byte) */
+ n += 4;
+ get_counter(&p);
+ break;
+ case 'B': /* byte (with optional counter) */
+ n += get_counter(&p);
+ break;
+ }
+ }
+ return n;
}
-static BOOL init_package(struct pack_desc* p, int count, int subcount)
+static BOOL init_package(struct pack_desc *p, int count, int subcount)
{
- int n = p->buflen;
- int i;
-
- if (!p->format || !p->base) return(False);
-
- i = count * getlen(p->format);
- if (p->subformat) i += subcount * getlen(p->subformat);
- p->structbuf = p->base;
- p->neededlen = 0;
- p->usedlen = 0;
- p->subcount = 0;
- p->curpos = p->format;
- if (i > n) {
- p->neededlen = i;
- i = n = 0;
- p->errcode = ERRmoredata;
- }
- else
- p->errcode = NERR_Success;
- p->buflen = i;
- n -= i;
- p->stringbuf = p->base + i;
- p->stringlen = n;
- return(p->errcode == NERR_Success);
+ int n = p->buflen;
+ int i;
+
+ if (!p->format || !p->base)
+ return (False);
+
+ i = count * getlen(p->format);
+ if (p->subformat)
+ i += subcount * getlen(p->subformat);
+ p->structbuf = p->base;
+ p->neededlen = 0;
+ p->usedlen = 0;
+ p->subcount = 0;
+ p->curpos = p->format;
+ if (i > n)
+ {
+ p->neededlen = i;
+ i = n = 0;
+ p->errcode = ERRmoredata;
+ }
+ else
+ p->errcode = NERR_Success;
+ p->buflen = i;
+ n -= i;
+ p->stringbuf = p->base + i;
+ p->stringlen = n;
+ return (p->errcode == NERR_Success);
}
#ifdef HAVE_STDARG_H
-static int package(struct pack_desc* p, ...)
+static int package(struct pack_desc *p, ...)
{
#else
static int package(va_alist)
-va_dcl
+ va_dcl
{
- struct pack_desc* p;
+ struct pack_desc *p;
#endif
- va_list args;
- int needed=0, stringneeded;
- char* str=NULL;
- int is_string=0, stringused;
- int32 temp;
+ va_list args;
+ int needed = 0, stringneeded;
+ char *str = NULL;
+ int is_string = 0, stringused;
+ int32 temp;
#ifdef HAVE_STDARG_H
- va_start(args,p);
+ va_start(args, p);
#else
- va_start(args);
- p = va_arg(args,struct pack_desc *);
+ va_start(args);
+ p = va_arg(args, struct pack_desc *);
#endif
- if (!*p->curpos) {
- if (!p->subcount)
- p->curpos = p->format;
- else {
- p->curpos = p->subformat;
- p->subcount--;
- }
- }
+ if (!*p->curpos)
+ {
+ if (!p->subcount)
+ p->curpos = p->format;
+ else
+ {
+ p->curpos = p->subformat;
+ p->subcount--;
+ }
+ }
#if CHECK_TYPES
- str = va_arg(args,char*);
- SMB_ASSERT(strncmp(str,p->curpos,strlen(str)) == 0);
+ str = va_arg(args, char *);
+ SMB_ASSERT(strncmp(str, p->curpos, strlen(str)) == 0);
#endif
- stringneeded = -1;
-
- if (!p->curpos) return(0);
-
- switch( *p->curpos++ ) {
- case 'W': /* word (2 byte) */
- needed = 2;
- temp = va_arg(args,int);
- if (p->buflen >= needed) SSVAL(p->structbuf,0,temp);
- break;
- case 'N': /* count of substructures (word) at end */
- needed = 2;
- p->subcount = va_arg(args,int);
- if (p->buflen >= needed) SSVAL(p->structbuf,0,p->subcount);
- break;
- case 'D': /* double word (4 byte) */
- needed = 4;
- temp = va_arg(args,int);
- if (p->buflen >= needed) SIVAL(p->structbuf,0,temp);
- break;
- case 'B': /* byte (with optional counter) */
- needed = get_counter(&p->curpos);
- {
- char *s = va_arg(args,char*);
- if (p->buflen >= needed) StrnCpy(p->structbuf,s?s:"",needed);
- }
- break;
- case 'z': /* offset to zero terminated string (4 byte) */
- str = va_arg(args,char*);
- stringneeded = (str ? strlen(str)+1 : 0);
- is_string = 1;
- break;
- case 'l': /* offset to user data (4 byte) */
- str = va_arg(args,char*);
- stringneeded = va_arg(args,int);
- is_string = 0;
- break;
- case 'b': /* offset to data (with counter) (4 byte) */
- str = va_arg(args,char*);
- stringneeded = get_counter(&p->curpos);
- is_string = 0;
- break;
- }
- va_end(args);
- if (stringneeded >= 0) {
- needed = 4;
- if (p->buflen >= needed) {
- stringused = stringneeded;
- if (stringused > p->stringlen) {
- stringused = (is_string ? p->stringlen : 0);
- if (p->errcode == NERR_Success) p->errcode = ERRmoredata;
- }
- if (!stringused)
- SIVAL(p->structbuf,0,0);
- else {
- SIVAL(p->structbuf,0,PTR_DIFF(p->stringbuf,p->base));
- memcpy(p->stringbuf,str?str:"",stringused);
- if (is_string) p->stringbuf[stringused-1] = '\0';
- p->stringbuf += stringused;
- p->stringlen -= stringused;
- p->usedlen += stringused;
- }
- }
- p->neededlen += stringneeded;
- }
- p->neededlen += needed;
- if (p->buflen >= needed) {
- p->structbuf += needed;
- p->buflen -= needed;
- p->usedlen += needed;
- }
- else {
- if (p->errcode == NERR_Success) p->errcode = ERRmoredata;
- }
- return 1;
+ stringneeded = -1;
+
+ if (!p->curpos)
+ {
+ va_end(args);
+ return (0);
+ }
+
+ switch (*p->curpos++)
+ {
+ case 'W': /* word (2 byte) */
+ needed = 2;
+ temp = va_arg(args, int);
+ if (p->buflen >= needed)
+ SSVAL(p->structbuf, 0, temp);
+ break;
+ case 'N': /* count of substructures (word) at end */
+ needed = 2;
+ p->subcount = va_arg(args, int);
+ if (p->buflen >= needed)
+ SSVAL(p->structbuf, 0, p->subcount);
+ break;
+ case 'D': /* double word (4 byte) */
+ needed = 4;
+ temp = va_arg(args, int);
+ if (p->buflen >= needed)
+ SIVAL(p->structbuf, 0, temp);
+ break;
+ case 'B': /* byte (with optional counter) */
+ needed = get_counter(&p->curpos);
+ {
+ char *s = va_arg(args, char *);
+ if (p->buflen >= needed)
+ StrnCpy(p->structbuf, s ? s : "",
+ needed - 1);
+ }
+ break;
+ case 'z': /* offset to zero terminated string (4 byte) */
+ str = va_arg(args, char *);
+ stringneeded = (str ? strlen(str) + 1 : 0);
+ is_string = 1;
+ break;
+ case 'l': /* offset to user data (4 byte) */
+ str = va_arg(args, char *);
+ stringneeded = va_arg(args, int);
+ is_string = 0;
+ break;
+ case 'b': /* offset to data (with counter) (4 byte) */
+ str = va_arg(args, char *);
+ stringneeded = get_counter(&p->curpos);
+ is_string = 0;
+ break;
+ }
+ va_end(args);
+ if (stringneeded >= 0)
+ {
+ needed = 4;
+ if (p->buflen >= needed)
+ {
+ stringused = stringneeded;
+ if (stringused > p->stringlen)
+ {
+ stringused = (is_string ? p->stringlen : 0);
+ if (p->errcode == NERR_Success)
+ p->errcode = ERRmoredata;
+ }
+ if (!stringused)
+ SIVAL(p->structbuf, 0, 0);
+ else
+ {
+ SIVAL(p->structbuf, 0,
+ PTR_DIFF(p->stringbuf, p->base));
+ memcpy(p->stringbuf, str ? str : "",
+ stringused);
+ if (is_string)
+ p->stringbuf[stringused - 1] = '\0';
+ p->stringbuf += stringused;
+ p->stringlen -= stringused;
+ p->usedlen += stringused;
+ }
+ }
+ p->neededlen += stringneeded;
+ }
+ p->neededlen += needed;
+ if (p->buflen >= needed)
+ {
+ p->structbuf += needed;
+ p->buflen -= needed;
+ p->usedlen += needed;
+ }
+ else
+ {
+ if (p->errcode == NERR_Success)
+ p->errcode = ERRmoredata;
+ }
+ return 1;
}
#if CHECK_TYPES
#define PACKl(desc,t,v,l) package(desc,v,l)
#endif
-static void PACKI(struct pack_desc* desc,char *t,int v)
+static void PACKI(struct pack_desc *desc, char *t, int v)
{
- PACK(desc,t,v);
+ PACK(desc, t, v);
}
-static void PACKS(struct pack_desc* desc,char *t,char *v)
+static void PACKS(struct pack_desc *desc, char *t, char *v)
{
- PACK(desc,t,v);
+ PACK(desc, t, v);
}
get a print queue
****************************************************************************/
-static void PackDriverData(struct pack_desc* desc)
+static void PackDriverData(struct pack_desc *desc)
{
- char drivdata[4+4+32];
- SIVAL(drivdata,0,sizeof drivdata); /* cb */
- SIVAL(drivdata,4,1000); /* lVersion */
- memset(drivdata+8,0,32); /* szDeviceName */
- pstrcpy(drivdata+8,"NULL");
- PACKl(desc,"l",drivdata,sizeof drivdata); /* pDriverData */
+ char drivdata[4 + 4 + 32];
+ SIVAL(drivdata, 0, sizeof drivdata); /* cb */
+ SIVAL(drivdata, 4, 1000); /* lVersion */
+ memset(drivdata + 8, 0, 32); /* szDeviceName */
+ pstrcpy(drivdata + 8, "NULL");
+ PACKl(desc, "l", drivdata, sizeof drivdata); /* pDriverData */
}
-static int check_printq_info(struct pack_desc* desc,
- int uLevel, char *id1, char *id2)
+static int check_printq_info(struct pack_desc *desc,
+ int uLevel, char *id1, char *id2)
{
- desc->subformat = NULL;
- switch( uLevel ) {
- case 0:
- desc->format = "B13";
- break;
- case 1:
- desc->format = "B13BWWWzzzzzWW";
- break;
- case 2:
- desc->format = "B13BWWWzzzzzWN";
- desc->subformat = "WB21BB16B10zWWzDDz";
- break;
- case 3:
- desc->format = "zWWWWzzzzWWzzl";
- break;
- case 4:
- desc->format = "zWWWWzzzzWNzzl";
- desc->subformat = "WWzWWDDzz";
- break;
- case 5:
- desc->format = "z";
- break;
- case 52:
- desc->format = "WzzzzzzzzN";
- desc->subformat = "z";
- break;
- default: return False;
- }
- if (strcmp(desc->format,id1) != 0) return False;
- if (desc->subformat && strcmp(desc->subformat,id2) != 0) return False;
- return True;
+ desc->subformat = NULL;
+ switch (uLevel)
+ {
+ case 0:
+ desc->format = "B13";
+ break;
+ case 1:
+ desc->format = "B13BWWWzzzzzWW";
+ break;
+ case 2:
+ desc->format = "B13BWWWzzzzzWN";
+ desc->subformat = "WB21BB16B10zWWzDDz";
+ break;
+ case 3:
+ desc->format = "zWWWWzzzzWWzzl";
+ break;
+ case 4:
+ desc->format = "zWWWWzzzzWNzzl";
+ desc->subformat = "WWzWWDDzz";
+ break;
+ case 5:
+ desc->format = "z";
+ break;
+ case 52:
+ desc->format = "WzzzzzzzzN";
+ desc->subformat = "z";
+ break;
+ default:
+ return False;
+ }
+ if (strcmp(desc->format, id1) != 0)
+ return False;
+ if (desc->subformat && strcmp(desc->subformat, id2) != 0)
+ return False;
+ return True;
}
-static void fill_printjob_info(connection_struct *conn,
- int snum, int uLevel,
- struct pack_desc* desc,
- print_queue_struct* queue, int n)
+static void fill_printjob_info(connection_struct * conn, int snum, int uLevel,
+ struct pack_desc *desc,
+ print_queue_struct * queue, int n)
{
- time_t t = queue->time;
-
- /* the client expects localtime */
- t -= TimeDiff(t);
-
- PACKI(desc,"W",printjob_encode(snum, queue->job)); /* uJobId */
- if (uLevel == 1) {
- PACKS(desc,"B21",queue->user); /* szUserName */
- PACKS(desc,"B",""); /* pad */
- PACKS(desc,"B16",""); /* szNotifyName */
- PACKS(desc,"B10","PM_Q_RAW"); /* szDataType */
- PACKS(desc,"z",""); /* pszParms */
- PACKI(desc,"W",n+1); /* uPosition */
- PACKI(desc,"W",queue->status); /* fsStatus */
- PACKS(desc,"z",""); /* pszStatus */
- PACKI(desc,"D",t); /* ulSubmitted */
- PACKI(desc,"D",queue->size); /* ulSize */
- PACKS(desc,"z",queue->file); /* pszComment */
- }
- if (uLevel == 2 || uLevel == 3) {
- PACKI(desc,"W",queue->priority); /* uPriority */
- PACKS(desc,"z",queue->user); /* pszUserName */
- PACKI(desc,"W",n+1); /* uPosition */
- PACKI(desc,"W",queue->status); /* fsStatus */
- PACKI(desc,"D",t); /* ulSubmitted */
- PACKI(desc,"D",queue->size); /* ulSize */
- PACKS(desc,"z","Samba"); /* pszComment */
- PACKS(desc,"z",queue->file); /* pszDocument */
- if (uLevel == 3) {
- PACKS(desc,"z",""); /* pszNotifyName */
- PACKS(desc,"z","PM_Q_RAW"); /* pszDataType */
- PACKS(desc,"z",""); /* pszParms */
- PACKS(desc,"z",""); /* pszStatus */
- PACKS(desc,"z",SERVICE(snum)); /* pszQueue */
- PACKS(desc,"z","lpd"); /* pszQProcName */
- PACKS(desc,"z",""); /* pszQProcParms */
- PACKS(desc,"z","NULL"); /* pszDriverName */
- PackDriverData(desc); /* pDriverData */
- PACKS(desc,"z",""); /* pszPrinterName */
- }
- }
+ time_t t = queue->time;
+
+ /* the client expects localtime */
+ t -= TimeDiff(t);
+
+ PACKI(desc, "W", printjob_encode(snum, queue->job)); /* uJobId */
+ if (uLevel == 1)
+ {
+ PACKS(desc, "B21", queue->user); /* szUserName */
+ PACKS(desc, "B", ""); /* pad */
+ PACKS(desc, "B16", ""); /* szNotifyName */
+ PACKS(desc, "B10", "PM_Q_RAW"); /* szDataType */
+ PACKS(desc, "z", ""); /* pszParms */
+ PACKI(desc, "W", n + 1); /* uPosition */
+ PACKI(desc, "W", queue->status); /* fsStatus */
+ PACKS(desc, "z", ""); /* pszStatus */
+ PACKI(desc, "D", t); /* ulSubmitted */
+ PACKI(desc, "D", queue->size); /* ulSize */
+ PACKS(desc, "z", queue->file); /* pszComment */
+ }
+ if (uLevel == 2 || uLevel == 3)
+ {
+ PACKI(desc, "W", queue->priority); /* uPriority */
+ PACKS(desc, "z", queue->user); /* pszUserName */
+ PACKI(desc, "W", n + 1); /* uPosition */
+ PACKI(desc, "W", queue->status); /* fsStatus */
+ PACKI(desc, "D", t); /* ulSubmitted */
+ PACKI(desc, "D", queue->size); /* ulSize */
+ PACKS(desc, "z", "Samba"); /* pszComment */
+ PACKS(desc, "z", queue->file); /* pszDocument */
+ if (uLevel == 3)
+ {
+ PACKS(desc, "z", ""); /* pszNotifyName */
+ PACKS(desc, "z", "PM_Q_RAW"); /* pszDataType */
+ PACKS(desc, "z", ""); /* pszParms */
+ PACKS(desc, "z", ""); /* pszStatus */
+ PACKS(desc, "z", SERVICE(snum)); /* pszQueue */
+ PACKS(desc, "z", "lpd"); /* pszQProcName */
+ PACKS(desc, "z", ""); /* pszQProcParms */
+ PACKS(desc, "z", "NULL"); /* pszDriverName */
+ PackDriverData(desc); /* pDriverData */
+ PACKS(desc, "z", ""); /* pszPrinterName */
+ }
+ }
}
-static void fill_printq_info(connection_struct *conn, const vuser_key *key,
- int snum, int uLevel,
- struct pack_desc* desc,
- int count, print_queue_struct* queue,
- print_status_struct* status)
+static void fill_printq_info(connection_struct * conn, const vuser_key * key,
+ int snum, int uLevel, struct pack_desc *desc,
+ int count, print_queue_struct * queue,
+ print_status_struct * status)
{
- switch (uLevel) {
- case 1:
- case 2:
- PACKS(desc,"B13",SERVICE(snum));
- break;
- case 3:
- case 4:
- case 5:
- PACKS(desc,"z",Expand(conn,key, snum,SERVICE(snum)));
- break;
- }
-
- if (uLevel == 1 || uLevel == 2) {
- PACKS(desc,"B",""); /* alignment */
- PACKI(desc,"W",5); /* priority */
- PACKI(desc,"W",0); /* start time */
- PACKI(desc,"W",0); /* until time */
- PACKS(desc,"z",""); /* pSepFile */
- PACKS(desc,"z","lpd"); /* pPrProc */
- PACKS(desc,"z",SERVICE(snum)); /* pDestinations */
- PACKS(desc,"z",""); /* pParms */
- if (snum < 0) {
- PACKS(desc,"z","UNKNOWN PRINTER");
- PACKI(desc,"W",LPSTAT_ERROR);
- }
- else if (!status || !status->message[0]) {
- PACKS(desc,"z",Expand(conn,key, snum,lp_comment(snum)));
- PACKI(desc,"W",LPSTAT_OK); /* status */
- } else {
- PACKS(desc,"z",status->message);
- PACKI(desc,"W",status->status); /* status */
- }
- PACKI(desc,(uLevel == 1 ? "W" : "N"),count);
- }
- if (uLevel == 3 || uLevel == 4) {
- PACKI(desc,"W",5); /* uPriority */
- PACKI(desc,"W",0); /* uStarttime */
- PACKI(desc,"W",0); /* uUntiltime */
- PACKI(desc,"W",5); /* pad1 */
- PACKS(desc,"z",""); /* pszSepFile */
- PACKS(desc,"z","WinPrint"); /* pszPrProc */
- PACKS(desc,"z",""); /* pszParms */
- if (!status || !status->message[0]) {
- PACKS(desc,"z",Expand(conn,key, snum,lp_comment(snum))); /* pszComment */
- PACKI(desc,"W",LPSTAT_OK); /* fsStatus */
- } else {
- PACKS(desc,"z",status->message); /* pszComment */
- PACKI(desc,"W",status->status); /* fsStatus */
- }
- PACKI(desc,(uLevel == 3 ? "W" : "N"),count); /* cJobs */
- PACKS(desc,"z",SERVICE(snum)); /* pszPrinters */
- PACKS(desc,"z",lp_printerdriver(snum)); /* pszDriverName */
- PackDriverData(desc); /* pDriverData */
- }
- if (uLevel == 2 || uLevel == 4) {
- int i;
- for (i=0;i<count;i++)
- fill_printjob_info(conn,snum,uLevel == 2 ? 1 : 2,desc,&queue[i],i);
- }
-
- if (uLevel==52) {
- int i,ok=0;
- pstring tok,driver,datafile,langmon,helpfile,datatype;
- char *p,*q;
- FILE *f;
- pstring fname;
-
- pstrcpy(fname,lp_driverfile());
- f=sys_fopen(fname,"r");
- if (!f) {
- DEBUG(3,("fill_printq_info: Can't open %s - %s\n",fname,strerror(errno)));
- desc->errcode=NERR_notsupported;
- return;
- }
-
- if ((p=(char *)malloc(8192*sizeof(char))) == NULL) {
- DEBUG(0,("fill_printq_info: malloc fail !\n"));
- desc->errcode=NERR_notsupported;
- fclose(f);
- return;
- }
-
- memset(p, 0, 8192*sizeof(char));
- q=p;
-
- /* lookup the long printer driver name in the file description */
- while (f && !feof(f) && !ok)
- {
- p = q; /* reset string pointer */
- fgets(p,8191,f);
- p[strlen(p)-1]='\0';
- if (next_token(&p,tok,":",sizeof(tok)) &&
- (strlen(lp_printerdriver(snum)) == strlen(tok)) &&
- (!strncmp(tok,lp_printerdriver(snum),strlen(lp_printerdriver(snum)))))
- ok=1;
- }
- fclose(f);
-
- /* driver file name */
- if (ok && !next_token(&p,driver,":",sizeof(driver))) ok = 0;
- /* data file name */
- if (ok && !next_token(&p,datafile,":",sizeof(datafile))) ok = 0;
- /*
- * for the next tokens - which may be empty - I have to check for empty
- * tokens first because the next_token function will skip all empty
- * token fields
- */
- if (ok) {
- /* help file */
- if (*p == ':') {
- *helpfile = '\0';
- p++;
- } else if (!next_token(&p,helpfile,":",sizeof(helpfile))) ok = 0;
- }
-
- if (ok) {
- /* language monitor */
- if (*p == ':') {
- *langmon = '\0';
- p++;
- } else if (!next_token(&p,langmon,":",sizeof(langmon))) ok = 0;
- }
-
- /* default data type */
- if (ok && !next_token(&p,datatype,":",sizeof(datatype))) ok = 0;
-
- if (ok) {
- PACKI(desc,"W",0x0400); /* don't know */
- PACKS(desc,"z",lp_printerdriver(snum)); /* long printer name */
- PACKS(desc,"z",driver); /* Driverfile Name */
- PACKS(desc,"z",datafile); /* Datafile name */
- PACKS(desc,"z",langmon); /* language monitor */
- PACKS(desc,"z",lp_driverlocation(snum)); /* share to retrieve files */
- PACKS(desc,"z",datatype); /* default data type */
- PACKS(desc,"z",helpfile); /* helpfile name */
- PACKS(desc,"z",driver); /* driver name */
- DEBUG(3,("Driver:%s:\n",driver));
- DEBUG(3,("Data File:%s:\n",datafile));
- DEBUG(3,("Language Monitor:%s:\n",langmon));
- DEBUG(3,("Data Type:%s:\n",datatype));
- DEBUG(3,("Help File:%s:\n",helpfile));
- PACKI(desc,"N",count); /* number of files to copy */
- for (i=0;i<count;i++)
- {
- /* no need to check return value here - it was already tested in
- * get_printerdrivernumber
- */
- next_token(&p,tok,",",sizeof(tok));
- PACKS(desc,"z",tok); /* driver files to copy */
- DEBUG(3,("file:%s:\n",tok));
- }
-
- DEBUG(3,("fill_printq_info on <%s> gave %d entries\n",
- SERVICE(snum),count));
- } else {
- DEBUG(3,("fill_printq_info: Can't supply driver files\n"));
- desc->errcode=NERR_notsupported;
- }
- free(q);
- }
+ switch (uLevel)
+ {
+ case 1:
+ case 2:
+ PACKS(desc, "B13", SERVICE(snum));
+ break;
+ case 3:
+ case 4:
+ case 5:
+ PACKS(desc, "z",
+ Expand(conn, key, snum, SERVICE(snum)));
+ break;
+ }
+
+ if (uLevel == 1 || uLevel == 2)
+ {
+ PACKS(desc, "B", ""); /* alignment */
+ PACKI(desc, "W", 5); /* priority */
+ PACKI(desc, "W", 0); /* start time */
+ PACKI(desc, "W", 0); /* until time */
+ PACKS(desc, "z", ""); /* pSepFile */
+ PACKS(desc, "z", "lpd"); /* pPrProc */
+ PACKS(desc, "z", SERVICE(snum)); /* pDestinations */
+ PACKS(desc, "z", ""); /* pParms */
+ if (snum < 0)
+ {
+ PACKS(desc, "z", "UNKNOWN PRINTER");
+ PACKI(desc, "W", LPSTAT_ERROR);
+ }
+ else if (!status || !status->message[0])
+ {
+ PACKS(desc, "z",
+ Expand(conn, key, snum, lp_comment(snum)));
+ PACKI(desc, "W", LPSTAT_OK); /* status */
+ }
+ else
+ {
+ PACKS(desc, "z", status->message);
+ PACKI(desc, "W", status->status); /* status */
+ }
+ PACKI(desc, (uLevel == 1 ? "W" : "N"), count);
+ }
+ if (uLevel == 3 || uLevel == 4)
+ {
+ PACKI(desc, "W", 5); /* uPriority */
+ PACKI(desc, "W", 0); /* uStarttime */
+ PACKI(desc, "W", 0); /* uUntiltime */
+ PACKI(desc, "W", 5); /* pad1 */
+ PACKS(desc, "z", ""); /* pszSepFile */
+ PACKS(desc, "z", "WinPrint"); /* pszPrProc */
+ PACKS(desc, "z", ""); /* pszParms */
+ if (!status || !status->message[0])
+ {
+ PACKS(desc, "z", Expand(conn, key, snum, lp_comment(snum))); /* pszComment */
+ PACKI(desc, "W", LPSTAT_OK); /* fsStatus */
+ }
+ else
+ {
+ PACKS(desc, "z", status->message); /* pszComment */
+ PACKI(desc, "W", status->status); /* fsStatus */
+ }
+ PACKI(desc, (uLevel == 3 ? "W" : "N"), count); /* cJobs */
+ PACKS(desc, "z", SERVICE(snum)); /* pszPrinters */
+ PACKS(desc, "z", lp_printerdriver(snum)); /* pszDriverName */
+ PackDriverData(desc); /* pDriverData */
+ }
+ if (uLevel == 2 || uLevel == 4)
+ {
+ int i;
+ for (i = 0; i < count; i++)
+ fill_printjob_info(conn, snum, uLevel == 2 ? 1 : 2,
+ desc, &queue[i], i);
+ }
+
+ if (uLevel == 52)
+ {
+ int i, ok = 0;
+ pstring tok, driver, datafile, langmon, helpfile, datatype;
+ char *p, *q;
+ FILE *f;
+ pstring fname;
+
+ pstrcpy(fname, lp_driverfile());
+ f = sys_fopen(fname, "r");
+ if (!f)
+ {
+ DEBUG(3,
+ ("fill_printq_info: Can't open %s - %s\n",
+ fname, strerror(errno)));
+ desc->errcode = NERR_notsupported;
+ return;
+ }
+
+ if ((p = (char *)malloc(8192 * sizeof(char))) == NULL)
+ {
+ DEBUG(0, ("fill_printq_info: malloc fail !\n"));
+ desc->errcode = NERR_notsupported;
+ fclose(f);
+ return;
+ }
+
+ memset(p, 0, 8192 * sizeof(char));
+ q = p;
+
+ /* lookup the long printer driver name in the file description */
+ while (f && !feof(f) && !ok)
+ {
+ p = q; /* reset string pointer */
+ fgets(p, 8191, f);
+ p[strlen(p) - 1] = '\0';
+ if (next_token(&p, tok, ":", sizeof(tok)) &&
+ (strlen(lp_printerdriver(snum)) == strlen(tok)) &&
+ (!strncmp(tok, lp_printerdriver(snum),
+ strlen(lp_printerdriver(snum)))))
+ ok = 1;
+ }
+ fclose(f);
+
+ /* driver file name */
+ if (ok && !next_token(&p, driver, ":", sizeof(driver)))
+ ok = 0;
+ /* data file name */
+ if (ok && !next_token(&p, datafile, ":", sizeof(datafile)))
+ ok = 0;
+ /*
+ * for the next tokens - which may be empty - I have to check for empty
+ * tokens first because the next_token function will skip all empty
+ * token fields
+ */
+ if (ok)
+ {
+ /* help file */
+ if (*p == ':')
+ {
+ *helpfile = '\0';
+ p++;
+ }
+ else
+ if (!next_token
+ (&p, helpfile, ":",
+ sizeof(helpfile))) ok = 0;
+ }
+
+ if (ok)
+ {
+ /* language monitor */
+ if (*p == ':')
+ {
+ *langmon = '\0';
+ p++;
+ }
+ else
+ if (!next_token
+ (&p, langmon, ":", sizeof(langmon))) ok =
+ 0;
+ }
+
+ /* default data type */
+ if (ok && !next_token(&p, datatype, ":", sizeof(datatype)))
+ ok = 0;
+
+ if (ok)
+ {
+ PACKI(desc, "W", 0x0400); /* don't know */
+ PACKS(desc, "z", lp_printerdriver(snum)); /* long printer name */
+ PACKS(desc, "z", driver); /* Driverfile Name */
+ PACKS(desc, "z", datafile); /* Datafile name */
+ PACKS(desc, "z", langmon); /* language monitor */
+ PACKS(desc, "z", lp_driverlocation(snum)); /* share to retrieve files */
+ PACKS(desc, "z", datatype); /* default data type */
+ PACKS(desc, "z", helpfile); /* helpfile name */
+ PACKS(desc, "z", driver); /* driver name */
+ DEBUG(3, ("Driver:%s:\n", driver));
+ DEBUG(3, ("Data File:%s:\n", datafile));
+ DEBUG(3, ("Language Monitor:%s:\n", langmon));
+ DEBUG(3, ("Data Type:%s:\n", datatype));
+ DEBUG(3, ("Help File:%s:\n", helpfile));
+ PACKI(desc, "N", count); /* number of files to copy */
+ for (i = 0; i < count; i++)
+ {
+ /* no need to check return value here - it was already tested in
+ * get_printerdrivernumber
+ */
+ next_token(&p, tok, ",", sizeof(tok));
+ PACKS(desc, "z", tok); /* driver files to copy */
+ DEBUG(3, ("file:%s:\n", tok));
+ }
+
+ DEBUG(3,
+ ("fill_printq_info on <%s> gave %d entries\n",
+ SERVICE(snum), count));
+ }
+ else
+ {
+ DEBUG(3,
+ ("fill_printq_info: Can't supply driver files\n"));
+ desc->errcode = NERR_notsupported;
+ }
+ free(q);
+ }
}
/* This function returns the number of files for a given driver */
static int get_printerdrivernumber(int snum)
{
- int i=0,ok=0;
- pstring tok;
- char *p,*q;
- FILE *f;
- pstring fname;
-
- pstrcpy(fname,lp_driverfile());
-
- DEBUG(4,("In get_printerdrivernumber: %s\n",fname));
- f=sys_fopen(fname,"r");
- if (!f) {
- DEBUG(3,("get_printerdrivernumber: Can't open %s - %s\n",fname,strerror(errno)));
- return(0);
- }
-
- if ((p=(char *)malloc(8192*sizeof(char))) == NULL) {
- DEBUG(3,("get_printerdrivernumber: malloc fail !\n"));
- fclose(f);
- return 0;
- }
-
- q=p; /* need it to free memory because p change ! */
-
- /* lookup the long printer driver name in the file description */
- while (!feof(f) && !ok)
- {
- p = q; /* reset string pointer */
- fgets(p,8191,f);
- if (next_token(&p,tok,":",sizeof(tok)) &&
- (!strncmp(tok,lp_printerdriver(snum),strlen(lp_printerdriver(snum)))))
- ok=1;
- }
- fclose(f);
-
- if (ok) {
- /* skip 5 fields */
- i = 5;
- while (*p && i) {
- if (*p++ == ':') i--;
- }
- if (!*p || i)
- return(0);
-
- /* count the number of files */
- while (next_token(&p,tok,",",sizeof(tok)))
- i++;
- }
- free(q);
-
- return(i);
+ int i = 0, ok = 0;
+ pstring tok;
+ char *p, *q;
+ FILE *f;
+ pstring fname;
+
+ pstrcpy(fname, lp_driverfile());
+
+ DEBUG(4, ("In get_printerdrivernumber: %s\n", fname));
+ f = sys_fopen(fname, "r");
+ if (!f)
+ {
+ DEBUG(3,
+ ("get_printerdrivernumber: Can't open %s - %s\n", fname,
+ strerror(errno)));
+ return (0);
+ }
+
+ if ((p = (char *)malloc(8192 * sizeof(char))) == NULL)
+ {
+ DEBUG(3, ("get_printerdrivernumber: malloc fail !\n"));
+ fclose(f);
+ return 0;
+ }
+
+ q = p; /* need it to free memory because p change ! */
+
+ /* lookup the long printer driver name in the file description */
+ while (!feof(f) && !ok)
+ {
+ p = q; /* reset string pointer */
+ fgets(p, 8191, f);
+ if (next_token(&p, tok, ":", sizeof(tok)) &&
+ (!strncmp
+ (tok, lp_printerdriver(snum),
+ strlen(lp_printerdriver(snum)))))
+ ok = 1;
+ }
+ fclose(f);
+
+ if (ok)
+ {
+ /* skip 5 fields */
+ i = 5;
+ while (*p && i)
+ {
+ if (*p++ == ':')
+ i--;
+ }
+ if (!*p || i)
+ return (0);
+
+ /* count the number of files */
+ while (next_token(&p, tok, ",", sizeof(tok)))
+ i++;
+ }
+ free(q);
+
+ return (i);
}
-static BOOL api_DosPrintQGetInfo(connection_struct *conn,
- uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_DosPrintQGetInfo(connection_struct * conn,
+ uint16 vuid, char *param, char *data,
+ int mdrcnt, int mprcnt,
+ char **rdata, char **rparam,
+ int *rdata_len, int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- char *QueueName = p;
- int uLevel;
- int count=0;
- int snum;
- char* str3;
- struct pack_desc desc;
- print_queue_struct *queue=NULL;
- print_status_struct status;
-
- VUSER_KEY;
-
- ZERO_STRUCT(status);
- ZERO_STRUCT(desc);
-
- p = skip_string(p,1);
- uLevel = SVAL(p,0);
- str3 = p + 4;
-
- /* remove any trailing username */
- if ((p = strchr(QueueName,'%'))) *p = 0;
-
- DEBUG(3,("PrintQueue uLevel=%d name=%s\n",uLevel,QueueName));
-
- /* check it's a supported varient */
- if (!prefix_ok(str1,"zWrLh")) return False;
- if (!check_printq_info(&desc,uLevel,str2,str3)) return False;
-
- snum = lp_servicenumber(QueueName);
- if (snum < 0 && pcap_printername_ok(QueueName,NULL)) {
- int pnum = lp_servicenumber(PRINTERS_NAME);
- if (pnum >= 0) {
- lp_add_printer(QueueName,pnum);
- snum = lp_servicenumber(QueueName);
- }
- }
-
- if (snum < 0 || !VALID_SNUM(snum)) return(False);
-
- if (uLevel==52) {
- count = get_printerdrivernumber(snum);
- DEBUG(3,("api_DosPrintQGetInfo: Driver files count: %d\n",count));
- } else {
- count = get_printqueue(snum, conn,&key,&queue,&status);
- }
-
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- if (init_package(&desc,1,count)) {
- desc.subcount = count;
- fill_printq_info(conn,&key,snum,uLevel,&desc,count,queue,&status);
- } else if (uLevel == 0) {
- /*
- * This is a *disgusting* hack.
- * This is *so* bad that even I'm embarrassed (and I
- * have no shame). Here's the deal :
- * Until we get the correct SPOOLSS code into smbd
- * then when we're running with NT SMB support then
- * NT makes this call with a level of zero, and then
- * immediately follows it with an open request to
- * the \\SRVSVC pipe. If we allow that open to
- * succeed then NT barfs when it cannot open the
- * \\SPOOLSS pipe immediately after and continually
- * whines saying "Printer name is invalid" forever
- * after. If we cause *JUST THIS NEXT OPEN* of \\SRVSVC
- * to fail, then NT downgrades to using the downlevel code
- * and everything works as well as before. I hate
- * myself for adding this code.... JRA.
- */
-
- fail_next_srvsvc_open();
- }
-
- *rdata_len = desc.usedlen;
-
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,desc.neededlen);
-
- DEBUG(4,("printqgetinfo: errorcode %d\n",desc.errcode));
-
- if (queue) free(queue);
-
- return(True);
+ char *str1 = param + 2;
+ char *str2 = skip_string(str1, 1);
+ char *p = skip_string(str2, 1);
+ char *QueueName = p;
+ int uLevel;
+ int count = 0;
+ int snum;
+ char *str3;
+ struct pack_desc desc;
+ print_queue_struct *queue = NULL;
+ print_status_struct status;
+
+ VUSER_KEY;
+
+ ZERO_STRUCT(status);
+ ZERO_STRUCT(desc);
+
+ p = skip_string(p, 1);
+ uLevel = SVAL(p, 0);
+ str3 = p + 4;
+
+ /* remove any trailing username */
+ if ((p = strchr(QueueName, '%')))
+ *p = 0;
+
+ DEBUG(3, ("PrintQueue uLevel=%d name=%s\n", uLevel, QueueName));
+
+ /* check it's a supported varient */
+ if (!prefix_ok(str1, "zWrLh"))
+ return False;
+ if (!check_printq_info(&desc, uLevel, str2, str3))
+ {
+ /*
+ * Patch from Scott Moomaw <scott@bridgewater.edu>
+ * to return the 'invalid info level' error if an
+ * unknown level was requested.
+ */
+ *rdata_len = 0;
+ *rparam_len = 6;
+ *rparam = REALLOC(*rparam, *rparam_len);
+ SSVALS(*rparam, 0, ERROR_INVALID_LEVEL);
+ SSVAL(*rparam, 2, 0);
+ SSVAL(*rparam, 4, 0);
+ return (True);
+ }
+
+ snum = lp_servicenumber(QueueName);
+ if (snum < 0 && pcap_printername_ok(QueueName, NULL))
+ {
+ int pnum = lp_servicenumber(PRINTERS_NAME);
+ if (pnum >= 0)
+ {
+ lp_add_printer(QueueName, pnum);
+ snum = lp_servicenumber(QueueName);
+ }
+ }
+
+ if (snum < 0 || !VALID_SNUM(snum))
+ return (False);
+
+ if (uLevel == 52)
+ {
+ count = get_printerdrivernumber(snum);
+ DEBUG(3,
+ ("api_DosPrintQGetInfo: Driver files count: %d\n",
+ count));
+ }
+ else
+ {
+ count = get_printqueue(snum, conn, &key, &queue, &status);
+ }
+
+ if (mdrcnt > 0)
+ *rdata = REALLOC(*rdata, mdrcnt);
+ desc.base = *rdata;
+ desc.buflen = mdrcnt;
+ if (init_package(&desc, 1, count))
+ {
+ desc.subcount = count;
+ fill_printq_info(conn, &key, snum, uLevel, &desc, count,
+ queue, &status);
+ }
+ else if (uLevel == 0)
+ {
+ /*
+ * This is a *disgusting* hack.
+ * This is *so* bad that even I'm embarrassed (and I
+ * have no shame). Here's the deal :
+ * Until we get the correct SPOOLSS code into smbd
+ * then when we're running with NT SMB support then
+ * NT makes this call with a level of zero, and then
+ * immediately follows it with an open request to
+ * the \\SRVSVC pipe. If we allow that open to
+ * succeed then NT barfs when it cannot open the
+ * \\SPOOLSS pipe immediately after and continually
+ * whines saying "Printer name is invalid" forever
+ * after. If we cause *JUST THIS NEXT OPEN* of \\SRVSVC
+ * to fail, then NT downgrades to using the downlevel code
+ * and everything works as well as before. I hate
+ * myself for adding this code.... JRA.
+ */
+
+ fail_next_srvsvc_open();
+ }
+
+ *rdata_len = desc.usedlen;
+
+ *rparam_len = 6;
+ *rparam = REALLOC(*rparam, *rparam_len);
+ SSVALS(*rparam, 0, desc.errcode);
+ SSVAL(*rparam, 2, 0);
+ SSVAL(*rparam, 4, desc.neededlen);
+
+ DEBUG(4, ("printqgetinfo: errorcode %d\n", desc.errcode));
+
+ if (queue)
+ free(queue);
+
+ return (True);
}
/****************************************************************************
view list of all print jobs on all queues
****************************************************************************/
-static BOOL api_DosPrintQEnum(connection_struct *conn, uint16 vuid, char* param, char* data,
- int mdrcnt, int mprcnt,
- char **rdata, char** rparam,
- int *rdata_len, int *rparam_len)
+static BOOL api_DosPrintQEnum(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt, int mprcnt,
+ char **rdata, char **rparam, int *rdata_len,
+ int *rparam_len)
{
- char *param_format = param+2;
- char *output_format1 = skip_string(param_format,1);
- char *p = skip_string(output_format1,1);
- int uLevel = SVAL(p,0);
- char *output_format2 = p + 4;
- int services = lp_numservices();
- int i, n;
- struct pack_desc desc;
- print_queue_struct **queue = NULL;
- print_status_struct *status = NULL;
- int* subcntarr = NULL;
- int queuecnt, subcnt=0, succnt=0;
+ char *param_format = param + 2;
+ char *output_format1 = skip_string(param_format, 1);
+ char *p = skip_string(output_format1, 1);
+ int uLevel = SVAL(p, 0);
+ char *output_format2 = p + 4;
+ int services = lp_numservices();
+ int i, n;
+ struct pack_desc desc;
+ print_queue_struct **queue = NULL;
+ print_status_struct *status = NULL;
+ int *subcntarr = NULL;
+ int queuecnt, subcnt = 0, succnt = 0;
VUSER_KEY;
-
- ZERO_STRUCT(desc);
-
- DEBUG(3,("DosPrintQEnum uLevel=%d\n",uLevel));
-
- if (!prefix_ok(param_format,"WrLeh")) return False;
- if (!check_printq_info(&desc,uLevel,output_format1,output_format2))
- return False;
- queuecnt = 0;
- for (i = 0; i < services; i++)
- if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i))
- queuecnt++;
- if (uLevel > 0) {
- if ((queue = (print_queue_struct**)malloc(queuecnt*sizeof(print_queue_struct*))) == NULL) {
- DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
- return False;
- }
- memset(queue,0,queuecnt*sizeof(print_queue_struct*));
- if ((status = (print_status_struct*)malloc(queuecnt*sizeof(print_status_struct))) == NULL) {
- DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
- return False;
- }
- memset(status,0,queuecnt*sizeof(print_status_struct));
- if ((subcntarr = (int*)malloc(queuecnt*sizeof(int))) == NULL) {
- DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
- return False;
- }
- subcnt = 0;
- n = 0;
- for (i = 0; i < services; i++)
- if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
- subcntarr[n] = get_printqueue(i, conn, &key, &queue[n],&status[n]);
- subcnt += subcntarr[n];
- n++;
- }
- }
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
-
- if (init_package(&desc,queuecnt,subcnt)) {
- n = 0;
- succnt = 0;
- for (i = 0; i < services; i++)
- if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
- fill_printq_info(conn,&key, i,uLevel,&desc,subcntarr[n],queue[n],&status[n]);
- n++;
- if (desc.errcode == NERR_Success) succnt = n;
- }
- }
-
- if (subcntarr) free(subcntarr);
-
- *rdata_len = desc.usedlen;
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,succnt);
- SSVAL(*rparam,6,queuecnt);
-
- for (i = 0; i < queuecnt; i++) {
- if (queue && queue[i]) free(queue[i]);
- }
-
- if (queue) free(queue);
- if (status) free(status);
-
- return True;
+
+ ZERO_STRUCT(desc);
+
+ DEBUG(3, ("DosPrintQEnum uLevel=%d\n", uLevel));
+
+ if (!prefix_ok(param_format, "WrLeh"))
+ return False;
+ if (!check_printq_info(&desc, uLevel, output_format1, output_format2))
+ {
+ /*
+ * Patch from Scott Moomaw <scott@bridgewater.edu>
+ * to return the 'invalid info level' error if an
+ * unknown level was requested.
+ */
+ *rdata_len = 0;
+ *rparam_len = 6;
+ *rparam = REALLOC(*rparam, *rparam_len);
+ SSVALS(*rparam, 0, ERROR_INVALID_LEVEL);
+ SSVAL(*rparam, 2, 0);
+ SSVAL(*rparam, 4, 0);
+ return (True);
+ }
+
+ queuecnt = 0;
+ for (i = 0; i < services; i++)
+ if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i))
+ queuecnt++;
+ if (uLevel > 0)
+ {
+ if (
+ (queue =
+ (print_queue_struct **) malloc(queuecnt *
+ sizeof(print_queue_struct
+ *))) == NULL)
+ {
+ DEBUG(0, ("api_DosPrintQEnum: malloc fail !\n"));
+ return False;
+ }
+ memset(queue, 0, queuecnt * sizeof(print_queue_struct *));
+ if (
+ (status =
+ (print_status_struct *) malloc(queuecnt *
+ sizeof
+ (print_status_struct))) ==
+ NULL)
+ {
+ DEBUG(0, ("api_DosPrintQEnum: malloc fail !\n"));
+ return False;
+ }
+ memset(status, 0, queuecnt * sizeof(print_status_struct));
+ if ((subcntarr = (int *)malloc(queuecnt * sizeof(int))) ==
+ NULL)
+ {
+ DEBUG(0, ("api_DosPrintQEnum: malloc fail !\n"));
+ return False;
+ }
+ subcnt = 0;
+ n = 0;
+ for (i = 0; i < services; i++)
+ if (lp_snum_ok(i) && lp_print_ok(i)
+ && lp_browseable(i))
+ {
+ subcntarr[n] =
+ get_printqueue(i, conn, &key,
+ &queue[n], &status[n]);
+ subcnt += subcntarr[n];
+ n++;
+ }
+ }
+ if (mdrcnt > 0)
+ *rdata = REALLOC(*rdata, mdrcnt);
+ desc.base = *rdata;
+ desc.buflen = mdrcnt;
+
+ if (init_package(&desc, queuecnt, subcnt))
+ {
+ n = 0;
+ succnt = 0;
+ for (i = 0; i < services; i++)
+ if (lp_snum_ok(i) && lp_print_ok(i)
+ && lp_browseable(i))
+ {
+ fill_printq_info(conn, &key, i, uLevel, &desc,
+ subcntarr[n], queue[n],
+ &status[n]);
+ n++;
+ if (desc.errcode == NERR_Success)
+ succnt = n;
+ }
+ }
+
+ if (subcntarr)
+ free(subcntarr);
+
+ *rdata_len = desc.usedlen;
+ *rparam_len = 8;
+ *rparam = REALLOC(*rparam, *rparam_len);
+ SSVALS(*rparam, 0, desc.errcode);
+ SSVAL(*rparam, 2, 0);
+ SSVAL(*rparam, 4, succnt);
+ SSVAL(*rparam, 6, queuecnt);
+
+ for (i = 0; i < queuecnt; i++)
+ {
+ if (queue && queue[i])
+ free(queue[i]);
+ }
+
+ if (queue)
+ free(queue);
+ if (status)
+ free(status);
+
+ return True;
}
/****************************************************************************
get info level for a server list query
****************************************************************************/
-static BOOL check_server_info(int uLevel, char* id)
+static BOOL check_server_info(int uLevel, char *id)
{
- switch( uLevel ) {
- case 0:
- if (strcmp(id,"B16") != 0) return False;
- break;
- case 1:
- if (strcmp(id,"B16BBDz") != 0) return False;
- break;
- default:
- return False;
- }
- return True;
+ switch (uLevel)
+ {
+ case 0:
+ if (strcmp(id, "B16") != 0)
+ return False;
+ break;
+ case 1:
+ if (strcmp(id, "B16BBDz") != 0)
+ return False;
+ break;
+ default:
+ return False;
+ }
+ return True;
}
struct srv_info_struct
{
- fstring name;
- uint32 type;
- fstring comment;
- fstring domain;
- BOOL server_added;
+ fstring name;
+ uint32 type;
+ fstring comment;
+ fstring domain;
+ BOOL server_added;
};
get server info lists from the files saved by nmbd. Return the
number of entries
******************************************************************/
-static int get_server_info(uint32 servertype,
- struct srv_info_struct **servers,
- char *domain)
+static int get_server_info(uint32 servertype,
+ struct srv_info_struct **servers, char *domain)
{
- FILE *f;
- pstring fname;
- int count=0;
- int alloced=0;
- pstring line;
- BOOL local_list_only;
-
- pstrcpy(fname,lp_lockdir());
- trim_string(fname,NULL,"/");
- pstrcat(fname,"/");
- pstrcat(fname,SERVER_LIST);
-
- f = sys_fopen(fname,"r");
-
- if (!f) {
- DEBUG(4,("Can't open %s - %s\n",fname,strerror(errno)));
- return(0);
- }
-
- /* request for everything is code for request all servers */
- if (servertype == SV_TYPE_ALL)
- servertype &= ~(SV_TYPE_DOMAIN_ENUM|SV_TYPE_LOCAL_LIST_ONLY);
-
- local_list_only = (servertype & SV_TYPE_LOCAL_LIST_ONLY);
-
- DEBUG(4,("Servertype search: %8x\n",servertype));
-
- while (!feof(f))
- {
- fstring stype;
- struct srv_info_struct *s;
- char *ptr = line;
- BOOL ok = True;
- *ptr = 0;
-
- fgets(line,sizeof(line)-1,f);
- if (!*line) continue;
-
- if (count == alloced) {
- alloced += 10;
- (*servers) = (struct srv_info_struct *)
- Realloc(*servers,sizeof(**servers)*alloced);
- if (!(*servers)) return(0);
- memset((char *)((*servers)+count), 0, sizeof(**servers)*(alloced-count));
- }
- s = &(*servers)[count];
-
- if (!next_token(&ptr,s->name , NULL, sizeof(s->name))) continue;
- if (!next_token(&ptr,stype , NULL, sizeof(stype))) continue;
- if (!next_token(&ptr,s->comment, NULL, sizeof(s->comment))) continue;
- if (!next_token(&ptr,s->domain , NULL, sizeof(s->domain))) {
- /* this allows us to cope with an old nmbd */
- pstrcpy(s->domain,global_myworkgroup);
- }
-
- if (sscanf(stype,"%X",&s->type) != 1) {
- DEBUG(4,("r:host file "));
- ok = False;
- }
-
- /* Filter the servers/domains we return based on what was asked for. */
-
- /* Check to see if we are being asked for a local list only. */
- if (local_list_only && ((s->type & SV_TYPE_LOCAL_LIST_ONLY) == 0)) {
- DEBUG(4,("r: local list only"));
- ok = False;
- }
-
- /* doesn't match up: don't want it */
- if (!(servertype & s->type)) {
- DEBUG(4,("r:serv type "));
- ok = False;
- }
-
- if ((servertype & SV_TYPE_DOMAIN_ENUM) !=
- (s->type & SV_TYPE_DOMAIN_ENUM))
- {
- DEBUG(4,("s: dom mismatch "));
- ok = False;
- }
-
- if (!strequal(domain, s->domain) && !(servertype & SV_TYPE_DOMAIN_ENUM))
- {
- ok = False;
- }
-
- /* We should never return a server type with a SV_TYPE_LOCAL_LIST_ONLY set. */
- s->type &= ~SV_TYPE_LOCAL_LIST_ONLY;
-
- if (ok)
- {
- DEBUG(4,("**SV** %20s %8x %25s %15s\n",
- s->name, s->type, s->comment, s->domain));
-
- s->server_added = True;
- count++;
- }
- else
- {
- DEBUG(4,("%20s %8x %25s %15s\n",
- s->name, s->type, s->comment, s->domain));
- }
- }
-
- fclose(f);
- return(count);
+ FILE *f;
+ pstring fname;
+ int count = 0;
+ int alloced = 0;
+ pstring line;
+ BOOL local_list_only;
+
+ pstrcpy(fname, lp_lockdir());
+ trim_string(fname, NULL, "/");
+ pstrcat(fname, "/");
+ pstrcat(fname, SERVER_LIST);
+
+ f = sys_fopen(fname, "r");
+
+ if (!f)
+ {
+ DEBUG(4, ("Can't open %s - %s\n", fname, strerror(errno)));
+ return (0);
+ }
+
+ /* request for everything is code for request all servers */
+ if (servertype == SV_TYPE_ALL)
+ servertype &=
+ ~(SV_TYPE_DOMAIN_ENUM | SV_TYPE_LOCAL_LIST_ONLY);
+
+ local_list_only = (servertype & SV_TYPE_LOCAL_LIST_ONLY);
+
+ DEBUG(4, ("Servertype search: %8x\n", servertype));
+
+ while (!feof(f))
+ {
+ fstring stype;
+ struct srv_info_struct *s;
+ char *ptr = line;
+ BOOL ok = True;
+ *ptr = 0;
+
+ fgets(line, sizeof(line) - 1, f);
+ if (!*line)
+ continue;
+
+ if (count == alloced)
+ {
+ alloced += 10;
+ (*servers) = (struct srv_info_struct *)Realloc
+ (*servers, sizeof(**servers) * alloced);
+ if (!(*servers))
+ return (0);
+ memset((char *)((*servers) + count), 0,
+ sizeof(**servers) * (alloced - count));
+ }
+ s = &(*servers)[count];
+
+ if (!next_token(&ptr, s->name, NULL, sizeof(s->name)))
+ continue;
+ if (!next_token(&ptr, stype, NULL, sizeof(stype)))
+ continue;
+ if (!next_token(&ptr, s->comment, NULL, sizeof(s->comment)))
+ continue;
+ if (!next_token(&ptr, s->domain, NULL, sizeof(s->domain)))
+ {
+ /* this allows us to cope with an old nmbd */
+ pstrcpy(s->domain, global_myworkgroup);
+ }
+
+ if (sscanf(stype, "%X", &s->type) != 1)
+ {
+ DEBUG(4, ("r:host file "));
+ ok = False;
+ }
+
+ /* Filter the servers/domains we return based on what was asked for. */
+
+ /* Check to see if we are being asked for a local list only. */
+ if (local_list_only
+ && ((s->type & SV_TYPE_LOCAL_LIST_ONLY) == 0))
+ {
+ DEBUG(4, ("r: local list only"));
+ ok = False;
+ }
+
+ /* doesn't match up: don't want it */
+ if (!(servertype & s->type))
+ {
+ DEBUG(4, ("r:serv type "));
+ ok = False;
+ }
+
+ if ((servertype & SV_TYPE_DOMAIN_ENUM) !=
+ (s->type & SV_TYPE_DOMAIN_ENUM))
+ {
+ DEBUG(4, ("s: dom mismatch "));
+ ok = False;
+ }
+
+ if (!strequal(domain, s->domain)
+ && !(servertype & SV_TYPE_DOMAIN_ENUM))
+ {
+ ok = False;
+ }
+
+ /* We should never return a server type with a SV_TYPE_LOCAL_LIST_ONLY set. */
+ s->type &= ~SV_TYPE_LOCAL_LIST_ONLY;
+
+ if (ok)
+ {
+ DEBUG(4, ("**SV** %20s %8x %25s %15s\n",
+ s->name, s->type, s->comment, s->domain));
+
+ s->server_added = True;
+ count++;
+ }
+ else
+ {
+ DEBUG(4, ("%20s %8x %25s %15s\n",
+ s->name, s->type, s->comment, s->domain));
+ }
+ }
+
+ fclose(f);
+ return (count);
}
/*******************************************************************
fill in a server info structure
******************************************************************/
-static int fill_srv_info(struct srv_info_struct *service,
- int uLevel, char **buf, int *buflen,
+static int fill_srv_info(struct srv_info_struct *service,
+ int uLevel, char **buf, int *buflen,
char **stringbuf, int *stringspace, char *baseaddr)
{
- int struct_len;
- char* p;
- char* p2;
- int l2;
- int len;
-
- switch (uLevel) {
- case 0: struct_len = 16; break;
- case 1: struct_len = 26; break;
- default: return -1;
- }
-
- if (!buf)
- {
- len = 0;
- switch (uLevel)
- {
- case 1:
- len = strlen(service->comment)+1;
- break;
- }
-
- if (buflen) *buflen = struct_len;
- if (stringspace) *stringspace = len;
- return struct_len + len;
- }
-
- len = struct_len;
- p = *buf;
- if (*buflen < struct_len) return -1;
- if (stringbuf)
- {
- p2 = *stringbuf;
- l2 = *stringspace;
- }
- else
- {
- p2 = p + struct_len;
- l2 = *buflen - struct_len;
- }
- if (!baseaddr) baseaddr = p;
-
- switch (uLevel)
- {
- case 0:
- StrnCpy(p,service->name,15);
- break;
-
- case 1:
- StrnCpy(p,service->name,15);
- SIVAL(p,18,service->type);
- SIVAL(p,22,PTR_DIFF(p2,baseaddr));
- len += CopyAndAdvance(&p2,service->comment,&l2);
- break;
- }
-
- if (stringbuf)
- {
- *buf = p + struct_len;
- *buflen -= struct_len;
- *stringbuf = p2;
- *stringspace = l2;
- }
- else
- {
- *buf = p2;
- *buflen -= len;
- }
- return len;
+ int struct_len;
+ char *p;
+ char *p2;
+ int l2;
+ int len;
+
+ switch (uLevel)
+ {
+ case 0:
+ struct_len = 16;
+ break;
+ case 1:
+ struct_len = 26;
+ break;
+ default:
+ return -1;
+ }
+
+ if (!buf)
+ {
+ len = 0;
+ switch (uLevel)
+ {
+ case 1:
+ len = strlen(service->comment) + 1;
+ break;
+ }
+
+ if (buflen)
+ *buflen = struct_len;
+ if (stringspace)
+ *stringspace = len;
+ return struct_len + len;
+ }
+
+ len = struct_len;
+ p = *buf;
+ if (*buflen < struct_len)
+ return -1;
+ if (stringbuf)
+ {
+ p2 = *stringbuf;
+ l2 = *stringspace;
+ }
+ else
+ {
+ p2 = p + struct_len;
+ l2 = *buflen - struct_len;
+ }
+ if (!baseaddr)
+ baseaddr = p;
+
+ switch (uLevel)
+ {
+ case 0:
+ StrnCpy(p, service->name, 15);
+ break;
+
+ case 1:
+ StrnCpy(p, service->name, 15);
+ SIVAL(p, 18, service->type);
+ SIVAL(p, 22, PTR_DIFF(p2, baseaddr));
+ len += CopyAndAdvance(&p2, service->comment, &l2);
+ break;
+ }
+
+ if (stringbuf)
+ {
+ *buf = p + struct_len;
+ *buflen -= struct_len;
+ *stringbuf = p2;
+ *stringspace = l2;
+ }
+ else
+ {
+ *buf = p2;
+ *buflen -= len;
+ }
+ return len;
}
-static BOOL srv_comp(struct srv_info_struct *s1,struct srv_info_struct *s2)
+static BOOL srv_comp(struct srv_info_struct *s1, struct srv_info_struct *s2)
{
- return(strcmp(s1->name,s2->name));
+ return (strcmp(s1->name, s2->name));
}
/****************************************************************************
view list of servers available (or possibly domains). The info is
extracted from lists saved by nmbd on the local host
****************************************************************************/
-static BOOL api_RNetServerEnum(connection_struct *conn, uint16 vuid, char *param, char *data,
- int mdrcnt, int mprcnt, char **rdata,
- char **rparam, int *rdata_len, int *rparam_len)
+static BOOL api_RNetServerEnum(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt,
+ int mprcnt, char **rdata, char **rparam,
+ int *rdata_len, int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel = SVAL(p,0);
- int buf_len = SVAL(p,2);
- uint32 servertype = IVAL(p,4);
- char *p2;
- int data_len, fixed_len, string_len;
- int f_len = 0, s_len = 0;
- struct srv_info_struct *servers=NULL;
- int counted=0,total=0;
- int i,missed;
- fstring domain;
- BOOL domain_request;
- BOOL local_request;
-
- /* If someone sets all the bits they don't really mean to set
- DOMAIN_ENUM and LOCAL_LIST_ONLY, they just want all the
- known servers. */
-
- if (servertype == SV_TYPE_ALL)
- servertype &= ~(SV_TYPE_DOMAIN_ENUM|SV_TYPE_LOCAL_LIST_ONLY);
-
- /* If someone sets SV_TYPE_LOCAL_LIST_ONLY but hasn't set
- any other bit (they may just set this bit on it's own) they
- want all the locally seen servers. However this bit can be
- set on its own so set the requested servers to be
- ALL - DOMAIN_ENUM. */
-
- if ((servertype & SV_TYPE_LOCAL_LIST_ONLY) && !(servertype & SV_TYPE_DOMAIN_ENUM))
- servertype = SV_TYPE_ALL & ~(SV_TYPE_DOMAIN_ENUM);
-
- domain_request = ((servertype & SV_TYPE_DOMAIN_ENUM) != 0);
- local_request = ((servertype & SV_TYPE_LOCAL_LIST_ONLY) != 0);
-
- p += 8;
-
- if (!prefix_ok(str1,"WrLehD")) return False;
- if (!check_server_info(uLevel,str2)) return False;
-
- DEBUG(4, ("server request level: %s %8x ", str2, servertype));
- DEBUG(4, ("domains_req:%s ", BOOLSTR(domain_request)));
- DEBUG(4, ("local_only:%s\n", BOOLSTR(local_request)));
-
- if (strcmp(str1, "WrLehDz") == 0) {
- StrnCpy(domain, p, sizeof(fstring)-1);
- } else {
- StrnCpy(domain, global_myworkgroup, sizeof(fstring)-1);
- }
-
- if (lp_browse_list())
- total = get_server_info(servertype,&servers,domain);
-
- data_len = fixed_len = string_len = 0;
- missed = 0;
-
- qsort(servers,total,sizeof(servers[0]),QSORT_CAST srv_comp);
-
- {
- char *lastname=NULL;
-
- for (i=0;i<total;i++)
- {
- struct srv_info_struct *s = &servers[i];
- if (lastname && strequal(lastname,s->name)) continue;
- lastname = s->name;
- data_len += fill_srv_info(s,uLevel,0,&f_len,0,&s_len,0);
- DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n",
- s->name, s->type, s->comment, s->domain));
-
- if (data_len <= buf_len) {
- counted++;
- fixed_len += f_len;
- string_len += s_len;
- } else {
- missed++;
- }
- }
- }
-
- *rdata_len = fixed_len + string_len;
- *rdata = REALLOC(*rdata,*rdata_len);
- memset(*rdata, 0, *rdata_len);
-
- p2 = (*rdata) + fixed_len; /* auxilliary data (strings) will go here */
- p = *rdata;
- f_len = fixed_len;
- s_len = string_len;
-
- {
- char *lastname=NULL;
- int count2 = counted;
- for (i = 0; i < total && count2;i++)
- {
- struct srv_info_struct *s = &servers[i];
- if (lastname && strequal(lastname,s->name)) continue;
- lastname = s->name;
- fill_srv_info(s,uLevel,&p,&f_len,&p2,&s_len,*rdata);
- DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n",
- s->name, s->type, s->comment, s->domain));
- count2--;
- }
- }
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVAL(*rparam,0,(missed == 0 ? NERR_Success : ERRmoredata));
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,counted);
- SSVAL(*rparam,6,counted+missed);
-
- if (servers) free(servers);
-
- DEBUG(3,("NetServerEnum domain = %s uLevel=%d counted=%d total=%d\n",
- domain,uLevel,counted,counted+missed));
-
- return(True);
+ char *str1 = param + 2;
+ char *str2 = skip_string(str1, 1);
+ char *p = skip_string(str2, 1);
+ int uLevel = SVAL(p, 0);
+ int buf_len = SVAL(p, 2);
+ uint32 servertype = IVAL(p, 4);
+ char *p2;
+ int data_len, fixed_len, string_len;
+ int f_len = 0, s_len = 0;
+ struct srv_info_struct *servers = NULL;
+ int counted = 0, total = 0;
+ int i, missed;
+ fstring domain;
+ BOOL domain_request;
+ BOOL local_request;
+
+ /* If someone sets all the bits they don't really mean to set
+ DOMAIN_ENUM and LOCAL_LIST_ONLY, they just want all the
+ known servers. */
+
+ if (servertype == SV_TYPE_ALL)
+ servertype &=
+ ~(SV_TYPE_DOMAIN_ENUM | SV_TYPE_LOCAL_LIST_ONLY);
+
+ /* If someone sets SV_TYPE_LOCAL_LIST_ONLY but hasn't set
+ any other bit (they may just set this bit on it's own) they
+ want all the locally seen servers. However this bit can be
+ set on its own so set the requested servers to be
+ ALL - DOMAIN_ENUM. */
+
+ if ((servertype & SV_TYPE_LOCAL_LIST_ONLY)
+ && !(servertype & SV_TYPE_DOMAIN_ENUM))
+ servertype = SV_TYPE_ALL & ~(SV_TYPE_DOMAIN_ENUM);
+
+ domain_request = ((servertype & SV_TYPE_DOMAIN_ENUM) != 0);
+ local_request = ((servertype & SV_TYPE_LOCAL_LIST_ONLY) != 0);
+
+ p += 8;
+
+ if (!prefix_ok(str1, "WrLehD"))
+ return False;
+ if (!check_server_info(uLevel, str2))
+ return False;
+
+ DEBUG(4, ("server request level: %s %8x ", str2, servertype));
+ DEBUG(4, ("domains_req:%s ", BOOLSTR(domain_request)));
+ DEBUG(4, ("local_only:%s\n", BOOLSTR(local_request)));
+
+ if (strcmp(str1, "WrLehDz") == 0)
+ {
+ StrnCpy(domain, p, sizeof(fstring) - 1);
+ }
+ else
+ {
+ StrnCpy(domain, global_myworkgroup, sizeof(fstring) - 1);
+ }
+
+ if (lp_browse_list())
+ total = get_server_info(servertype, &servers, domain);
+
+ data_len = fixed_len = string_len = 0;
+ missed = 0;
+
+ qsort(servers, total, sizeof(servers[0]), QSORT_CAST srv_comp);
+
+ {
+ char *lastname = NULL;
+
+ for (i = 0; i < total; i++)
+ {
+ struct srv_info_struct *s = &servers[i];
+ if (lastname && strequal(lastname, s->name))
+ continue;
+ lastname = s->name;
+ data_len +=
+ fill_srv_info(s, uLevel, 0, &f_len, 0, &s_len,
+ 0);
+ DEBUG(4,
+ ("fill_srv_info %20s %8x %25s %15s\n", s->name,
+ s->type, s->comment, s->domain));
+
+ if (data_len <= buf_len)
+ {
+ counted++;
+ fixed_len += f_len;
+ string_len += s_len;
+ }
+ else
+ {
+ missed++;
+ }
+ }
+ }
+
+ *rdata_len = fixed_len + string_len;
+ *rdata = REALLOC(*rdata, *rdata_len);
+ memset(*rdata, 0, *rdata_len);
+
+ p2 = (*rdata) + fixed_len; /* auxilliary data (strings) will go here */
+ p = *rdata;
+ f_len = fixed_len;
+ s_len = string_len;
+
+ {
+ char *lastname = NULL;
+ int count2 = counted;
+ for (i = 0; i < total && count2; i++)
+ {
+ struct srv_info_struct *s = &servers[i];
+ if (lastname && strequal(lastname, s->name))
+ continue;
+ lastname = s->name;
+ fill_srv_info(s, uLevel, &p, &f_len, &p2, &s_len,
+ *rdata);
+ DEBUG(4,
+ ("fill_srv_info %20s %8x %25s %15s\n", s->name,
+ s->type, s->comment, s->domain));
+ count2--;
+ }
+ }
+
+ *rparam_len = 8;
+ *rparam = REALLOC(*rparam, *rparam_len);
+ SSVAL(*rparam, 0, (missed == 0 ? NERR_Success : ERRmoredata));
+ SSVAL(*rparam, 2, 0);
+ SSVAL(*rparam, 4, counted);
+ SSVAL(*rparam, 6, counted + missed);
+
+ if (servers)
+ free(servers);
+
+ DEBUG(3, ("NetServerEnum domain = %s uLevel=%d counted=%d total=%d\n",
+ domain, uLevel, counted, counted + missed));
+
+ return (True);
}
/****************************************************************************
command 0x34 - suspected of being a "Lookup Names" stub api
****************************************************************************/
-static BOOL api_RNetGroupGetUsers(connection_struct *conn, uint16 vuid, char *param, char *data,
- int mdrcnt, int mprcnt, char **rdata,
- char **rparam, int *rdata_len, int *rparam_len)
+static BOOL api_RNetGroupGetUsers(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt,
+ int mprcnt, char **rdata, char **rparam,
+ int *rdata_len, int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel = SVAL(p,0);
- int buf_len = SVAL(p,2);
- int counted=0;
- int missed=0;
-
- DEBUG(5,("RNetGroupGetUsers: %s %s %s %d %d\n",
- str1, str2, p, uLevel, buf_len));
-
- if (!prefix_ok(str1,"zWrLeh")) return False;
-
- *rdata_len = 0;
- *rdata = NULL;
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- SSVAL(*rparam,0,0x08AC); /* informational warning message */
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,counted);
- SSVAL(*rparam,6,counted+missed);
-
- return(True);
+ char *str1 = param + 2;
+ char *str2 = skip_string(str1, 1);
+ char *p = skip_string(str2, 1);
+ int uLevel = SVAL(p, 0);
+ int buf_len = SVAL(p, 2);
+ int counted = 0;
+ int missed = 0;
+
+ DEBUG(5, ("RNetGroupGetUsers: %s %s %s %d %d\n",
+ str1, str2, p, uLevel, buf_len));
+
+ if (!prefix_ok(str1, "zWrLeh"))
+ return False;
+
+ *rdata_len = 0;
+ *rdata = NULL;
+
+ *rparam_len = 8;
+ *rparam = REALLOC(*rparam, *rparam_len);
+
+ SSVAL(*rparam, 0, 0x08AC); /* informational warning message */
+ SSVAL(*rparam, 2, 0);
+ SSVAL(*rparam, 4, counted);
+ SSVAL(*rparam, 6, counted + missed);
+
+ return (True);
}
/****************************************************************************
get info about a share
****************************************************************************/
-static BOOL check_share_info(int uLevel, char* id)
+static BOOL check_share_info(int uLevel, char *id)
{
- switch( uLevel ) {
- case 0:
- if (strcmp(id,"B13") != 0) return False;
- break;
- case 1:
- if (strcmp(id,"B13BWz") != 0) return False;
- break;
- case 2:
- if (strcmp(id,"B13BWzWWWzB9B") != 0) return False;
- break;
- case 91:
- if (strcmp(id,"B13BWzWWWzB9BB9BWzWWzWW") != 0) return False;
- break;
- default: return False;
- }
- return True;
+ switch (uLevel)
+ {
+ case 0:
+ if (strcmp(id, "B13") != 0)
+ return False;
+ break;
+ case 1:
+ if (strcmp(id, "B13BWz") != 0)
+ return False;
+ break;
+ case 2:
+ if (strcmp(id, "B13BWzWWWzB9B") != 0)
+ return False;
+ break;
+ case 91:
+ if (strcmp(id, "B13BWzWWWzB9BB9BWzWWzWW") != 0)
+ return False;
+ break;
+ default:
+ return False;
+ }
+ return True;
}
-static int fill_share_info(connection_struct *conn, const vuser_key *key,
- int snum, int uLevel,
- char** buf, int* buflen,
- char** stringbuf, int* stringspace, char* baseaddr)
+static int fill_share_info(connection_struct * conn, const vuser_key * key,
+ int snum, int uLevel,
+ char **buf, int *buflen,
+ char **stringbuf, int *stringspace, char *baseaddr)
{
- int struct_len;
- char* p;
- char* p2;
- int l2;
- int len;
-
- switch( uLevel ) {
- case 0: struct_len = 13; break;
- case 1: struct_len = 20; break;
- case 2: struct_len = 40; break;
- case 91: struct_len = 68; break;
- default: return -1;
- }
-
-
- if (!buf)
- {
- len = 0;
- if (uLevel > 0) len += StrlenExpanded(conn,key,snum,lp_comment(snum));
- if (uLevel > 1) len += strlen(lp_pathname(snum)) + 1;
- if (buflen) *buflen = struct_len;
- if (stringspace) *stringspace = len;
- return struct_len + len;
- }
-
- len = struct_len;
- p = *buf;
- if ((*buflen) < struct_len) return -1;
- if (stringbuf)
- {
- p2 = *stringbuf;
- l2 = *stringspace;
- }
- else
- {
- p2 = p + struct_len;
- l2 = (*buflen) - struct_len;
- }
- if (!baseaddr) baseaddr = p;
-
- StrnCpy(p,lp_servicename(snum),13);
-
- if (uLevel > 0)
- {
- int type;
- CVAL(p,13) = 0;
- type = STYPE_DISKTREE;
- if (lp_print_ok(snum)) type = STYPE_PRINTQ;
- if (strequal("IPC$",lp_servicename(snum))) type = STYPE_IPC;
- SSVAL(p,14,type); /* device type */
- SIVAL(p,16,PTR_DIFF(p2,baseaddr));
- len += CopyExpanded(conn,key, snum,&p2,lp_comment(snum),&l2);
- }
-
- if (uLevel > 1)
- {
- SSVAL(p,20,ACCESS_READ|ACCESS_WRITE|ACCESS_CREATE); /* permissions */
- SSVALS(p,22,-1); /* max uses */
- SSVAL(p,24,1); /* current uses */
- SIVAL(p,26,PTR_DIFF(p2,baseaddr)); /* local pathname */
- len += CopyAndAdvance(&p2,lp_pathname(snum),&l2);
- memset(p+30,0,SHPWLEN+2); /* passwd (reserved), pad field */
- }
-
- if (uLevel > 2)
- {
- memset(p+40,0,SHPWLEN+2);
- SSVAL(p,50,0);
- SIVAL(p,52,0);
- SSVAL(p,56,0);
- SSVAL(p,58,0);
- SIVAL(p,60,0);
- SSVAL(p,64,0);
- SSVAL(p,66,0);
- }
-
- if (stringbuf)
- {
- (*buf) = p + struct_len;
- (*buflen) -= struct_len;
- (*stringbuf) = p2;
- (*stringspace) = l2;
- }
- else
- {
- (*buf) = p2;
- (*buflen) -= len;
- }
- return len;
+ int struct_len;
+ char *p;
+ char *p2;
+ int l2;
+ int len;
+
+ switch (uLevel)
+ {
+ case 0:
+ struct_len = 13;
+ break;
+ case 1:
+ struct_len = 20;
+ break;
+ case 2:
+ struct_len = 40;
+ break;
+ case 91:
+ struct_len = 68;
+ break;
+ default:
+ return -1;
+ }
+
+
+ if (!buf)
+ {
+ len = 0;
+ if (uLevel > 0)
+ len +=
+ StrlenExpanded(conn, key, snum,
+ lp_comment(snum));
+ if (uLevel > 1)
+ len += strlen(lp_pathname(snum)) + 1;
+ if (buflen)
+ *buflen = struct_len;
+ if (stringspace)
+ *stringspace = len;
+ return struct_len + len;
+ }
+
+ len = struct_len;
+ p = *buf;
+ if ((*buflen) < struct_len)
+ return -1;
+ if (stringbuf)
+ {
+ p2 = *stringbuf;
+ l2 = *stringspace;
+ }
+ else
+ {
+ p2 = p + struct_len;
+ l2 = (*buflen) - struct_len;
+ }
+ if (!baseaddr)
+ baseaddr = p;
+
+ StrnCpy(p, lp_servicename(snum), 13);
+
+ if (uLevel > 0)
+ {
+ int type;
+ CVAL(p, 13) = 0;
+ type = STYPE_DISKTREE;
+ if (lp_print_ok(snum))
+ type = STYPE_PRINTQ;
+ if (strequal("IPC$", lp_servicename(snum)))
+ type = STYPE_IPC;
+ SSVAL(p, 14, type); /* device type */
+ SIVAL(p, 16, PTR_DIFF(p2, baseaddr));
+ len +=
+ CopyExpanded(conn, key, snum, &p2, lp_comment(snum),
+ &l2);
+ }
+
+ if (uLevel > 1)
+ {
+ SSVAL(p, 20, ACCESS_READ | ACCESS_WRITE | ACCESS_CREATE); /* permissions */
+ SSVALS(p, 22, -1); /* max uses */
+ SSVAL(p, 24, 1); /* current uses */
+ SIVAL(p, 26, PTR_DIFF(p2, baseaddr)); /* local pathname */
+ len += CopyAndAdvance(&p2, lp_pathname(snum), &l2);
+ memset(p + 30, 0, SHPWLEN + 2); /* passwd (reserved), pad field */
+ }
+
+ if (uLevel > 2)
+ {
+ memset(p + 40, 0, SHPWLEN + 2);
+ SSVAL(p, 50, 0);
+ SIVAL(p, 52, 0);
+ SSVAL(p, 56, 0);
+ SSVAL(p, 58, 0);
+ SIVAL(p, 60, 0);
+ SSVAL(p, 64, 0);
+ SSVAL(p, 66, 0);
+ }
+
+ if (stringbuf)
+ {
+ (*buf) = p + struct_len;
+ (*buflen) -= struct_len;
+ (*stringbuf) = p2;
+ (*stringspace) = l2;
+ }
+ else
+ {
+ (*buf) = p2;
+ (*buflen) -= len;
+ }
+ return len;
}
-static BOOL api_RNetShareGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_RNetShareGetInfo(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt,
+ int mprcnt, char **rdata, char **rparam,
+ int *rdata_len, int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *netname = skip_string(str2,1);
- char *p = skip_string(netname,1);
- int uLevel = SVAL(p,0);
- int snum = find_service(netname);
+ char *str1 = param + 2;
+ char *str2 = skip_string(str1, 1);
+ char *netname = skip_string(str2, 1);
+ char *p = skip_string(netname, 1);
+ int uLevel = SVAL(p, 0);
+ int snum = find_service(netname);
VUSER_KEY;
-
- if (snum < 0) return False;
-
- /* check it's a supported varient */
- if (!prefix_ok(str1,"zWrLh")) return False;
- if (!check_share_info(uLevel,str2)) return False;
-
- *rdata = REALLOC(*rdata,mdrcnt);
- p = *rdata;
- *rdata_len = fill_share_info(conn,&key,snum,uLevel,&p,&mdrcnt,0,0,0);
- if (*rdata_len < 0) return False;
-
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
- SSVAL(*rparam,4,*rdata_len);
-
- return(True);
+
+ if (snum < 0)
+ return False;
+
+ /* check it's a supported varient */
+ if (!prefix_ok(str1, "zWrLh"))
+ return False;
+ if (!check_share_info(uLevel, str2))
+ return False;
+
+ *rdata = REALLOC(*rdata, mdrcnt);
+ p = *rdata;
+ *rdata_len =
+ fill_share_info(conn, &key, snum, uLevel, &p, &mdrcnt, 0, 0,
+ 0);
+ if (*rdata_len < 0)
+ return False;
+
+ *rparam_len = 6;
+ *rparam = REALLOC(*rparam, *rparam_len);
+ SSVAL(*rparam, 0, NERR_Success);
+ SSVAL(*rparam, 2, 0); /* converter word */
+ SSVAL(*rparam, 4, *rdata_len);
+
+ return (True);
}
/****************************************************************************
view list of shares available
****************************************************************************/
-static BOOL api_RNetShareEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_RNetShareEnum(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt, int mprcnt,
+ char **rdata, char **rparam, int *rdata_len,
+ int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel = SVAL(p,0);
- int buf_len = SVAL(p,2);
- char *p2;
- int count=lp_numservices();
- int total=0,counted=0;
- BOOL missed = False;
- int i;
- int data_len, fixed_len, string_len;
- int f_len = 0, s_len = 0;
+ char *str1 = param + 2;
+ char *str2 = skip_string(str1, 1);
+ char *p = skip_string(str2, 1);
+ int uLevel = SVAL(p, 0);
+ int buf_len = SVAL(p, 2);
+ char *p2;
+ int count = lp_numservices();
+ int total = 0, counted = 0;
+ BOOL missed = False;
+ int i;
+ int data_len, fixed_len, string_len;
+ int f_len = 0, s_len = 0;
VUSER_KEY;
-
- if (!prefix_ok(str1,"WrLeh")) return False;
- if (!check_share_info(uLevel,str2)) return False;
-
- data_len = fixed_len = string_len = 0;
- for (i=0;i<count;i++)
- if (lp_browseable(i) && lp_snum_ok(i))
- {
- total++;
- data_len += fill_share_info(conn,&key,i,uLevel,0,&f_len,0,&s_len,0);
- if (data_len <= buf_len)
- {
- counted++;
- fixed_len += f_len;
- string_len += s_len;
- }
- else
- missed = True;
- }
- *rdata_len = fixed_len + string_len;
- *rdata = REALLOC(*rdata,*rdata_len);
- memset(*rdata,0,*rdata_len);
-
- p2 = (*rdata) + fixed_len; /* auxillery data (strings) will go here */
- p = *rdata;
- f_len = fixed_len;
- s_len = string_len;
- for (i = 0; i < count;i++)
- if (lp_browseable(i) && lp_snum_ok(i))
- if (fill_share_info(conn,&key,i,uLevel,&p,&f_len,&p2,&s_len,*rdata) < 0)
- break;
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVAL(*rparam,0,missed ? ERRmoredata : NERR_Success);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,counted);
- SSVAL(*rparam,6,total);
-
- DEBUG(3,("RNetShareEnum gave %d entries of %d (%d %d %d %d)\n",
- counted,total,uLevel,
- buf_len,*rdata_len,mdrcnt));
- return(True);
+
+ if (!prefix_ok(str1, "WrLeh"))
+ return False;
+ if (!check_share_info(uLevel, str2))
+ return False;
+
+ data_len = fixed_len = string_len = 0;
+ for (i = 0; i < count; i++)
+ if (lp_browseable(i) && lp_snum_ok(i))
+ {
+ total++;
+ data_len +=
+ fill_share_info(conn, &key, i, uLevel, 0,
+ &f_len, 0, &s_len, 0);
+ if (data_len <= buf_len)
+ {
+ counted++;
+ fixed_len += f_len;
+ string_len += s_len;
+ }
+ else
+ missed = True;
+ }
+ *rdata_len = fixed_len + string_len;
+ *rdata = REALLOC(*rdata, *rdata_len);
+ memset(*rdata, 0, *rdata_len);
+
+ p2 = (*rdata) + fixed_len; /* auxillery data (strings) will go here */
+ p = *rdata;
+ f_len = fixed_len;
+ s_len = string_len;
+ for (i = 0; i < count; i++)
+ if (lp_browseable(i) && lp_snum_ok(i))
+ if (fill_share_info
+ (conn, &key, i, uLevel, &p, &f_len, &p2, &s_len,
+ *rdata) < 0)
+ break;
+
+ *rparam_len = 8;
+ *rparam = REALLOC(*rparam, *rparam_len);
+ SSVAL(*rparam, 0, missed ? ERRmoredata : NERR_Success);
+ SSVAL(*rparam, 2, 0);
+ SSVAL(*rparam, 4, counted);
+ SSVAL(*rparam, 6, total);
+
+ DEBUG(3, ("RNetShareEnum gave %d entries of %d (%d %d %d %d)\n",
+ counted, total, uLevel, buf_len, *rdata_len, mdrcnt));
+ return (True);
}
/****************************************************************************
get the time of day info
****************************************************************************/
-static BOOL api_NetRemoteTOD(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_NetRemoteTOD(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt, int mprcnt,
+ char **rdata, char **rparam, int *rdata_len,
+ int *rparam_len)
{
- char *p;
- *rparam_len = 4;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- *rdata_len = 21;
- *rdata = REALLOC(*rdata,*rdata_len);
-
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
-
- p = *rdata;
+ char *p;
+ *rparam_len = 4;
+ *rparam = REALLOC(*rparam, *rparam_len);
- {
- struct tm *t;
- time_t unixdate = time(NULL);
+ *rdata_len = 21;
+ *rdata = REALLOC(*rdata, *rdata_len);
- put_dos_date3(p,0,unixdate); /* this is the time that is looked at
- by NT in a "net time" operation,
- it seems to ignore the one below */
+ SSVAL(*rparam, 0, NERR_Success);
+ SSVAL(*rparam, 2, 0); /* converter word */
- /* the client expects to get localtime, not GMT, in this bit
- (I think, this needs testing) */
- t = LocalTime(&unixdate);
+ p = *rdata;
- SIVAL(p,4,0); /* msecs ? */
- CVAL(p,8) = t->tm_hour;
- CVAL(p,9) = t->tm_min;
- CVAL(p,10) = t->tm_sec;
- CVAL(p,11) = 0; /* hundredths of seconds */
- SSVALS(p,12,TimeDiff(unixdate)/60); /* timezone in minutes from GMT */
- SSVAL(p,14,10000); /* timer interval in 0.0001 of sec */
- CVAL(p,16) = t->tm_mday;
- CVAL(p,17) = t->tm_mon + 1;
- SSVAL(p,18,1900+t->tm_year);
- CVAL(p,20) = t->tm_wday;
- }
+ {
+ struct tm *t;
+ time_t unixdate = time(NULL);
+
+ put_dos_date3(p, 0, unixdate); /* this is the time that is looked at
+ by NT in a "net time" operation,
+ it seems to ignore the one below */
+
+ /* the client expects to get localtime, not GMT, in this bit
+ (I think, this needs testing) */
+ t = LocalTime(&unixdate);
+
+ SIVAL(p, 4, 0); /* msecs ? */
+ CVAL(p, 8) = t->tm_hour;
+ CVAL(p, 9) = t->tm_min;
+ CVAL(p, 10) = t->tm_sec;
+ CVAL(p, 11) = 0; /* hundredths of seconds */
+ SSVALS(p, 12, TimeDiff(unixdate) / 60); /* timezone in minutes from GMT */
+ SSVAL(p, 14, 10000); /* timer interval in 0.0001 of sec */
+ CVAL(p, 16) = t->tm_mday;
+ CVAL(p, 17) = t->tm_mon + 1;
+ SSVAL(p, 18, 1900 + t->tm_year);
+ CVAL(p, 20) = t->tm_wday;
+ }
- return(True);
+ return (True);
}
/****************************************************************************
set the user password
****************************************************************************/
-static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_SetUserPassword(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt,
+ int mprcnt, char **rdata, char **rparam,
+ int *rdata_len, int *rparam_len)
{
- char *p = skip_string(param+2,2);
- fstring user;
- fstring pass1,pass2;
- uchar pwbuf[516];
- uchar nt_pw[16];
- uchar lm_pw[16];
-
- fstrcpy(user,p);
+ char *p = skip_string(param + 2, 2);
+ fstring user;
+ fstring pass1, pass2;
+ uchar pwbuf[516];
+ uchar nt_pw[16];
+ uchar lm_pw[16];
- p = skip_string(p,1);
+ fstrcpy(user, p);
- memcpy(pass1,p,16);
- memcpy(pass2,p+16,16);
+ p = skip_string(p, 1);
- *rparam_len = 4;
- *rparam = REALLOC(*rparam,*rparam_len);
+ memcpy(pass1, p, 16);
+ memcpy(pass2, p + 16, 16);
- *rdata_len = 0;
+ *rparam_len = 4;
+ *rparam = REALLOC(*rparam, *rparam_len);
- SSVAL(*rparam,0,NERR_badpass);
- SSVAL(*rparam,2,0); /* converter word */
+ *rdata_len = 0;
- DEBUG(3,("Set password for <%s>\n",user));
+ SSVAL(*rparam, 0, NERR_badpass);
+ SSVAL(*rparam, 2, 0); /* converter word */
- /*
- * Pass the user through the NT -> unix user mapping
- * function.
- */
+ DEBUG(3, ("Set password for <%s>\n", user));
- (void)map_username(user);
+ /*
+ * Pass the user through the NT -> unix user mapping
+ * function.
+ */
- /*
- * Do any UNIX username case mangling.
- */
- (void)Get_Pwnam( user, True);
+ (void)map_username(user);
- if (strequal(param + 2, "zb16b16WW"))
- {
- /*
- * attempt the encrypted pw change. NT will generate this
- * after trying the samr method.
- */
+ /*
+ * Do any UNIX username case mangling.
+ */
+ (void)Get_Pwnam(user, True);
- if (SVAL(*rparam,0) != NERR_Success)
+ if (strequal(param + 2, "zb16b16WW"))
{
- if (make_oem_passwd_hash(pwbuf, pass1, 16, NULL, False) &&
- msrpc_sam_ntpasswd_set("\\\\.", user, NULL,
- pwbuf, pass2, /* lm pw */
- NULL, NULL)) /* nt pw */
+ /*
+ * attempt the encrypted pw change. NT will generate this
+ * after trying the samr method.
+ */
+
+ if (SVAL(*rparam, 0) != NERR_Success)
{
- SSVAL(*rparam,0,NERR_Success);
+ if (make_oem_passwd_hash
+ (pwbuf, pass1, 16, NULL, False)
+ && msrpc_sam_ntpasswd_set("\\\\.", user, NULL,
+ pwbuf, pass2, /* lm pw */
+ NULL, NULL)) /* nt pw */
+ {
+ SSVAL(*rparam, 0, NERR_Success);
+ }
}
}
- }
- else
- {
- /*
- * Attempt the plaintext password change first.
- * Older versions of Windows seem to do this.
- */
-
- nt_lm_owf_gen(pass1, nt_pw, lm_pw);
- if (msrpc_sam_ntchange_pwd("\\\\.", user, global_sam_name,
- lm_pw, nt_pw, pass2))
+ else
{
- SSVAL(*rparam,0,NERR_Success);
+ /*
+ * Attempt the plaintext password change first.
+ * Older versions of Windows seem to do this.
+ */
+
+ nt_lm_owf_gen(pass1, nt_pw, lm_pw);
+ if (msrpc_sam_ntchange_pwd("\\\\.", user, global_sam_name,
+ lm_pw, nt_pw, pass2))
+ {
+ SSVAL(*rparam, 0, NERR_Success);
+ }
}
- }
ZERO_STRUCT(pwbuf);
ZERO_STRUCT(pass1);
ZERO_STRUCT(pass2);
- return(True);
+ return (True);
}
/****************************************************************************
Set the user password (SamOEM version - gets plaintext).
****************************************************************************/
-static BOOL api_SamOEMChangePassword(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_SamOEMChangePassword(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt,
+ int mprcnt, char **rdata, char **rparam,
+ int *rdata_len, int *rparam_len)
{
- fstring user;
- char *p = param + 2;
- *rparam_len = 2;
- *rparam = REALLOC(*rparam,*rparam_len);
+ fstring user;
+ char *p = param + 2;
+ *rparam_len = 2;
+ *rparam = REALLOC(*rparam, *rparam_len);
- *rdata_len = 0;
+ *rdata_len = 0;
- SSVAL(*rparam,0,NERR_badpass);
+ SSVAL(*rparam, 0, NERR_badpass);
- /*
- * Check the parameter definition is correct.
- */
- if (!strequal(param + 2, "zsT")) {
- DEBUG(0,("api_SamOEMChangePassword: Invalid parameter string %s\n", param + 2));
- return False;
- }
- p = skip_string(p, 1);
-
- if (!strequal(p, "B516B16")) {
- DEBUG(0,("api_SamOEMChangePassword: Invalid data parameter string %s\n", p));
- return False;
- }
- p = skip_string(p,1);
-
- fstrcpy(user,p);
- p = skip_string(p,1);
-
- DEBUG(3,("api_SamOEMChangePassword: Change password for <%s>\n",user));
-
- if (msrpc_sam_ntpasswd_set("\\\\.", user, NULL,
- (uchar*) data, (uchar *)&data[516], /* lm pw */
- NULL, NULL)) /* nt pw */
- {
- SSVAL(*rparam,0,NERR_Success);
- }
-
- return(True);
+ /*
+ * Check the parameter definition is correct.
+ */
+ if (!strequal(param + 2, "zsT"))
+ {
+ DEBUG(0,
+ ("api_SamOEMChangePassword: Invalid parameter string %s\n",
+ param + 2));
+ return False;
+ }
+ p = skip_string(p, 1);
+
+ if (!strequal(p, "B516B16"))
+ {
+ DEBUG(0,
+ ("api_SamOEMChangePassword: Invalid data parameter string %s\n",
+ p));
+ return False;
+ }
+ p = skip_string(p, 1);
+
+ fstrcpy(user, p);
+ p = skip_string(p, 1);
+
+ DEBUG(3,
+ ("api_SamOEMChangePassword: Change password for <%s>\n", user));
+
+ if (msrpc_sam_ntpasswd_set("\\\\.", user, NULL,
+ (uchar *) data, (uchar *) & data[516], /* lm pw */
+ NULL, NULL)) /* nt pw */
+ {
+ SSVAL(*rparam, 0, NERR_Success);
+ }
+
+ return (True);
}
/****************************************************************************
delete a print job
Form: <W> <>
****************************************************************************/
-static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_RDosPrintJobDel(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt,
+ int mprcnt, char **rdata, char **rparam,
+ int *rdata_len, int *rparam_len)
{
- int function = SVAL(param,0);
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int jobid, snum;
- int i, count;
+ int function = SVAL(param, 0);
+ char *str1 = param + 2;
+ char *str2 = skip_string(str1, 1);
+ char *p = skip_string(str2, 1);
+ int jobid, snum;
+ int i, count;
VUSER_KEY;
- printjob_decode(SVAL(p,0), &snum, &jobid);
-
- /* check it's a supported varient */
- if (!(strcsequal(str1,"W") && strcsequal(str2,"")))
- return(False);
-
- *rparam_len = 4;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- *rdata_len = 0;
-
- SSVAL(*rparam,0,NERR_Success);
-
- if (snum >= 0 && VALID_SNUM(snum))
- {
- print_queue_struct *queue=NULL;
- lpq_reset(snum);
- count = get_printqueue(snum,conn,&key,&queue,NULL);
-
- for (i=0;i<count;i++)
- if ((queue[i].job&0xFF) == jobid)
- {
- switch (function) {
- case 81: /* delete */
- DEBUG(3,("Deleting queue entry %d\n",queue[i].job));
- del_printqueue(conn,&key,snum,queue[i].job);
- break;
- case 82: /* pause */
- case 83: /* resume */
- DEBUG(3,("%s queue entry %d\n",
- (function==82?"pausing":"resuming"),queue[i].job));
- status_printjob(conn,&key,snum,queue[i].job,
- (function==82?LPQ_PAUSED:LPQ_QUEUED));
- break;
- }
- break;
- }
-
- if (i==count)
- SSVAL(*rparam,0,NERR_JobNotFound);
-
- if (queue) free(queue);
- }
-
- SSVAL(*rparam,2,0); /* converter word */
-
- return(True);
+ printjob_decode(SVAL(p, 0), &snum, &jobid);
+
+ /* check it's a supported varient */
+ if (!(strcsequal(str1, "W") && strcsequal(str2, "")))
+ return (False);
+
+ *rparam_len = 4;
+ *rparam = REALLOC(*rparam, *rparam_len);
+
+ *rdata_len = 0;
+
+ SSVAL(*rparam, 0, NERR_Success);
+
+ if (snum >= 0 && VALID_SNUM(snum))
+ {
+ print_queue_struct *queue = NULL;
+ lpq_reset(snum);
+ count = get_printqueue(snum, conn, &key, &queue, NULL);
+
+ for (i = 0; i < count; i++)
+ if ((queue[i].job & 0xFF) == jobid)
+ {
+ switch (function)
+ {
+ case 81: /* delete */
+ DEBUG(3,
+ ("Deleting queue entry %d\n",
+ queue[i].job));
+ del_printqueue(conn, &key,
+ snum,
+ queue[i].job);
+ break;
+ case 82: /* pause */
+ case 83: /* resume */
+ DEBUG(3,
+ ("%s queue entry %d\n",
+ (function ==
+ 82 ? "pausing" :
+ "resuming"),
+ queue[i].job));
+ status_printjob(conn, &key,
+ snum,
+ queue[i].job,
+ (function ==
+ 82 ?
+ LPQ_PAUSED :
+ LPQ_QUEUED));
+ break;
+ }
+ break;
+ }
+
+ if (i == count)
+ SSVAL(*rparam, 0, NERR_JobNotFound);
+
+ if (queue)
+ free(queue);
+ }
+
+ SSVAL(*rparam, 2, 0); /* converter word */
+
+ return (True);
}
/****************************************************************************
Purge a print queue - or pause or resume it.
****************************************************************************/
-static BOOL api_WPrintQueuePurge(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_WPrintQueuePurge(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt,
+ int mprcnt, char **rdata, char **rparam,
+ int *rdata_len, int *rparam_len)
{
- int function = SVAL(param,0);
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *QueueName = skip_string(str2,1);
- int snum;
+ int function = SVAL(param, 0);
+ char *str1 = param + 2;
+ char *str2 = skip_string(str1, 1);
+ char *QueueName = skip_string(str2, 1);
+ int snum;
VUSER_KEY;
- /* check it's a supported varient */
- if (!(strcsequal(str1,"z") && strcsequal(str2,"")))
- return(False);
-
- *rparam_len = 4;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- *rdata_len = 0;
-
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
-
- snum = lp_servicenumber(QueueName);
- if (snum < 0 && pcap_printername_ok(QueueName,NULL)) {
- int pnum = lp_servicenumber(PRINTERS_NAME);
- if (pnum >= 0) {
- lp_add_printer(QueueName,pnum);
- snum = lp_servicenumber(QueueName);
- }
- }
-
- if (snum >= 0 && VALID_SNUM(snum)) {
- lpq_reset(snum);
-
- switch (function) {
- case 74: /* Pause queue */
- case 75: /* Resume queue */
- {
- status_printqueue(conn,&key,snum,(function==74?LPSTAT_STOPPED:LPSTAT_OK));
- DEBUG(3,("Print queue %s, queue=%s\n",
- (function==74?"pause":"resume"),QueueName));
- break;
- }
- case 103: /* Purge */
- {
- print_queue_struct *queue=NULL;
- int i, count;
- count = get_printqueue(snum,conn,&key,&queue,NULL);
- for (i = 0; i < count; i++)
- del_printqueue(conn,&key,snum,queue[i].job);
-
- if (queue) free(queue);
- DEBUG(3,("Print queue purge, queue=%s\n",QueueName));
- break;
- }
- }
- }
-
- return(True);
+ /* check it's a supported varient */
+ if (!(strcsequal(str1, "z") && strcsequal(str2, "")))
+ return (False);
+
+ *rparam_len = 4;
+ *rparam = REALLOC(*rparam, *rparam_len);
+
+ *rdata_len = 0;
+
+ SSVAL(*rparam, 0, NERR_Success);
+ SSVAL(*rparam, 2, 0); /* converter word */
+
+ snum = lp_servicenumber(QueueName);
+ if (snum < 0 && pcap_printername_ok(QueueName, NULL))
+ {
+ int pnum = lp_servicenumber(PRINTERS_NAME);
+ if (pnum >= 0)
+ {
+ lp_add_printer(QueueName, pnum);
+ snum = lp_servicenumber(QueueName);
+ }
+ }
+
+ if (snum >= 0 && VALID_SNUM(snum))
+ {
+ lpq_reset(snum);
+
+ switch (function)
+ {
+ case 74: /* Pause queue */
+ case 75: /* Resume queue */
+ {
+ status_printqueue(conn, &key, snum,
+ (function ==
+ 74 ? LPSTAT_STOPPED :
+ LPSTAT_OK));
+ DEBUG(3,
+ ("Print queue %s, queue=%s\n",
+ (function == 74 ? "pause" : "resume"),
+ QueueName));
+ break;
+ }
+ case 103: /* Purge */
+ {
+ print_queue_struct *queue = NULL;
+ int i, count;
+ count =
+ get_printqueue(snum, conn, &key,
+ &queue, NULL);
+ for (i = 0; i < count; i++)
+ del_printqueue(conn, &key, snum,
+ queue[i].job);
+
+ if (queue)
+ free(queue);
+ DEBUG(3,
+ ("Print queue purge, queue=%s\n",
+ QueueName));
+ break;
+ }
+ }
+ }
+
+ return (True);
}
Form: <WWsTP> <WWzWWDDzzzzzzzzzzlz>
or <WWsTP> <WB21BB16B10zWWzDDz>
****************************************************************************/
-static int check_printjob_info(struct pack_desc* desc,
- int uLevel, char* id)
+static int check_printjob_info(struct pack_desc *desc, int uLevel, char *id)
{
- desc->subformat = NULL;
- switch( uLevel ) {
- case 0: desc->format = "W"; break;
- case 1: desc->format = "WB21BB16B10zWWzDDz"; break;
- case 2: desc->format = "WWzWWDDzz"; break;
- case 3: desc->format = "WWzWWDDzzzzzzzzzzlz"; break;
- default: return False;
- }
- if (strcmp(desc->format,id) != 0) return False;
- return True;
+ desc->subformat = NULL;
+ switch (uLevel)
+ {
+ case 0:
+ desc->format = "W";
+ break;
+ case 1:
+ desc->format = "WB21BB16B10zWWzDDz";
+ break;
+ case 2:
+ desc->format = "WWzWWDDzz";
+ break;
+ case 3:
+ desc->format = "WWzWWDDzzzzzzzzzzlz";
+ break;
+ default:
+ return False;
+ }
+ if (strcmp(desc->format, id) != 0)
+ return False;
+ return True;
}
-static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_PrintJobInfo(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt, int mprcnt,
+ char **rdata, char **rparam, int *rdata_len,
+ int *rparam_len)
{
struct pack_desc desc;
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
+ char *str1 = param + 2;
+ char *str2 = skip_string(str1, 1);
+ char *p = skip_string(str2, 1);
int jobid, snum;
- int uLevel = SVAL(p,2);
- int function = SVAL(p,4); /* what is this ?? */
+ int uLevel = SVAL(p, 2);
+ int function = SVAL(p, 4); /* what is this ?? */
int i;
char *s = data;
files_struct *fsp;
VUSER_KEY;
- printjob_decode(SVAL(p,0), &snum, &jobid);
-
+ printjob_decode(SVAL(p, 0), &snum, &jobid);
+
*rparam_len = 4;
- *rparam = REALLOC(*rparam,*rparam_len);
-
+ *rparam = REALLOC(*rparam, *rparam_len);
+
*rdata_len = 0;
-
+
/* check it's a supported varient */
- if ((strcmp(str1,"WWsTP")) ||
- (!check_printjob_info(&desc,uLevel,str2)))
- return(False);
-
- switch (function) {
- case 0x6: /* change job place in the queue,
- data gives the new place */
- if (snum >= 0 && VALID_SNUM(snum)) {
- print_queue_struct *queue=NULL;
- int count;
-
- lpq_reset(snum);
- count = get_printqueue(snum,conn,&key,&queue,NULL);
- for (i=0;i<count;i++) /* find job */
- if ((queue[i].job&0xFF) == jobid) break;
-
- if (i==count) {
- desc.errcode=NERR_JobNotFound;
- if (queue) free(queue);
- } else {
- desc.errcode=NERR_Success;
- i++;
-#if 0
+ if ((strcmp(str1, "WWsTP")) ||
+ (!check_printjob_info(&desc, uLevel, str2)))
+ return (False);
+
+ switch (function)
+ {
+ case 0x6: /* change job place in the queue,
+ data gives the new place */
+ if (snum >= 0 && VALID_SNUM(snum))
+ {
+ print_queue_struct *queue = NULL;
+ int count;
+
+ lpq_reset(snum);
+ count =
+ get_printqueue(snum, conn, &key,
+ &queue, NULL);
+ for (i = 0; i < count; i++) /* find job */
+ if ((queue[i].job & 0xFF) == jobid)
+ break;
+
+ if (i == count)
{
- int place= SVAL(data,0);
- /* we currently have no way of
- doing this. Can any unix do it? */
- if (i < place) /* move down */;
- else if (i > place ) /* move up */;
+ desc.errcode = NERR_JobNotFound;
+ if (queue)
+ free(queue);
}
+ else
+ {
+ desc.errcode = NERR_Success;
+ i++;
+#if 0
+ {
+ int place = SVAL(data, 0);
+ /* we currently have no way of
+ doing this. Can any unix do it? */
+ if (i <
+ place) /* move down */ ;
+ else if (i > place) /* move up */
+ ;
+ }
#endif
- desc.errcode=NERR_notsupported; /* not yet
- supported */
- if (queue) free(queue);
+ desc.errcode = NERR_notsupported; /* not yet
+ supported */
+ if (queue)
+ free(queue);
+ }
}
- } else {
- desc.errcode=NERR_JobNotFound;
- }
- break;
-
- case 0xb: /* change print job name, data gives the name */
- /* jobid, snum should be zero */
- if (isalpha((int)*s)) {
- pstring name;
- int l = 0;
- while (l<64 && *s) {
- if (issafe(*s)) name[l++] = *s;
- s++;
- }
- name[l] = 0;
-
- DEBUG(3,("Setting print name to %s\n",name));
-
- fsp = file_find_print();
-
- if (fsp) {
- connection_struct *fconn = fsp->conn;
- unbecome_user();
-
- if (!become_user(fconn,vuid) ||
- !become_service(fconn,True))
+ else
+ {
+ desc.errcode = NERR_JobNotFound;
+ }
+ break;
+
+ case 0xb: /* change print job name, data gives the name */
+ /* jobid, snum should be zero */
+ if (isalpha((int)*s))
+ {
+ pstring name;
+ int l = 0;
+ while (l < 64 && *s)
+ {
+ if (issafe(*s))
+ name[l++] = *s;
+ s++;
+ }
+ name[l] = 0;
+
+ DEBUG(3,
+ ("Setting print name to %s\n", name));
+
+ fsp = file_find_print();
+
+ if (fsp)
+ {
+ pstring zfrom, zto;
+ connection_struct *fconn = fsp->conn;
+ unbecome_user();
+
+ if (!become_user(fconn, vuid) ||
+ !become_service(fconn, True))
+ break;
+
+ pstrcpy(zfrom,
+ dos_to_unix(fsp->fsp_name,
+ False));
+ pstrcpy(zto,
+ dos_to_unix(name, False));
+
+ if (fsp->conn->
+ vfs_ops.rename(zfrom, zto) == 0)
+ {
+ string_set(&fsp->fsp_name,
+ name);
+ }
break;
-
- if (conn->vfs_ops.rename(dos_to_unix(fsp->fsp_name,False),name) == 0) {
- string_set(&fsp->fsp_name,name);
}
- break;
}
- }
- desc.errcode=NERR_Success;
- break;
+ desc.errcode = NERR_Success;
+ break;
- default: /* not implemented */
- return False;
+ default: /* not implemented */
+ return False;
}
-
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0); /* converter word */
-
- return(True);
+
+ SSVALS(*rparam, 0, desc.errcode);
+ SSVAL(*rparam, 2, 0); /* converter word */
+
+ return (True);
}
/****************************************************************************
get info about the server
****************************************************************************/
-static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_RNetServerGetInfo(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt,
+ int mprcnt, char **rdata, char **rparam,
+ int *rdata_len, int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel = SVAL(p,0);
- char *p2;
- int struct_len;
+ char *str1 = param + 2;
+ char *str2 = skip_string(str1, 1);
+ char *p = skip_string(str2, 1);
+ int uLevel = SVAL(p, 0);
+ char *p2;
+ int struct_len;
VUSER_KEY;
- DEBUG(4,("NetServerGetInfo level %d\n",uLevel));
-
- /* check it's a supported varient */
- if (!prefix_ok(str1,"WrLh")) return False;
- switch( uLevel ) {
- case 0:
- if (strcmp(str2,"B16") != 0) return False;
- struct_len = 16;
- break;
- case 1:
- if (strcmp(str2,"B16BBDz") != 0) return False;
- struct_len = 26;
- break;
- case 2:
- if (strcmp(str2,"B16BBDzDDDWWzWWWWWWWBB21zWWWWWWWWWWWWWWWWWWWWWWz")
- != 0) return False;
- struct_len = 134;
- break;
- case 3:
- if (strcmp(str2,"B16BBDzDDDWWzWWWWWWWBB21zWWWWWWWWWWWWWWWWWWWWWWzDWz")
- != 0) return False;
- struct_len = 144;
- break;
- case 20:
- if (strcmp(str2,"DN") != 0) return False;
- struct_len = 6;
- break;
- case 50:
- if (strcmp(str2,"B16BBDzWWzzz") != 0) return False;
- struct_len = 42;
- break;
- default: return False;
- }
-
- *rdata_len = mdrcnt;
- *rdata = REALLOC(*rdata,*rdata_len);
-
- p = *rdata;
- p2 = p + struct_len;
- if (uLevel != 20) {
- StrnCpy(p,local_machine,16);
- strupper(p);
- }
- p += 16;
- if (uLevel > 0)
- {
- struct srv_info_struct *servers=NULL;
- int i,count;
- pstring comment;
- uint32 servertype= lp_default_server_announce();
-
- pstrcpy(comment,lp_serverstring());
-
- if ((count=get_server_info(SV_TYPE_ALL,&servers,global_myworkgroup))>0) {
- for (i=0;i<count;i++)
- if (strequal(servers[i].name,local_machine))
- {
- servertype = servers[i].type;
- pstrcpy(comment,servers[i].comment);
- }
- }
- if (servers) free(servers);
-
- SCVAL(p,0,lp_major_announce_version());
- SCVAL(p,1,lp_minor_announce_version());
- SIVAL(p,2,servertype);
-
- if (mdrcnt == struct_len) {
- SIVAL(p,6,0);
- } else {
- user_struct *vuser = get_valid_user_struct(&key);
- SIVAL(p,6,PTR_DIFF(p2,*rdata));
- standard_sub(conn,vuser, comment);
- StrnCpy(p2,comment,MAX(mdrcnt - struct_len,0));
- p2 = skip_string(p2,1);
- vuid_free_user_struct(vuser);
+ DEBUG(4, ("NetServerGetInfo level %d\n", uLevel));
+
+ /* check it's a supported varient */
+ if (!prefix_ok(str1, "WrLh"))
+ return False;
+ switch (uLevel)
+ {
+ case 0:
+ if (strcmp(str2, "B16") != 0)
+ return False;
+ struct_len = 16;
+ break;
+ case 1:
+ if (strcmp(str2, "B16BBDz") != 0)
+ return False;
+ struct_len = 26;
+ break;
+ case 2:
+ if (strcmp
+ (str2,
+ "B16BBDzDDDWWzWWWWWWWBB21zWWWWWWWWWWWWWWWWWWWWWWz")
+ != 0)
+ return False;
+ struct_len = 134;
+ break;
+ case 3:
+ if (strcmp
+ (str2,
+ "B16BBDzDDDWWzWWWWWWWBB21zWWWWWWWWWWWWWWWWWWWWWWzDWz")
+ != 0)
+ return False;
+ struct_len = 144;
+ break;
+ case 20:
+ if (strcmp(str2, "DN") != 0)
+ return False;
+ struct_len = 6;
+ break;
+ case 50:
+ if (strcmp(str2, "B16BBDzWWzzz") != 0)
+ return False;
+ struct_len = 42;
+ break;
+ default:
+ return False;
+ }
+
+ *rdata_len = mdrcnt;
+ *rdata = REALLOC(*rdata, *rdata_len);
+
+ p = *rdata;
+ p2 = p + struct_len;
+ if (uLevel != 20)
+ {
+ StrnCpy(p, local_machine, 16);
+ strupper(p);
+ }
+ p += 16;
+ if (uLevel > 0)
+ {
+ struct srv_info_struct *servers = NULL;
+ int i, count;
+ pstring comment;
+ uint32 servertype = lp_default_server_announce();
+
+ pstrcpy(comment,
+ string_truncate(lp_serverstring(),
+ MAX_SERVER_STRING_LENGTH));
+
+ if (
+ (count =
+ get_server_info(SV_TYPE_ALL, &servers,
+ global_myworkgroup)) > 0)
+ {
+ for (i = 0; i < count; i++)
+ if (strequal(servers[i].name, local_machine))
+ {
+ servertype = servers[i].type;
+ pstrcpy(comment, servers[i].comment);
+ }
+ }
+ if (servers)
+ free(servers);
- }
- }
- if (uLevel > 1)
- {
- return False; /* not yet implemented */
- }
+ SCVAL(p, 0, lp_major_announce_version());
+ SCVAL(p, 1, lp_minor_announce_version());
+ SIVAL(p, 2, servertype);
+
+ if (mdrcnt == struct_len)
+ {
+ SIVAL(p, 6, 0);
+ }
+ else
+ {
+ user_struct *vuser = get_valid_user_struct(&key);
+ SIVAL(p, 6, PTR_DIFF(p2, *rdata));
+ standard_sub(conn, vuser, comment);
+ StrnCpy(p2, comment, MAX(mdrcnt - struct_len, 0));
+ p2 = skip_string(p2, 1);
+ vuid_free_user_struct(vuser);
+
+ }
+ }
+ if (uLevel > 1)
+ {
+ return False; /* not yet implemented */
+ }
- *rdata_len = PTR_DIFF(p2,*rdata);
+ *rdata_len = PTR_DIFF(p2, *rdata);
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
- SSVAL(*rparam,4,*rdata_len);
+ *rparam_len = 6;
+ *rparam = REALLOC(*rparam, *rparam_len);
+ SSVAL(*rparam, 0, NERR_Success);
+ SSVAL(*rparam, 2, 0); /* converter word */
+ SSVAL(*rparam, 4, *rdata_len);
- return(True);
+ return (True);
}
/****************************************************************************
get info about the server
****************************************************************************/
-static BOOL api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_NetWkstaGetInfo(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt,
+ int mprcnt, char **rdata, char **rparam,
+ int *rdata_len, int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- char *p2;
- extern pstring sesssetup_user;
- int level = SVAL(p,0);
+ char *str1 = param + 2;
+ char *str2 = skip_string(str1, 1);
+ char *p = skip_string(str2, 1);
+ char *p2;
+ extern pstring sesssetup_user;
+ int level = SVAL(p, 0);
- DEBUG(4,("NetWkstaGetInfo level %d\n",level));
+ DEBUG(4, ("NetWkstaGetInfo level %d\n", level));
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
+ *rparam_len = 6;
+ *rparam = REALLOC(*rparam, *rparam_len);
- /* check it's a supported varient */
- if (!(level==10 && strcsequal(str1,"WrLh") && strcsequal(str2,"zzzBBzz")))
- return(False);
+ /* check it's a supported varient */
+ if (!
+ (level == 10 && strcsequal(str1, "WrLh")
+ && strcsequal(str2, "zzzBBzz")))
+ return (False);
- *rdata_len = mdrcnt + 1024;
- *rdata = REALLOC(*rdata,*rdata_len);
+ *rdata_len = mdrcnt + 1024;
+ *rdata = REALLOC(*rdata, *rdata_len);
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
+ SSVAL(*rparam, 0, NERR_Success);
+ SSVAL(*rparam, 2, 0); /* converter word */
- p = *rdata;
- p2 = p + 22;
+ p = *rdata;
+ p2 = p + 22;
- SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* host name */
- pstrcpy(p2,local_machine);
- strupper(p2);
- p2 = skip_string(p2,1);
- p += 4;
+ SIVAL(p, 0, PTR_DIFF(p2, *rdata)); /* host name */
+ pstrcpy(p2, local_machine);
+ strupper(p2);
+ p2 = skip_string(p2, 1);
+ p += 4;
- SIVAL(p,0,PTR_DIFF(p2,*rdata));
- pstrcpy(p2,sesssetup_user);
- p2 = skip_string(p2,1);
- p += 4;
+ SIVAL(p, 0, PTR_DIFF(p2, *rdata));
+ pstrcpy(p2, sesssetup_user);
+ p2 = skip_string(p2, 1);
+ p += 4;
- SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* login domain */
- pstrcpy(p2,global_myworkgroup);
- strupper(p2);
- p2 = skip_string(p2,1);
- p += 4;
+ SIVAL(p, 0, PTR_DIFF(p2, *rdata)); /* login domain */
+ pstrcpy(p2, global_myworkgroup);
+ strupper(p2);
+ p2 = skip_string(p2, 1);
+ p += 4;
- SCVAL(p,0,lp_major_announce_version()); /* system version - e.g 4 in 4.1 */
- SCVAL(p,1,lp_minor_announce_version()); /* system version - e.g .1 in 4.1 */
- p += 2;
+ SCVAL(p, 0, lp_major_announce_version()); /* system version - e.g 4 in 4.1 */
+ SCVAL(p, 1, lp_minor_announce_version()); /* system version - e.g .1 in 4.1 */
+ p += 2;
- SIVAL(p,0,PTR_DIFF(p2,*rdata));
- pstrcpy(p2,global_myworkgroup); /* don't know. login domain?? */
- p2 = skip_string(p2,1);
- p += 4;
+ SIVAL(p, 0, PTR_DIFF(p2, *rdata));
+ pstrcpy(p2, global_myworkgroup); /* don't know. login domain?? */
+ p2 = skip_string(p2, 1);
+ p += 4;
- SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* don't know */
- pstrcpy(p2,"");
- p2 = skip_string(p2,1);
- p += 4;
+ SIVAL(p, 0, PTR_DIFF(p2, *rdata)); /* don't know */
+ pstrcpy(p2, "");
+ p2 = skip_string(p2, 1);
+ p += 4;
- *rdata_len = PTR_DIFF(p2,*rdata);
+ *rdata_len = PTR_DIFF(p2, *rdata);
- SSVAL(*rparam,4,*rdata_len);
+ SSVAL(*rparam, 4, *rdata_len);
- return(True);
+ return (True);
}
/****************************************************************************
****************************************************************************/
-#define usri11_name 0
+#define usri11_name 0
#define usri11_pad 21
#define usri11_comment 22
#define usri11_usr_comment 26
#define USER_PRIV_USER 1
#define USER_PRIV_ADMIN 2
-#define AF_OP_PRINT 0
+#define AF_OP_PRINT 0
#define AF_OP_COMM 1
#define AF_OP_SERVER 2
#define AF_OP_ACCOUNTS 3
-static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_RNetUserGetInfo(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt,
+ int mprcnt, char **rdata, char **rparam,
+ int *rdata_len, int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *UserName = skip_string(str2,1);
- char *p = skip_string(UserName,1);
- int uLevel = SVAL(p,0);
+ char *str1 = param + 2;
+ char *str2 = skip_string(str1, 1);
+ char *UserName = skip_string(str2, 1);
+ char *p = skip_string(UserName, 1);
+ int uLevel = SVAL(p, 0);
char *p2;
fstring nt_name;
fstring home_dir;
fstring logon_srv;
- /* get NIS home of a previously validated user - simeon */
- /* With share level security vuid will always be zero.
- Don't depend on vuser being non-null !!. JRA */
- user_struct *vuser = NULL;
- /* moved here due to initialization code (req for IRIX cc) */
+ /* get NIS home of a previously validated user - simeon */
+ /* With share level security vuid will always be zero.
+ Don't depend on vuser being non-null !!. JRA */
+ user_struct *vuser = NULL;
+ /* moved here due to initialization code (req for IRIX cc) */
VUSER_KEY;
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
+ *rparam_len = 6;
+ *rparam = REALLOC(*rparam, *rparam_len);
+
+ DEBUG(4, ("RNetUserGetInfo level=%d\n", uLevel));
- DEBUG(4,("RNetUserGetInfo level=%d\n", uLevel));
-
/* check it's a supported variant */
- if (strcmp(str1,"zWrLh") != 0) return False;
- switch( uLevel )
- {
- case 0: p2 = "B21"; break;
- case 1: p2 = "B21BB16DWzzWz"; break;
- case 2: p2 = "B21BB16DWzzWzDzzzzDDDDWb21WWzWW"; break;
- case 10: p2 = "B21Bzzz"; break;
- case 11: p2 = "B21BzzzWDDzzDDWWzWzDWb21W"; break;
+ if (strcmp(str1, "zWrLh") != 0)
+ return False;
+ switch (uLevel)
+ {
+ case 0:
+ p2 = "B21";
+ break;
+ case 1:
+ p2 = "B21BB16DWzzWz";
+ break;
+ case 2:
+ p2 = "B21BB16DWzzWzDzzzzDDDDWb21WWzWW";
+ break;
+ case 10:
+ p2 = "B21Bzzz";
+ break;
+ case 11:
+ p2 = "B21BzzzWDDzzDDWWzWzDWb21W";
+ break;
default:
{
vuid_free_user_struct(vuser);
}
}
- if (strcmp(p2,str2) != 0)
+ if (strcmp(p2, str2) != 0)
+ {
+ return False;
+ }
+
+ vuser = get_valid_user_struct(&key);
+ if (vuser != NULL)
+ {
+ DEBUG(3,
+ (" Username of UID %d is %s\n", (int)vuser->uid,
+ vuser->name));
+ }
+ else
{
return False;
}
- vuser = get_valid_user_struct(&key);
- if (vuser != NULL)
- {
- DEBUG(3,(" Username of UID %d is %s\n", (int)vuser->uid, vuser->name));
- }
- else
- {
- return False;
- }
-
- unistr2_to_ascii(full_name, &vuser->usr.uni_full_name, sizeof(full_name)-1);
- unistr2_to_ascii(home_dir, &vuser->usr.uni_home_dir, sizeof(home_dir)-1);
- unistr2_to_ascii(nt_name, &vuser->usr.uni_user_name, sizeof(nt_name)-1);
- unistr2_to_ascii(logon_path, &vuser->usr.uni_logon_script, sizeof(logon_path)-1);
+ unistr2_to_ascii(full_name, &vuser->usr.uni_full_name,
+ sizeof(full_name) - 1);
+ unistr2_to_ascii(home_dir, &vuser->usr.uni_home_dir,
+ sizeof(home_dir) - 1);
+ unistr2_to_ascii(nt_name, &vuser->usr.uni_user_name,
+ sizeof(nt_name) - 1);
+ unistr2_to_ascii(logon_path, &vuser->usr.uni_logon_script,
+ sizeof(logon_path) - 1);
fstrcpy(logon_srv, "\\\\");
- unistr2_to_ascii(&logon_srv[2], &vuser->usr.uni_logon_srv, sizeof(logon_srv)-3);
+ unistr2_to_ascii(&logon_srv[2], &vuser->usr.uni_logon_srv,
+ sizeof(logon_srv) - 3);
*rdata_len = mdrcnt + 1024;
- *rdata = REALLOC(*rdata,*rdata_len);
+ *rdata = REALLOC(*rdata, *rdata_len);
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
+ SSVAL(*rparam, 0, NERR_Success);
+ SSVAL(*rparam, 2, 0); /* converter word */
p = *rdata;
p2 = p + usri11_end;
- memset(p,0,21);
- fstrcpy(p+usri11_name,nt_name); /* 21 bytes - user name */
+ memset(p, 0, 21);
+ fstrcpy(p + usri11_name, nt_name); /* 21 bytes - user name */
if (uLevel > 0)
{
- SCVAL(p,usri11_pad,0); /* padding - 1 byte */
+ SCVAL(p, usri11_pad, 0); /* padding - 1 byte */
*p2 = 0;
}
if (uLevel >= 10)
{
- SIVAL(p,usri11_comment,PTR_DIFF(p2,p)); /* comment */
+ SIVAL(p, usri11_comment, PTR_DIFF(p2, p)); /* comment */
pstrcpy(p2, "");
- p2 = skip_string(p2,1);
+ p2 = skip_string(p2, 1);
- SIVAL(p,usri11_usr_comment,PTR_DIFF(p2,p)); /* user_comment */
+ SIVAL(p, usri11_usr_comment, PTR_DIFF(p2, p)); /* user_comment */
pstrcpy(p2, "");
- p2 = skip_string(p2,1);
+ p2 = skip_string(p2, 1);
/* EEK! the cifsrap.txt doesn't have this in!!!! */
- SIVAL(p,usri11_full_name,PTR_DIFF(p2,p)); /* full name */
+ SIVAL(p, usri11_full_name, PTR_DIFF(p2, p)); /* full name */
pstrcpy(p2, full_name);
- p2 = skip_string(p2,1);
+ p2 = skip_string(p2, 1);
}
- if (uLevel == 11) /* modelled after NTAS 3.51 reply */
- {
- SSVAL(p,usri11_priv,conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
- SIVAL(p,usri11_auth_flags,AF_OP_PRINT); /* auth flags */
- SIVALS(p,usri11_password_age,-1); /* password age */
- SIVAL(p,usri11_homedir,PTR_DIFF(p2,p)); /* home dir */
+ if (uLevel == 11) /* modelled after NTAS 3.51 reply */
+ {
+ SSVAL(p, usri11_priv,
+ conn->admin_user ? USER_PRIV_ADMIN : USER_PRIV_USER);
+ SIVAL(p, usri11_auth_flags, AF_OP_PRINT); /* auth flags */
+ SIVALS(p, usri11_password_age, -1); /* password age */
+ SIVAL(p, usri11_homedir, PTR_DIFF(p2, p)); /* home dir */
pstrcpy(p2, home_dir);
- p2 = skip_string(p2,1);
- SIVAL(p,usri11_parms,PTR_DIFF(p2,p)); /* parms */
- pstrcpy(p2,"");
- p2 = skip_string(p2,1);
- SIVAL(p,usri11_last_logon,0); /* last logon */
- SIVAL(p,usri11_last_logoff,0); /* last logoff */
- SSVALS(p,usri11_bad_pw_count,vuser->usr.bad_pw_count); /* bad pw counts */
- SSVALS(p,usri11_num_logons,vuser->usr.logon_count); /* num logons */
- SIVAL(p,usri11_logon_server,PTR_DIFF(p2,p)); /* logon server */
- pstrcpy(p2,logon_srv);
- p2 = skip_string(p2,1);
- SSVAL(p,usri11_country_code,0); /* country code */
-
- SIVAL(p,usri11_workstations,PTR_DIFF(p2,p)); /* workstations */
+ p2 = skip_string(p2, 1);
+ SIVAL(p, usri11_parms, PTR_DIFF(p2, p)); /* parms */
pstrcpy(p2, "");
- p2 = skip_string(p2,1);
+ p2 = skip_string(p2, 1);
+ SIVAL(p, usri11_last_logon, 0); /* last logon */
+ SIVAL(p, usri11_last_logoff, 0); /* last logoff */
+ SSVALS(p, usri11_bad_pw_count, vuser->usr.bad_pw_count); /* bad pw counts */
+ SSVALS(p, usri11_num_logons, vuser->usr.logon_count); /* num logons */
+ SIVAL(p, usri11_logon_server, PTR_DIFF(p2, p)); /* logon server */
+ pstrcpy(p2, logon_srv);
+ p2 = skip_string(p2, 1);
+ SSVAL(p, usri11_country_code, 0); /* country code */
+
+ SIVAL(p, usri11_workstations, PTR_DIFF(p2, p)); /* workstations */
+ pstrcpy(p2, "");
+ p2 = skip_string(p2, 1);
- SIVALS(p,usri11_max_storage,-1); /* max storage */
- SSVAL(p,usri11_units_per_week,168); /* units per week */
- SIVAL(p,usri11_logon_hours,PTR_DIFF(p2,p)); /* logon hours */
+ SIVALS(p, usri11_max_storage, -1); /* max storage */
+ SSVAL(p, usri11_units_per_week, 168); /* units per week */
+ SIVAL(p, usri11_logon_hours, PTR_DIFF(p2, p)); /* logon hours */
/* a simple way to get logon hours at all times. */
- memset(p2,0xff,21);
- SCVAL(p2,21,0); /* fix zero termination */
- p2 = skip_string(p2,1);
+ memset(p2, 0xff, 21);
+ SCVAL(p2, 21, 0); /* fix zero termination */
+ p2 = skip_string(p2, 1);
- SSVAL(p,usri11_code_page,0); /* code page */
+ SSVAL(p, usri11_code_page, 0); /* code page */
}
if (uLevel == 1 || uLevel == 2)
{
- memset(p+22,' ',16); /* password */
- SIVALS(p,38,-1); /* password age */
- SSVAL(p,42,
- conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
- SIVAL(p,44,PTR_DIFF(p2,*rdata)); /* home dir */
- pstrcpy(p2,logon_path);
- p2 = skip_string(p2,1);
- SIVAL(p,48,PTR_DIFF(p2,*rdata)); /* comment */
+ memset(p + 22, ' ', 16); /* password */
+ SIVALS(p, 38, -1); /* password age */
+ SSVAL(p, 42,
+ conn->admin_user ? USER_PRIV_ADMIN : USER_PRIV_USER);
+ SIVAL(p, 44, PTR_DIFF(p2, *rdata)); /* home dir */
+ pstrcpy(p2, logon_path);
+ p2 = skip_string(p2, 1);
+ SIVAL(p, 48, PTR_DIFF(p2, *rdata)); /* comment */
*p2++ = 0;
- SSVAL(p,52,0); /* flags */
- SIVAL(p,54,0); /* script_path */
+ SSVAL(p, 52, 0); /* flags */
+ SIVAL(p, 54, 0); /* script_path */
if (uLevel == 2)
{
- SIVAL(p,60,0); /* auth_flags */
- SIVAL(p,64,PTR_DIFF(p2,*rdata)); /* full_name */
- pstrcpy(p2, nt_name);
- p2 = skip_string(p2,1);
- SIVAL(p,68,0); /* urs_comment */
- SIVAL(p,72,PTR_DIFF(p2,*rdata)); /* parms */
- pstrcpy(p2,"");
- p2 = skip_string(p2,1);
- SIVAL(p,76,0); /* workstations */
- SIVAL(p,80,0); /* last_logon */
- SIVAL(p,84,0); /* last_logoff */
- SIVALS(p,88,-1); /* acct_expires */
- SIVALS(p,92,-1); /* max_storage */
- SSVAL(p,96,168); /* units_per_week */
- SIVAL(p,98,PTR_DIFF(p2,*rdata)); /* logon_hours */
- memset(p2,-1,21);
+ SIVAL(p, 60, 0); /* auth_flags */
+ SIVAL(p, 64, PTR_DIFF(p2, *rdata)); /* full_name */
+ pstrcpy(p2, nt_name);
+ p2 = skip_string(p2, 1);
+ SIVAL(p, 68, 0); /* urs_comment */
+ SIVAL(p, 72, PTR_DIFF(p2, *rdata)); /* parms */
+ pstrcpy(p2, "");
+ p2 = skip_string(p2, 1);
+ SIVAL(p, 76, 0); /* workstations */
+ SIVAL(p, 80, 0); /* last_logon */
+ SIVAL(p, 84, 0); /* last_logoff */
+ SIVALS(p, 88, -1); /* acct_expires */
+ SIVALS(p, 92, -1); /* max_storage */
+ SSVAL(p, 96, 168); /* units_per_week */
+ SIVAL(p, 98, PTR_DIFF(p2, *rdata)); /* logon_hours */
+ memset(p2, -1, 21);
p2 += 21;
- SSVALS(p,102,vuser->usr.bad_pw_count); /* bad_pw_count */
- SSVALS(p,104,vuser->usr.logon_count); /* num_logons */
- SIVAL(p,106,PTR_DIFF(p2,*rdata)); /* logon_server */
- pstrcpy(p2,logon_srv);
- p2 = skip_string(p2,1);
- SSVAL(p,110,49); /* country_code */
- SSVAL(p,112,860); /* code page */
+ SSVALS(p, 102, vuser->usr.bad_pw_count); /* bad_pw_count */
+ SSVALS(p, 104, vuser->usr.logon_count); /* num_logons */
+ SIVAL(p, 106, PTR_DIFF(p2, *rdata)); /* logon_server */
+ pstrcpy(p2, logon_srv);
+ p2 = skip_string(p2, 1);
+ SSVAL(p, 110, 49); /* country_code */
+ SSVAL(p, 112, 860); /* code page */
}
}
- *rdata_len = PTR_DIFF(p2,*rdata);
+ *rdata_len = PTR_DIFF(p2, *rdata);
- SSVAL(*rparam,4,*rdata_len); /* is this right?? */
+ SSVAL(*rparam, 4, *rdata_len); /* is this right?? */
vuid_free_user_struct(vuser);
- return(True);
+ return (True);
}
/*******************************************************************
get groups that a user is a member of
******************************************************************/
-static BOOL api_NetUserGetGroups(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_NetUserGetGroups(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt,
+ int mprcnt, char **rdata, char **rparam,
+ int *rdata_len, int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *UserName = skip_string(str2,1);
- char *p = skip_string(UserName,1);
- int uLevel = SVAL(p,0);
- char *p2;
- int count=0;
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- /* check it's a supported varient */
- if (strcmp(str1,"zWrLeh") != 0) return False;
- switch( uLevel ) {
- case 0: p2 = "B21"; break;
- default: return False;
- }
- if (strcmp(p2,str2) != 0) return False;
-
- *rdata_len = mdrcnt + 1024;
- *rdata = REALLOC(*rdata,*rdata_len);
+ char *str1 = param + 2;
+ char *str2 = skip_string(str1, 1);
+ char *UserName = skip_string(str2, 1);
+ char *p = skip_string(UserName, 1);
+ int uLevel = SVAL(p, 0);
+ char *p2;
+ int count = 0;
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
+ *rparam_len = 8;
+ *rparam = REALLOC(*rparam, *rparam_len);
- p = *rdata;
+ /* check it's a supported varient */
+ if (strcmp(str1, "zWrLeh") != 0)
+ return False;
+ switch (uLevel)
+ {
+ case 0:
+ p2 = "B21";
+ break;
+ default:
+ return False;
+ }
+ if (strcmp(p2, str2) != 0)
+ return False;
- /* XXXX we need a real SAM database some day */
- pstrcpy(p,"Users"); p += 21; count++;
- pstrcpy(p,"Domain Users"); p += 21; count++;
- pstrcpy(p,"Guests"); p += 21; count++;
- pstrcpy(p,"Domain Guests"); p += 21; count++;
+ *rdata_len = mdrcnt + 1024;
+ *rdata = REALLOC(*rdata, *rdata_len);
- *rdata_len = PTR_DIFF(p,*rdata);
+ SSVAL(*rparam, 0, NERR_Success);
+ SSVAL(*rparam, 2, 0); /* converter word */
- SSVAL(*rparam,4,count); /* is this right?? */
- SSVAL(*rparam,6,count); /* is this right?? */
+ p = *rdata;
- return(True);
+ /* XXXX we need a real SAM database some day */
+ pstrcpy(p, "Users");
+ p += 21;
+ count++;
+ pstrcpy(p, "Domain Users");
+ p += 21;
+ count++;
+ pstrcpy(p, "Guests");
+ p += 21;
+ count++;
+ pstrcpy(p, "Domain Guests");
+ p += 21;
+ count++;
+
+ *rdata_len = PTR_DIFF(p, *rdata);
+
+ SSVAL(*rparam, 4, count); /* is this right?? */
+ SSVAL(*rparam, 6, count); /* is this right?? */
+
+ return (True);
}
-static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_WWkstaUserLogon(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt,
+ int mprcnt, char **rdata, char **rparam,
+ int *rdata_len, int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel;
- struct pack_desc desc;
- char* name;
- user_struct *vuser;
- VUSER_KEY;
- vuser = get_valid_user_struct(&key); /* moved due to VUSER_KEY initialization */
+ char *str1 = param + 2;
+ char *str2 = skip_string(str1, 1);
+ char *p = skip_string(str2, 1);
+ int uLevel;
+ struct pack_desc desc;
+ char *name;
+ user_struct *vuser;
+ VUSER_KEY;
+ vuser = get_valid_user_struct(&key); /* moved due to VUSER_KEY initialization */
if (vuser == NULL)
{
return False;
}
- uLevel = SVAL(p,0);
- name = p + 2;
-
- ZERO_STRUCT(desc);
-
- DEBUG(3,("WWkstaUserLogon uLevel=%d name=%s\n",uLevel,name));
-
- /* check it's a supported varient */
- if (strcmp(str1,"OOWb54WrLh") != 0) return False;
- if (uLevel != 1 || strcmp(str2,"WB21BWDWWDDDDDDDzzzD") != 0) return False;
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- desc.subformat = NULL;
- desc.format = str2;
-
- if (init_package(&desc,1,0))
- {
- fstring nt_name;
- fstring logon_script;
- fstring logon_srv;
- fstring logon_dom;
-
- unistr2_to_ascii(nt_name, &vuser->usr.uni_user_name, sizeof(nt_name)-1);
- unistr2_to_ascii(logon_script, &vuser->usr.uni_logon_script, sizeof(logon_script)-1);
- unistr2_to_ascii(logon_dom, &vuser->usr.uni_logon_dom, sizeof(logon_dom)-1);
- fstrcpy(logon_srv, "\\\\");
- unistr2_to_ascii(&logon_srv[2], &vuser->usr.uni_logon_srv, sizeof(logon_srv)-3);
-
- PACKI(&desc,"W",0); /* code */
- PACKS(&desc,"B21",nt_name); /* eff. name */
- PACKS(&desc,"B",""); /* pad */
- PACKI(&desc,"W",
- conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
- PACKI(&desc,"D",0); /* auth flags XXX */
- PACKI(&desc,"W",0); /* num logons */
- PACKI(&desc,"W",0); /* bad pw count */
- PACKI(&desc,"D",0); /* last logon */
- PACKI(&desc,"D",-1); /* last logoff */
- PACKI(&desc,"D",-1); /* logoff time */
- PACKI(&desc,"D",-1); /* kickoff time */
- PACKI(&desc,"D",0); /* password age */
- PACKI(&desc,"D",0); /* password can change */
- PACKI(&desc,"D",-1); /* password must change */
- {
- PACKS(&desc,"z",logon_srv); /* computer */
- }
- PACKS(&desc,"z",logon_dom);/* domain */
- PACKS(&desc,"z", logon_script); /* script path */
-
- PACKI(&desc,"D",0x00000000); /* reserved */
- }
-
- *rdata_len = desc.usedlen;
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,desc.neededlen);
-
- DEBUG(4,("WWkstaUserLogon: errorcode %d\n",desc.errcode));
- vuid_free_user_struct(vuser);
-
- return(True);
+ uLevel = SVAL(p, 0);
+ name = p + 2;
+
+ ZERO_STRUCT(desc);
+
+ DEBUG(3, ("WWkstaUserLogon uLevel=%d name=%s\n", uLevel, name));
+
+ /* check it's a supported varient */
+ if (strcmp(str1, "OOWb54WrLh") != 0)
+ return False;
+ if (uLevel != 1 || strcmp(str2, "WB21BWDWWDDDDDDDzzzD") != 0)
+ return False;
+ if (mdrcnt > 0)
+ *rdata = REALLOC(*rdata, mdrcnt);
+ desc.base = *rdata;
+ desc.buflen = mdrcnt;
+ desc.subformat = NULL;
+ desc.format = str2;
+
+ if (init_package(&desc, 1, 0))
+ {
+ fstring nt_name;
+ fstring logon_script;
+ fstring logon_srv;
+ fstring logon_dom;
+
+ unistr2_to_ascii(nt_name, &vuser->usr.uni_user_name,
+ sizeof(nt_name) - 1);
+ unistr2_to_ascii(logon_script, &vuser->usr.uni_logon_script,
+ sizeof(logon_script) - 1);
+ unistr2_to_ascii(logon_dom, &vuser->usr.uni_logon_dom,
+ sizeof(logon_dom) - 1);
+ fstrcpy(logon_srv, "\\\\");
+ unistr2_to_ascii(&logon_srv[2], &vuser->usr.uni_logon_srv,
+ sizeof(logon_srv) - 3);
+
+ PACKI(&desc, "W", 0); /* code */
+ PACKS(&desc, "B21", nt_name); /* eff. name */
+ PACKS(&desc, "B", ""); /* pad */
+ PACKI(&desc, "W",
+ conn->admin_user ? USER_PRIV_ADMIN : USER_PRIV_USER);
+ PACKI(&desc, "D", 0); /* auth flags XXX */
+ PACKI(&desc, "W", 0); /* num logons */
+ PACKI(&desc, "W", 0); /* bad pw count */
+ PACKI(&desc, "D", 0); /* last logon */
+ PACKI(&desc, "D", -1); /* last logoff */
+ PACKI(&desc, "D", -1); /* logoff time */
+ PACKI(&desc, "D", -1); /* kickoff time */
+ PACKI(&desc, "D", 0); /* password age */
+ PACKI(&desc, "D", 0); /* password can change */
+ PACKI(&desc, "D", -1); /* password must change */
+ {
+ PACKS(&desc, "z", logon_srv); /* computer */
+ }
+ PACKS(&desc, "z", logon_dom); /* domain */
+ PACKS(&desc, "z", logon_script); /* script path */
+
+ PACKI(&desc, "D", 0x00000000); /* reserved */
+ }
+
+ *rdata_len = desc.usedlen;
+ *rparam_len = 6;
+ *rparam = REALLOC(*rparam, *rparam_len);
+ SSVALS(*rparam, 0, desc.errcode);
+ SSVAL(*rparam, 2, 0);
+ SSVAL(*rparam, 4, desc.neededlen);
+
+ DEBUG(4, ("WWkstaUserLogon: errorcode %d\n", desc.errcode));
+ vuid_free_user_struct(vuser);
+
+ return (True);
}
/****************************************************************************
api_WAccessGetUserPerms
****************************************************************************/
-static BOOL api_WAccessGetUserPerms(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_WAccessGetUserPerms(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt,
+ int mprcnt, char **rdata, char **rparam,
+ int *rdata_len, int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *user = skip_string(str2,1);
- char *resource = skip_string(user,1);
+ char *str1 = param + 2;
+ char *str2 = skip_string(str1, 1);
+ char *user = skip_string(str2, 1);
+ char *resource = skip_string(user, 1);
- DEBUG(3,("WAccessGetUserPerms user=%s resource=%s\n",user,resource));
+ DEBUG(3,
+ ("WAccessGetUserPerms user=%s resource=%s\n", user, resource));
- /* check it's a supported varient */
- if (strcmp(str1,"zzh") != 0) return False;
- if (strcmp(str2,"") != 0) return False;
+ /* check it's a supported varient */
+ if (strcmp(str1, "zzh") != 0)
+ return False;
+ if (strcmp(str2, "") != 0)
+ return False;
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,0); /* errorcode */
- SSVAL(*rparam,2,0); /* converter word */
- SSVAL(*rparam,4,0x7f); /* permission flags */
+ *rparam_len = 6;
+ *rparam = REALLOC(*rparam, *rparam_len);
+ SSVALS(*rparam, 0, 0); /* errorcode */
+ SSVAL(*rparam, 2, 0); /* converter word */
+ SSVAL(*rparam, 4, 0x7f); /* permission flags */
- return(True);
+ return (True);
}
/****************************************************************************
api_WPrintJobEnumerate
****************************************************************************/
-static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_WPrintJobGetInfo(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt,
+ int mprcnt, char **rdata, char **rparam,
+ int *rdata_len, int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel;
- int count;
- int i;
- int snum;
- int job;
- struct pack_desc desc;
- print_queue_struct *queue=NULL;
- print_status_struct status;
+ char *str1 = param + 2;
+ char *str2 = skip_string(str1, 1);
+ char *p = skip_string(str2, 1);
+ int uLevel;
+ int count;
+ int i;
+ int snum;
+ int job;
+ struct pack_desc desc;
+ print_queue_struct *queue = NULL;
+ print_status_struct status;
VUSER_KEY;
- uLevel = SVAL(p,2);
+ uLevel = SVAL(p, 2);
- ZERO_STRUCT(desc);
- ZERO_STRUCT(status);
+ ZERO_STRUCT(desc);
+ ZERO_STRUCT(status);
- DEBUG(3,("WPrintJobGetInfo uLevel=%d uJobId=0x%X\n",uLevel,SVAL(p,0)));
+ DEBUG(3,
+ ("WPrintJobGetInfo uLevel=%d uJobId=0x%X\n", uLevel,
+ SVAL(p, 0)));
- /* check it's a supported varient */
- if (strcmp(str1,"WWrLh") != 0) return False;
- if (!check_printjob_info(&desc,uLevel,str2)) return False;
+ /* check it's a supported varient */
+ if (strcmp(str1, "WWrLh") != 0)
+ return False;
+ if (!check_printjob_info(&desc, uLevel, str2))
+ return False;
- printjob_decode(SVAL(p,0), &snum, &job);
+ printjob_decode(SVAL(p, 0), &snum, &job);
- if (snum < 0 || !VALID_SNUM(snum)) return(False);
+ if (snum < 0 || !VALID_SNUM(snum))
+ return (False);
- count = get_printqueue(snum,conn,&key,&queue,&status);
- for (i = 0; i < count; i++) {
- if ((queue[i].job & 0xFF) == job) break;
- }
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
+ count = get_printqueue(snum, conn, &key, &queue, &status);
+ for (i = 0; i < count; i++)
+ {
+ if ((queue[i].job & 0xFF) == job)
+ break;
+ }
+ if (mdrcnt > 0)
+ *rdata = REALLOC(*rdata, mdrcnt);
+ desc.base = *rdata;
+ desc.buflen = mdrcnt;
- if (init_package(&desc,1,0)) {
- if (i < count) {
- fill_printjob_info(conn,snum,uLevel,&desc,&queue[i],i);
- *rdata_len = desc.usedlen;
- }
- else {
- desc.errcode = NERR_JobNotFound;
- *rdata_len = 0;
- }
- }
+ if (init_package(&desc, 1, 0))
+ {
+ if (i < count)
+ {
+ fill_printjob_info(conn, snum, uLevel, &desc,
+ &queue[i], i);
+ *rdata_len = desc.usedlen;
+ }
+ else
+ {
+ desc.errcode = NERR_JobNotFound;
+ *rdata_len = 0;
+ }
+ }
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,desc.neededlen);
+ *rparam_len = 6;
+ *rparam = REALLOC(*rparam, *rparam_len);
+ SSVALS(*rparam, 0, desc.errcode);
+ SSVAL(*rparam, 2, 0);
+ SSVAL(*rparam, 4, desc.neededlen);
- if (queue) free(queue);
+ if (queue)
+ free(queue);
- DEBUG(4,("WPrintJobGetInfo: errorcode %d\n",desc.errcode));
- return(True);
+ DEBUG(4, ("WPrintJobGetInfo: errorcode %d\n", desc.errcode));
+ return (True);
}
-static BOOL api_WPrintJobEnumerate(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_WPrintJobEnumerate(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt,
+ int mprcnt, char **rdata, char **rparam,
+ int *rdata_len, int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- char* name = p;
- int uLevel;
- int count;
- int i, succnt=0;
- int snum;
- struct pack_desc desc;
- print_queue_struct *queue=NULL;
- print_status_struct status;
+ char *str1 = param + 2;
+ char *str2 = skip_string(str1, 1);
+ char *p = skip_string(str2, 1);
+ char *name = p;
+ int uLevel;
+ int count;
+ int i, succnt = 0;
+ int snum;
+ struct pack_desc desc;
+ print_queue_struct *queue = NULL;
+ print_status_struct status;
VUSER_KEY;
- ZERO_STRUCT(desc);
- ZERO_STRUCT(status);
+ ZERO_STRUCT(desc);
+ ZERO_STRUCT(status);
- p = skip_string(p,1);
- uLevel = SVAL(p,0);
+ p = skip_string(p, 1);
+ uLevel = SVAL(p, 0);
- DEBUG(3,("WPrintJobEnumerate uLevel=%d name=%s\n",uLevel,name));
+ DEBUG(3, ("WPrintJobEnumerate uLevel=%d name=%s\n", uLevel, name));
- /* check it's a supported varient */
- if (strcmp(str1,"zWrLeh") != 0) return False;
- if (uLevel > 2) return False; /* defined only for uLevel 0,1,2 */
- if (!check_printjob_info(&desc,uLevel,str2)) return False;
+ /* check it's a supported varient */
+ if (strcmp(str1, "zWrLeh") != 0)
+ return False;
+ if (uLevel > 2)
+ return False; /* defined only for uLevel 0,1,2 */
+ if (!check_printjob_info(&desc, uLevel, str2))
+ return False;
- snum = lp_servicenumber(name);
- if (snum < 0 && pcap_printername_ok(name,NULL)) {
- int pnum = lp_servicenumber(PRINTERS_NAME);
- if (pnum >= 0) {
- lp_add_printer(name,pnum);
- snum = lp_servicenumber(name);
- }
- }
+ snum = lp_servicenumber(name);
+ if (snum < 0 && pcap_printername_ok(name, NULL))
+ {
+ int pnum = lp_servicenumber(PRINTERS_NAME);
+ if (pnum >= 0)
+ {
+ lp_add_printer(name, pnum);
+ snum = lp_servicenumber(name);
+ }
+ }
- if (snum < 0 || !VALID_SNUM(snum)) return(False);
+ if (snum < 0 || !VALID_SNUM(snum))
+ return (False);
- count = get_printqueue(snum,conn,&key,&queue,&status);
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
+ count = get_printqueue(snum, conn, &key, &queue, &status);
+ if (mdrcnt > 0)
+ *rdata = REALLOC(*rdata, mdrcnt);
+ desc.base = *rdata;
+ desc.buflen = mdrcnt;
- if (init_package(&desc,count,0)) {
- succnt = 0;
- for (i = 0; i < count; i++) {
- fill_printjob_info(conn,snum,uLevel,&desc,&queue[i],i);
- if (desc.errcode == NERR_Success) succnt = i+1;
- }
- }
+ if (init_package(&desc, count, 0))
+ {
+ succnt = 0;
+ for (i = 0; i < count; i++)
+ {
+ fill_printjob_info(conn, snum, uLevel, &desc,
+ &queue[i], i);
+ if (desc.errcode == NERR_Success)
+ succnt = i + 1;
+ }
+ }
- *rdata_len = desc.usedlen;
+ *rdata_len = desc.usedlen;
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,succnt);
- SSVAL(*rparam,6,count);
+ *rparam_len = 8;
+ *rparam = REALLOC(*rparam, *rparam_len);
+ SSVALS(*rparam, 0, desc.errcode);
+ SSVAL(*rparam, 2, 0);
+ SSVAL(*rparam, 4, succnt);
+ SSVAL(*rparam, 6, count);
- if (queue) free(queue);
+ if (queue)
+ free(queue);
- DEBUG(4,("WPrintJobEnumerate: errorcode %d\n",desc.errcode));
- return(True);
+ DEBUG(4, ("WPrintJobEnumerate: errorcode %d\n", desc.errcode));
+ return (True);
}
-static int check_printdest_info(struct pack_desc* desc,
- int uLevel, char* id)
+static int check_printdest_info(struct pack_desc *desc, int uLevel, char *id)
{
- desc->subformat = NULL;
- switch( uLevel ) {
- case 0: desc->format = "B9"; break;
- case 1: desc->format = "B9B21WWzW"; break;
- case 2: desc->format = "z"; break;
- case 3: desc->format = "zzzWWzzzWW"; break;
- default: return False;
- }
- if (strcmp(desc->format,id) != 0) return False;
- return True;
+ desc->subformat = NULL;
+ switch (uLevel)
+ {
+ case 0:
+ desc->format = "B9";
+ break;
+ case 1:
+ desc->format = "B9B21WWzW";
+ break;
+ case 2:
+ desc->format = "z";
+ break;
+ case 3:
+ desc->format = "zzzWWzzzWW";
+ break;
+ default:
+ return False;
+ }
+ if (strcmp(desc->format, id) != 0)
+ return False;
+ return True;
}
-static void fill_printdest_info(connection_struct *conn, int snum, int uLevel,
- struct pack_desc* desc)
+static void fill_printdest_info(connection_struct * conn, int snum,
+ int uLevel, struct pack_desc *desc)
{
- char buf[100];
- strncpy(buf,SERVICE(snum),sizeof(buf)-1);
- buf[sizeof(buf)-1] = 0;
- strupper(buf);
- if (uLevel <= 1) {
- PACKS(desc,"B9",buf); /* szName */
- if (uLevel == 1) {
- PACKS(desc,"B21",""); /* szUserName */
- PACKI(desc,"W",0); /* uJobId */
- PACKI(desc,"W",0); /* fsStatus */
- PACKS(desc,"z",""); /* pszStatus */
- PACKI(desc,"W",0); /* time */
- }
- }
- if (uLevel == 2 || uLevel == 3) {
- PACKS(desc,"z",buf); /* pszPrinterName */
- if (uLevel == 3) {
- PACKS(desc,"z",""); /* pszUserName */
- PACKS(desc,"z",""); /* pszLogAddr */
- PACKI(desc,"W",0); /* uJobId */
- PACKI(desc,"W",0); /* fsStatus */
- PACKS(desc,"z",""); /* pszStatus */
- PACKS(desc,"z",""); /* pszComment */
- PACKS(desc,"z","NULL"); /* pszDrivers */
- PACKI(desc,"W",0); /* time */
- PACKI(desc,"W",0); /* pad1 */
- }
- }
+ char buf[100];
+ strncpy(buf, SERVICE(snum), sizeof(buf) - 1);
+ buf[sizeof(buf) - 1] = 0;
+ strupper(buf);
+ if (uLevel <= 1)
+ {
+ PACKS(desc, "B9", buf); /* szName */
+ if (uLevel == 1)
+ {
+ PACKS(desc, "B21", ""); /* szUserName */
+ PACKI(desc, "W", 0); /* uJobId */
+ PACKI(desc, "W", 0); /* fsStatus */
+ PACKS(desc, "z", ""); /* pszStatus */
+ PACKI(desc, "W", 0); /* time */
+ }
+ }
+ if (uLevel == 2 || uLevel == 3)
+ {
+ PACKS(desc, "z", buf); /* pszPrinterName */
+ if (uLevel == 3)
+ {
+ PACKS(desc, "z", ""); /* pszUserName */
+ PACKS(desc, "z", ""); /* pszLogAddr */
+ PACKI(desc, "W", 0); /* uJobId */
+ PACKI(desc, "W", 0); /* fsStatus */
+ PACKS(desc, "z", ""); /* pszStatus */
+ PACKS(desc, "z", ""); /* pszComment */
+ PACKS(desc, "z", "NULL"); /* pszDrivers */
+ PACKI(desc, "W", 0); /* time */
+ PACKI(desc, "W", 0); /* pad1 */
+ }
+ }
}
-static BOOL api_WPrintDestGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_WPrintDestGetInfo(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt,
+ int mprcnt, char **rdata, char **rparam,
+ int *rdata_len, int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- char* PrinterName = p;
- int uLevel;
- struct pack_desc desc;
- int snum;
-
- ZERO_STRUCT(desc);
-
- p = skip_string(p,1);
- uLevel = SVAL(p,0);
-
- DEBUG(3,("WPrintDestGetInfo uLevel=%d PrinterName=%s\n",uLevel,PrinterName));
-
- /* check it's a supported varient */
- if (strcmp(str1,"zWrLh") != 0) return False;
- if (!check_printdest_info(&desc,uLevel,str2)) return False;
-
- snum = lp_servicenumber(PrinterName);
- if (snum < 0 && pcap_printername_ok(PrinterName,NULL)) {
- int pnum = lp_servicenumber(PRINTERS_NAME);
- if (pnum >= 0) {
- lp_add_printer(PrinterName,pnum);
- snum = lp_servicenumber(PrinterName);
- }
- }
-
- if (snum < 0) {
- *rdata_len = 0;
- desc.errcode = NERR_DestNotFound;
- desc.neededlen = 0;
- }
- else {
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- if (init_package(&desc,1,0)) {
- fill_printdest_info(conn,snum,uLevel,&desc);
- }
- *rdata_len = desc.usedlen;
- }
-
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,desc.neededlen);
-
- DEBUG(4,("WPrintDestGetInfo: errorcode %d\n",desc.errcode));
- return(True);
+ char *str1 = param + 2;
+ char *str2 = skip_string(str1, 1);
+ char *p = skip_string(str2, 1);
+ char *PrinterName = p;
+ int uLevel;
+ struct pack_desc desc;
+ int snum;
+
+ ZERO_STRUCT(desc);
+
+ p = skip_string(p, 1);
+ uLevel = SVAL(p, 0);
+
+ DEBUG(3,
+ ("WPrintDestGetInfo uLevel=%d PrinterName=%s\n", uLevel,
+ PrinterName));
+
+ /* check it's a supported varient */
+ if (strcmp(str1, "zWrLh") != 0)
+ return False;
+ if (!check_printdest_info(&desc, uLevel, str2))
+ return False;
+
+ snum = lp_servicenumber(PrinterName);
+ if (snum < 0 && pcap_printername_ok(PrinterName, NULL))
+ {
+ int pnum = lp_servicenumber(PRINTERS_NAME);
+ if (pnum >= 0)
+ {
+ lp_add_printer(PrinterName, pnum);
+ snum = lp_servicenumber(PrinterName);
+ }
+ }
+
+ if (snum < 0)
+ {
+ *rdata_len = 0;
+ desc.errcode = NERR_DestNotFound;
+ desc.neededlen = 0;
+ }
+ else
+ {
+ if (mdrcnt > 0)
+ *rdata = REALLOC(*rdata, mdrcnt);
+ desc.base = *rdata;
+ desc.buflen = mdrcnt;
+ if (init_package(&desc, 1, 0))
+ {
+ fill_printdest_info(conn, snum, uLevel, &desc);
+ }
+ *rdata_len = desc.usedlen;
+ }
+
+ *rparam_len = 6;
+ *rparam = REALLOC(*rparam, *rparam_len);
+ SSVALS(*rparam, 0, desc.errcode);
+ SSVAL(*rparam, 2, 0);
+ SSVAL(*rparam, 4, desc.neededlen);
+
+ DEBUG(4, ("WPrintDestGetInfo: errorcode %d\n", desc.errcode));
+ return (True);
}
-static BOOL api_WPrintDestEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_WPrintDestEnum(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt,
+ int mprcnt, char **rdata, char **rparam,
+ int *rdata_len, int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel;
- int queuecnt;
- int i, n, succnt=0;
- struct pack_desc desc;
- int services = lp_numservices();
-
- ZERO_STRUCT(desc);
-
- uLevel = SVAL(p,0);
-
- DEBUG(3,("WPrintDestEnum uLevel=%d\n",uLevel));
-
- /* check it's a supported varient */
- if (strcmp(str1,"WrLeh") != 0) return False;
- if (!check_printdest_info(&desc,uLevel,str2)) return False;
-
- queuecnt = 0;
- for (i = 0; i < services; i++)
- if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i))
- queuecnt++;
-
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- if (init_package(&desc,queuecnt,0)) {
- succnt = 0;
- n = 0;
- for (i = 0; i < services; i++) {
- if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
- fill_printdest_info(conn,i,uLevel,&desc);
- n++;
- if (desc.errcode == NERR_Success) succnt = n;
- }
- }
- }
-
- *rdata_len = desc.usedlen;
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,succnt);
- SSVAL(*rparam,6,queuecnt);
-
- DEBUG(4,("WPrintDestEnumerate: errorcode %d\n",desc.errcode));
- return(True);
+ char *str1 = param + 2;
+ char *str2 = skip_string(str1, 1);
+ char *p = skip_string(str2, 1);
+ int uLevel;
+ int queuecnt;
+ int i, n, succnt = 0;
+ struct pack_desc desc;
+ int services = lp_numservices();
+
+ ZERO_STRUCT(desc);
+
+ uLevel = SVAL(p, 0);
+
+ DEBUG(3, ("WPrintDestEnum uLevel=%d\n", uLevel));
+
+ /* check it's a supported varient */
+ if (strcmp(str1, "WrLeh") != 0)
+ return False;
+ if (!check_printdest_info(&desc, uLevel, str2))
+ return False;
+
+ queuecnt = 0;
+ for (i = 0; i < services; i++)
+ if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i))
+ queuecnt++;
+
+ if (mdrcnt > 0)
+ *rdata = REALLOC(*rdata, mdrcnt);
+ desc.base = *rdata;
+ desc.buflen = mdrcnt;
+ if (init_package(&desc, queuecnt, 0))
+ {
+ succnt = 0;
+ n = 0;
+ for (i = 0; i < services; i++)
+ {
+ if (lp_snum_ok(i) && lp_print_ok(i)
+ && lp_browseable(i))
+ {
+ fill_printdest_info(conn, i, uLevel, &desc);
+ n++;
+ if (desc.errcode == NERR_Success)
+ succnt = n;
+ }
+ }
+ }
+
+ *rdata_len = desc.usedlen;
+
+ *rparam_len = 8;
+ *rparam = REALLOC(*rparam, *rparam_len);
+ SSVALS(*rparam, 0, desc.errcode);
+ SSVAL(*rparam, 2, 0);
+ SSVAL(*rparam, 4, succnt);
+ SSVAL(*rparam, 6, queuecnt);
+
+ DEBUG(4, ("WPrintDestEnumerate: errorcode %d\n", desc.errcode));
+ return (True);
}
-static BOOL api_WPrintDriverEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_WPrintDriverEnum(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt,
+ int mprcnt, char **rdata, char **rparam,
+ int *rdata_len, int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel;
- int succnt;
- struct pack_desc desc;
+ char *str1 = param + 2;
+ char *str2 = skip_string(str1, 1);
+ char *p = skip_string(str2, 1);
+ int uLevel;
+ int succnt;
+ struct pack_desc desc;
- ZERO_STRUCT(desc);
+ ZERO_STRUCT(desc);
- uLevel = SVAL(p,0);
+ uLevel = SVAL(p, 0);
- DEBUG(3,("WPrintDriverEnum uLevel=%d\n",uLevel));
+ DEBUG(3, ("WPrintDriverEnum uLevel=%d\n", uLevel));
- /* check it's a supported varient */
- if (strcmp(str1,"WrLeh") != 0) return False;
- if (uLevel != 0 || strcmp(str2,"B41") != 0) return False;
+ /* check it's a supported varient */
+ if (strcmp(str1, "WrLeh") != 0)
+ return False;
+ if (uLevel != 0 || strcmp(str2, "B41") != 0)
+ return False;
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- if (init_package(&desc,1,0)) {
- PACKS(&desc,"B41","NULL");
- }
+ if (mdrcnt > 0)
+ *rdata = REALLOC(*rdata, mdrcnt);
+ desc.base = *rdata;
+ desc.buflen = mdrcnt;
+ if (init_package(&desc, 1, 0))
+ {
+ PACKS(&desc, "B41", "NULL");
+ }
- succnt = (desc.errcode == NERR_Success ? 1 : 0);
+ succnt = (desc.errcode == NERR_Success ? 1 : 0);
- *rdata_len = desc.usedlen;
+ *rdata_len = desc.usedlen;
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,succnt);
- SSVAL(*rparam,6,1);
+ *rparam_len = 8;
+ *rparam = REALLOC(*rparam, *rparam_len);
+ SSVALS(*rparam, 0, desc.errcode);
+ SSVAL(*rparam, 2, 0);
+ SSVAL(*rparam, 4, succnt);
+ SSVAL(*rparam, 6, 1);
- DEBUG(4,("WPrintDriverEnum: errorcode %d\n",desc.errcode));
- return(True);
+ DEBUG(4, ("WPrintDriverEnum: errorcode %d\n", desc.errcode));
+ return (True);
}
-static BOOL api_WPrintQProcEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_WPrintQProcEnum(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt,
+ int mprcnt, char **rdata, char **rparam,
+ int *rdata_len, int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel;
- int succnt;
- struct pack_desc desc;
+ char *str1 = param + 2;
+ char *str2 = skip_string(str1, 1);
+ char *p = skip_string(str2, 1);
+ int uLevel;
+ int succnt;
+ struct pack_desc desc;
- ZERO_STRUCT(desc);
+ ZERO_STRUCT(desc);
- uLevel = SVAL(p,0);
+ uLevel = SVAL(p, 0);
- DEBUG(3,("WPrintQProcEnum uLevel=%d\n",uLevel));
+ DEBUG(3, ("WPrintQProcEnum uLevel=%d\n", uLevel));
- /* check it's a supported varient */
- if (strcmp(str1,"WrLeh") != 0) return False;
- if (uLevel != 0 || strcmp(str2,"B13") != 0) return False;
+ /* check it's a supported varient */
+ if (strcmp(str1, "WrLeh") != 0)
+ return False;
+ if (uLevel != 0 || strcmp(str2, "B13") != 0)
+ return False;
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- desc.format = str2;
- if (init_package(&desc,1,0)) {
- PACKS(&desc,"B13","lpd");
- }
+ if (mdrcnt > 0)
+ *rdata = REALLOC(*rdata, mdrcnt);
+ desc.base = *rdata;
+ desc.buflen = mdrcnt;
+ desc.format = str2;
+ if (init_package(&desc, 1, 0))
+ {
+ PACKS(&desc, "B13", "lpd");
+ }
- succnt = (desc.errcode == NERR_Success ? 1 : 0);
+ succnt = (desc.errcode == NERR_Success ? 1 : 0);
- *rdata_len = desc.usedlen;
+ *rdata_len = desc.usedlen;
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,succnt);
- SSVAL(*rparam,6,1);
+ *rparam_len = 8;
+ *rparam = REALLOC(*rparam, *rparam_len);
+ SSVALS(*rparam, 0, desc.errcode);
+ SSVAL(*rparam, 2, 0);
+ SSVAL(*rparam, 4, succnt);
+ SSVAL(*rparam, 6, 1);
- DEBUG(4,("WPrintQProcEnum: errorcode %d\n",desc.errcode));
- return(True);
+ DEBUG(4, ("WPrintQProcEnum: errorcode %d\n", desc.errcode));
+ return (True);
}
-static BOOL api_WPrintPortEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_WPrintPortEnum(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt,
+ int mprcnt, char **rdata, char **rparam,
+ int *rdata_len, int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel;
- int succnt;
- struct pack_desc desc;
+ char *str1 = param + 2;
+ char *str2 = skip_string(str1, 1);
+ char *p = skip_string(str2, 1);
+ int uLevel;
+ int succnt;
+ struct pack_desc desc;
- ZERO_STRUCT(desc);
+ ZERO_STRUCT(desc);
- uLevel = SVAL(p,0);
+ uLevel = SVAL(p, 0);
- DEBUG(3,("WPrintPortEnum uLevel=%d\n",uLevel));
+ DEBUG(3, ("WPrintPortEnum uLevel=%d\n", uLevel));
- /* check it's a supported varient */
- if (strcmp(str1,"WrLeh") != 0) return False;
- if (uLevel != 0 || strcmp(str2,"B9") != 0) return False;
+ /* check it's a supported varient */
+ if (strcmp(str1, "WrLeh") != 0)
+ return False;
+ if (uLevel != 0 || strcmp(str2, "B9") != 0)
+ return False;
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- ZERO_STRUCT(desc);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- desc.format = str2;
- if (init_package(&desc,1,0)) {
- PACKS(&desc,"B13","lp0");
- }
+ if (mdrcnt > 0)
+ *rdata = REALLOC(*rdata, mdrcnt);
+ ZERO_STRUCT(desc);
+ desc.base = *rdata;
+ desc.buflen = mdrcnt;
+ desc.format = str2;
+ if (init_package(&desc, 1, 0))
+ {
+ PACKS(&desc, "B13", "lp0");
+ }
- succnt = (desc.errcode == NERR_Success ? 1 : 0);
+ succnt = (desc.errcode == NERR_Success ? 1 : 0);
- *rdata_len = desc.usedlen;
+ *rdata_len = desc.usedlen;
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,succnt);
- SSVAL(*rparam,6,1);
+ *rparam_len = 8;
+ *rparam = REALLOC(*rparam, *rparam_len);
+ SSVALS(*rparam, 0, desc.errcode);
+ SSVAL(*rparam, 2, 0);
+ SSVAL(*rparam, 4, succnt);
+ SSVAL(*rparam, 6, 1);
- DEBUG(4,("WPrintPortEnum: errorcode %d\n",desc.errcode));
- return(True);
+ DEBUG(4, ("WPrintPortEnum: errorcode %d\n", desc.errcode));
+ return (True);
}
/****************************************************************************
- the buffer was too small
+ The buffer was too small
****************************************************************************/
-static BOOL api_TooSmall(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_TooSmall(connection_struct * conn, uint16 vuid, char *param,
+ char *data, int mdrcnt, int mprcnt, char **rdata,
+ char **rparam, int *rdata_len, int *rparam_len)
{
- *rparam_len = MIN(*rparam_len,mprcnt);
- *rparam = REALLOC(*rparam,*rparam_len);
+ *rparam_len = MIN(*rparam_len, mprcnt);
+ *rparam = REALLOC(*rparam, *rparam_len);
- *rdata_len = 0;
+ *rdata_len = 0;
- SSVAL(*rparam,0,NERR_BufTooSmall);
+ SSVAL(*rparam, 0, NERR_BufTooSmall);
- DEBUG(3,("Supplied buffer too small in API command\n"));
+ DEBUG(3, ("Supplied buffer too small in API command\n"));
- return(True);
+ return (True);
}
/****************************************************************************
- the request is not supported
+ The request is not supported
****************************************************************************/
-static BOOL api_Unsupported(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_Unsupported(connection_struct * conn, uint16 vuid,
+ char *param, char *data, int mdrcnt, int mprcnt,
+ char **rdata, char **rparam, int *rdata_len,
+ int *rparam_len)
{
- *rparam_len = 4;
- *rparam = REALLOC(*rparam,*rparam_len);
+ *rparam_len = 4;
+ *rparam = REALLOC(*rparam, *rparam_len);
- *rdata_len = 0;
+ *rdata_len = 0;
- SSVAL(*rparam,0,NERR_notsupported);
- SSVAL(*rparam,2,0); /* converter word */
+ SSVAL(*rparam, 0, NERR_notsupported);
+ SSVAL(*rparam, 2, 0); /* converter word */
- DEBUG(3,("Unsupported API command\n"));
+ DEBUG(3, ("Unsupported API command\n"));
- return(True);
+ return (True);
}
struct
{
- char *name;
- int id;
- BOOL (*fn)(connection_struct *,uint16,char *,char *,
- int,int,char **,char **,int *,int *);
- int flags;
-} api_commands[] = {
- {"RNetShareEnum", 0, api_RNetShareEnum,0},
- {"RNetShareGetInfo", 1, api_RNetShareGetInfo,0},
- {"RNetServerGetInfo", 13, api_RNetServerGetInfo,0},
- {"RNetGroupGetUsers", 52, api_RNetGroupGetUsers,0},
- {"RNetUserGetInfo", 56, api_RNetUserGetInfo,0},
- {"NetUserGetGroups", 59, api_NetUserGetGroups,0},
- {"NetWkstaGetInfo", 63, api_NetWkstaGetInfo,0},
- {"DosPrintQEnum", 69, api_DosPrintQEnum,0},
- {"DosPrintQGetInfo", 70, api_DosPrintQGetInfo,0},
- {"WPrintQueuePause", 74, api_WPrintQueuePurge,0},
- {"WPrintQueueResume", 75, api_WPrintQueuePurge,0},
- {"WPrintJobEnumerate",76, api_WPrintJobEnumerate,0},
- {"WPrintJobGetInfo", 77, api_WPrintJobGetInfo,0},
- {"RDosPrintJobDel", 81, api_RDosPrintJobDel,0},
- {"RDosPrintJobPause", 82, api_RDosPrintJobDel,0},
- {"RDosPrintJobResume",83, api_RDosPrintJobDel,0},
- {"WPrintDestEnum", 84, api_WPrintDestEnum,0},
- {"WPrintDestGetInfo", 85, api_WPrintDestGetInfo,0},
- {"NetRemoteTOD", 91, api_NetRemoteTOD,0},
- {"WPrintQueuePurge", 103, api_WPrintQueuePurge,0},
- {"NetServerEnum", 104, api_RNetServerEnum,0},
- {"WAccessGetUserPerms",105, api_WAccessGetUserPerms,0},
- {"SetUserPassword", 115, api_SetUserPassword,0},
- {"WWkstaUserLogon", 132, api_WWkstaUserLogon,0},
- {"PrintJobInfo", 147, api_PrintJobInfo,0},
- {"WPrintDriverEnum", 205, api_WPrintDriverEnum,0},
- {"WPrintQProcEnum", 206, api_WPrintQProcEnum,0},
- {"WPrintPortEnum", 207, api_WPrintPortEnum,0},
- {"SamOEMChangePassword", 214, api_SamOEMChangePassword,0},
- {NULL, -1, api_Unsupported,0}};
+ char *name;
+ int id;
+ BOOL (*fn) (connection_struct *, uint16, char *, char *,
+ int, int, char **, char **, int *, int *);
+ int flags;
+} api_commands[] =
+{
+ {
+ "RNetShareEnum", 0, api_RNetShareEnum, 0}
+ ,
+ {
+ "RNetShareGetInfo", 1, api_RNetShareGetInfo, 0}
+ ,
+ {
+ "RNetServerGetInfo", 13, api_RNetServerGetInfo, 0}
+ ,
+ {
+ "RNetGroupGetUsers", 52, api_RNetGroupGetUsers, 0}
+ ,
+ {
+ "RNetUserGetInfo", 56, api_RNetUserGetInfo, 0}
+ ,
+ {
+ "NetUserGetGroups", 59, api_NetUserGetGroups, 0}
+ ,
+ {
+ "NetWkstaGetInfo", 63, api_NetWkstaGetInfo, 0}
+ ,
+ {
+ "DosPrintQEnum", 69, api_DosPrintQEnum, 0}
+ ,
+ {
+ "DosPrintQGetInfo", 70, api_DosPrintQGetInfo, 0}
+ ,
+ {
+ "WPrintQueuePause", 74, api_WPrintQueuePurge, 0}
+ ,
+ {
+ "WPrintQueueResume", 75, api_WPrintQueuePurge, 0}
+ ,
+ {
+ "WPrintJobEnumerate", 76, api_WPrintJobEnumerate, 0}
+ ,
+ {
+ "WPrintJobGetInfo", 77, api_WPrintJobGetInfo, 0}
+ ,
+ {
+ "RDosPrintJobDel", 81, api_RDosPrintJobDel, 0}
+ ,
+ {
+ "RDosPrintJobPause", 82, api_RDosPrintJobDel, 0}
+ ,
+ {
+ "RDosPrintJobResume", 83, api_RDosPrintJobDel, 0}
+ ,
+ {
+ "WPrintDestEnum", 84, api_WPrintDestEnum, 0}
+ ,
+ {
+ "WPrintDestGetInfo", 85, api_WPrintDestGetInfo, 0}
+ ,
+ {
+ "NetRemoteTOD", 91, api_NetRemoteTOD, 0}
+ ,
+ {
+ "WPrintQueuePurge", 103, api_WPrintQueuePurge, 0}
+ ,
+ {
+ "NetServerEnum", 104, api_RNetServerEnum, 0}
+ ,
+ {
+ "WAccessGetUserPerms", 105, api_WAccessGetUserPerms, 0}
+ ,
+ {
+ "SetUserPassword", 115, api_SetUserPassword, 0}
+ ,
+ {
+ "WWkstaUserLogon", 132, api_WWkstaUserLogon, 0}
+ ,
+ {
+ "PrintJobInfo", 147, api_PrintJobInfo, 0}
+ ,
+ {
+ "WPrintDriverEnum", 205, api_WPrintDriverEnum, 0}
+ ,
+ {
+ "WPrintQProcEnum", 206, api_WPrintQProcEnum, 0}
+ ,
+ {
+ "WPrintPortEnum", 207, api_WPrintPortEnum, 0}
+ ,
+ {
+ "SamOEMChangePassword", 214, api_SamOEMChangePassword, 0}
+ ,
+ {
+ NULL, -1, api_Unsupported, 0}
+};
/****************************************************************************
- handle remote api calls
+ Handle remote api calls
****************************************************************************/
-int api_reply(connection_struct *conn,uint16 vuid,char *outbuf,char *data,char *params,
- int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
+int api_reply(connection_struct * conn, uint16 vuid, char *outbuf, char *data,
+ char *params, int tdscnt, int tpscnt, int mdrcnt, int mprcnt)
{
- int api_command;
- prs_struct rdata_buf;
- prs_struct rparam_buf;
- char *rdata = NULL;
- char *rparam = NULL;
- int rdata_len = 0;
- int rparam_len = 0;
- BOOL reply=False;
- int i;
-
- SMB_ASSERT(params != 0);
-
- api_command = SVAL(params,0);
-
- DEBUG(3,("Got API command %d of form <%s> <%s> (tdscnt=%d,tpscnt=%d,mdrcnt=%d,mprcnt=%d)\n",
- api_command,
- params+2,
- skip_string(params+2,1),
- tdscnt,tpscnt,mdrcnt,mprcnt));
-
- for (i=0;api_commands[i].name;i++)
- if (api_commands[i].id == api_command && api_commands[i].fn)
- {
- DEBUG(3,("Doing %s\n",api_commands[i].name));
- break;
- }
-
- rdata = (char *)malloc(1024); if (rdata) memset(rdata, 0, 1024);
- rparam = (char *)malloc(1024); if (rparam) memset(rparam, 0, 1024);
-
- if (!rdata || !rparam) {
- DEBUG(0,("api_reply: malloc fail !\n"));
- return -1;
- }
-
- reply = api_commands[i].fn(conn,vuid,params,data,mdrcnt,mprcnt,
- &rdata,&rparam,&rdata_len,&rparam_len);
-
-
- if (rdata_len > mdrcnt ||
- rparam_len > mprcnt)
- {
- reply = api_TooSmall(conn,vuid,params,data,mdrcnt,mprcnt,
- &rdata,&rparam,&rdata_len,&rparam_len);
- }
-
-
- /* if we get False back then it's actually unsupported */
- if (!reply)
- api_Unsupported(conn,vuid,params,data,mdrcnt,mprcnt,
- &rdata,&rparam,&rdata_len,&rparam_len);
-
- prs_create(&rdata_buf , rdata , rdata_len , 0, False);
- prs_create(&rparam_buf, rparam, rparam_len, 0, False);
-
- /* now send the reply */
- send_trans_reply(outbuf, &rdata_buf, &rparam_buf, NULL, 0, 0, False);
-
- prs_free_data(&rdata_buf );
- prs_free_data(&rparam_buf);
-
- return(-1);
-}
+ int api_command;
+ prs_struct rdata_buf;
+ prs_struct rparam_buf;
+ char *rdata = NULL;
+ char *rparam = NULL;
+ int rdata_len = 0;
+ int rparam_len = 0;
+ BOOL reply = False;
+ int i;
+
+ if (params == 0)
+ {
+ DEBUG(0,("ERROR: NULL params in api_reply()\n"));
+ return 0;
+ }
+
+ api_command = SVAL(params, 0);
+
+ DEBUG(3,
+ ("Got API command %d of form <%s> <%s> (tdscnt=%d,tpscnt=%d,mdrcnt=%d,mprcnt=%d)\n",
+ api_command, params + 2, skip_string(params + 2, 1), tdscnt,
+ tpscnt, mdrcnt, mprcnt));
+
+ for (i = 0; api_commands[i].name; i++)
+ if (api_commands[i].id == api_command && api_commands[i].fn)
+ {
+ DEBUG(3, ("Doing %s\n", api_commands[i].name));
+ break;
+ }
+
+ rdata = (char *)malloc(1024);
+ if (rdata)
+ memset(rdata, 0, 1024);
+ rparam = (char *)malloc(1024);
+ if (rparam)
+ memset(rparam, 0, 1024);
+
+ if (!rdata || !rparam)
+ {
+ DEBUG(0, ("api_reply: malloc fail !\n"));
+ return -1;
+ }
+
+ reply = api_commands[i].fn(conn, vuid, params, data, mdrcnt, mprcnt,
+ &rdata, &rparam, &rdata_len, &rparam_len);
+
+
+ if (rdata_len > mdrcnt || rparam_len > mprcnt)
+ {
+ reply = api_TooSmall(conn, vuid, params, data, mdrcnt, mprcnt,
+ &rdata, &rparam, &rdata_len,
+ &rparam_len);
+ }
+
+
+ /* if we get False back then it's actually unsupported */
+ if (!reply)
+ api_Unsupported(conn, vuid, params, data, mdrcnt, mprcnt,
+ &rdata, &rparam, &rdata_len, &rparam_len);
+ prs_create(&rdata_buf, rdata, rdata_len, 0, False);
+ prs_create(&rparam_buf, rparam, rparam_len, 0, False);
+
+ /* now send the reply */
+ send_trans_reply(outbuf, &rdata_buf, &rparam_buf, NULL, 0, 0, False);
+
+ prs_free_data(&rdata_buf);
+ prs_free_data(&rparam_buf);
+
+ return (-1);
+}
* global. There is a call to lp_magicchar() in server.c
* that is used to override the initial value.
*
- * basechars - The set of 36 characters used for name mangling. This
+ * MANGLE_BASE - This is the number of characters we use for name mangling.
+ *
+ * basechars - The set characters used for name mangling. This
* is static (scope is this file only).
*
- * base36() - Macro used to select a character from basechars (i.e.,
- * base36(n) will return the nth digit, modulo 36).
+ * mangle() - Macro used to select a character from basechars (i.e.,
+ * mangle(n) will return the nth digit, modulo MANGLE_BASE).
*
* chartest - array 0..255. The index range is the set of all possible
* values of a byte. For each byte value, the content is a
char magic_char = '~';
-static char basechars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+static char basechars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_-!@#$%";
+#define MANGLE_BASE (sizeof(basechars)/sizeof(char)-1)
static unsigned char chartest[256] = { 0 };
static BOOL ct_initialized = False;
-#define base36(V) ((char)(basechars[(V) % 36]))
+#define mangle(V) ((char)(basechars[(V) % MANGLE_BASE]))
#define BASECHAR_MASK 0xf0
#define ILLEGAL_MASK 0x0f
#define isbasechar(C) ( (chartest[ ((C) & 0xff) ]) & BASECHAR_MASK )
#define isillegal(C) ( (chartest[ ((C) & 0xff) ]) & ILLEGAL_MASK )
-static ubi_cacheRoot mangled_cache[1] = { { { 0 }, 0, 0, 0, 0, 0, 0} };
+static ubi_cacheRoot mangled_cache[1] = { { { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0 } };
static BOOL mc_initialized = False;
#define MANGLED_CACHE_MAX_ENTRIES 0
#define MANGLED_CACHE_MAX_MEMORY 16384
char *illegalchars = "*\\/?<>|\":";
unsigned char *s;
- memset( (char *)chartest, 0, 256 );
+ memset( (char *)chartest, '\0', 256 );
for( s = (unsigned char *)illegalchars; *s; s++ )
chartest[*s] = ILLEGAL_MASK;
s = (unsigned char *)name;
while( *s )
{
- skip = skip_multibyte_char( *s );
+ skip = get_character_len( *s );
if( skip != 0 )
{
s += skip;
dot_pos = NULL;
while( *p )
{
- if( (skip = skip_multibyte_char( *p )) != 0 )
+ if( (skip = get_character_len( *p )) != 0 )
p += skip;
else
{
*
* If the extension of the raw name maps directly to the
* extension of the mangled name, then we'll store both names
- * *without* extensions. That way, we can provide consistant
+ * *without* extensions. That way, we can provide consistent
* reverse mangling for all names that match. The test here is
* a bit more careful than the one done in earlier versions of
* mangle.c:
ubi_cacheEntryPtr new_entry;
char *s1;
char *s2;
- int mangled_len;
- int raw_len;
- int i;
+ size_t mangled_len;
+ size_t raw_len;
+ size_t i;
/* If the cache isn't initialized, give up. */
if( !mc_initialized )
}
}
- /* Allocate a new cache entry. If the allcoation fails, just return. */
+ /* Allocate a new cache entry. If the allocation fails, just return. */
i = sizeof( ubi_cacheEntry ) + mangled_len + raw_len + 2;
new_entry = malloc( i );
if( !new_entry )
*
* ************************************************************************** **
*/
+
BOOL check_mangled_cache( char *s )
- {
+{
ubi_cacheEntryPtr FoundPtr;
char *ext_start = NULL;
char *found_name;
+ char *saved_ext = NULL;
/* If the cache isn't initialized, give up. */
if( !mc_initialized )
/* If we didn't find the name *with* the extension, try without. */
if( !FoundPtr )
- {
+ {
ext_start = strrchr( s, '.' );
if( ext_start )
- {
+ {
+ if((saved_ext = strdup(ext_start)) == NULL)
+ return False;
+
*ext_start = '\0';
FoundPtr = ubi_cacheGet( mangled_cache, (ubi_trItemPtr)s );
- *ext_start = '.';
- }
+ /*
+ * At this point s is the name without the
+ * extension. We re-add the extension if saved_ext
+ * is not null, before freeing saved_ext.
+ */
}
+ }
/* Okay, if we haven't found it we're done. */
if( !FoundPtr )
+ {
+ if(saved_ext)
+ {
+ /* Replace the saved_ext as it was truncated. */
+ (void)pstrcat( s, saved_ext );
+ free(saved_ext);
+ }
return( False );
+ }
/* If we *did* find it, we need to copy it into the string buffer. */
found_name = (char *)(FoundPtr + 1);
DEBUG( 3, ("Found %s on mangled stack ", s) );
(void)pstrcpy( s, found_name );
- if( ext_start )
- (void)pstrcat( s, ext_start );
+ if( saved_ext )
+ {
+ /* Replace the saved_ext as it was truncated. */
+ (void)pstrcat( s, saved_ext );
+ free(saved_ext);
+ }
DEBUG( 3, ("as %s\n", s) );
return( True );
- } /* check_mangled_cache */
+} /* check_mangled_cache */
/* ************************************************************************** **
pstrcpy( matching_bit, "" ); /* Match but no star gets this. */
pp = pat; /* Initialize the pointers. */
sp = s;
+
+ if( strequal(s, ".") || strequal(s, ".."))
+ {
+ return NULL; /* Do not map '.' and '..' */
+ }
+
if( (len == 1) && (*pattern == '*') )
{
return NULL; /* Impossible, too ambiguous for */
*/
void mangle_name_83( char *s)
{
- int csum = str_checksum(s);
+ int csum;
char *p;
char extension[4];
char base[9];
csum = str_checksum( s );
*p = '.';
}
+ else
+ csum = str_checksum(s);
}
+ else
+ csum = str_checksum(s);
strupper( s );
*p++ = 0;
while( *p && extlen < 3 )
{
- skip = skip_multibyte_char( *p );
+ skip = get_character_len( *p );
switch( skip )
{
case 2:
}
else
{
- extension[extlen++] = base36( (unsigned char)*p );
+ extension[extlen++] = mangle( (unsigned char)*p );
}
p += 2;
break;
while( *p && baselen < 5 )
{
- skip = skip_multibyte_char(*p);
+ skip = get_character_len(*p);
switch( skip )
{
case 2:
}
else
{
- base[baselen++] = base36( (unsigned char)*p );
+ base[baselen++] = mangle( (unsigned char)*p );
}
p += 2;
break;
}
base[baselen] = 0;
- csum = csum % (36*36);
+ csum = csum % (MANGLE_BASE*MANGLE_BASE);
(void)slprintf(s, 12, "%s%c%c%c",
- base, magic_char, base36( csum/36 ), base36( csum ) );
+ base, magic_char, mangle( csum/MANGLE_BASE ), mangle( csum ) );
if( *extension )
{
* signal that a client does not require name mangling,
* thus skipping the name mangling even on shares which
* have name-mangling turned on.
+ * cache83 - If False, the mangled name cache will not be updated.
+ * This is usually used to prevent that we overwrite
+ * a conflicting cache entry prematurely, i.e. before
+ * we know whether the client is really interested in the
+ * current name. (See PR#13758). UKD.
* snum - Share number. This identifies the share in which the
* name exists.
*
*
* ****************************************************************************
*/
-BOOL name_map_mangle(char *OutName, BOOL need83, int snum)
+BOOL name_map_mangle(char *OutName, BOOL need83, BOOL cache83, int snum)
{
char *map;
- DEBUG(5,("name_map_mangle( %s, %s, %d )\n",
- OutName, need83?"TRUE":"FALSE", snum));
+ DEBUG(5,("name_map_mangle( %s, need83 = %s, cache83 = %s, %d )\n", OutName,
+ need83 ? "TRUE" : "FALSE", cache83 ? "TRUE" : "FALSE", snum));
#ifdef MANGLE_LONG_FILENAMES
if( !need83 && is_illegal_name(OutName) )
/* check if it's already in 8.3 format */
if (need83 && !is_8_3(OutName, True)) {
- char *tmp;
+ char *tmp = NULL;
if (!lp_manglednames(snum)) {
return(False);
}
/* mangle it into 8.3 */
- tmp = strdup(OutName);
+ if (cache83)
+ tmp = strdup(OutName);
+
mangle_name_83(OutName);
- if(tmp) {
+ if(tmp != NULL) {
cache_mangled_name(OutName, tmp);
free(tmp);
}
/* put it in a temporary file */
slprintf(s,sizeof(s)-1, "%s/msg.XXXXXX",tmpdir());
- fstrcpy(name,(char *)mktemp(s));
+ fstrcpy(name,(char *)smbd_mktemp(s));
fd = sys_open(name,O_WRONLY|O_CREAT|O_TRUNC|O_EXCL,0600);
if (fd == -1) {
return;
}
+ /*
+ * Incoming message is in DOS codepage format. Convert to UNIX in
+ * place.
+ */
+
+ if(msgpos > 0) {
+ msgbuf[msgpos] = '\0'; /* Ensure null terminated. */
+ dos_to_unix(msgbuf,True);
+ }
+
for (i=0;i<msgpos;) {
if (msgbuf[i]=='\r' && i<(msgpos-1) && msgbuf[i+1]=='\n') {
i++; continue;
/* run the command */
if (*lp_msg_command())
{
+ fstring alpha_msgfrom;
+ fstring alpha_msgto;
+
pstrcpy(s,lp_msg_command());
- string_sub(s,"%s",name);
- string_sub(s,"%f",msgfrom);
- string_sub(s,"%t",msgto);
+ pstring_sub(s,"%s",name);
+ pstring_sub(s,"%f",alpha_strcpy(alpha_msgfrom,msgfrom,sizeof(alpha_msgfrom)));
+ pstring_sub(s,"%t",alpha_strcpy(alpha_msgto,msgto,sizeof(alpha_msgto)));
standard_sub_basic(s);
smbrun(s,NULL,False);
}
msgpos = 0;
-
if (! (*lp_msg_command()))
return(ERROR(ERRSRV,ERRmsgoff));
fstrcpy(msgto,dest);
len = SVAL(msg,0);
- len = MIN(len,1600-msgpos);
+ len = MIN(len,sizeof(msgbuf)-msgpos);
+
+ memset(msgbuf,'\0',sizeof(msgbuf));
memcpy(&msgbuf[msgpos],msg+2,len);
msgpos += len;
outsize = set_message(outbuf,1,0,True);
+ memset(msgbuf,'\0',sizeof(msgbuf));
msgpos = 0;
orig = smb_buf(inbuf)+1;
msg = smb_buf(inbuf) + 1;
len = SVAL(msg,0);
- len = MIN(len,1600-msgpos);
+ len = MIN(len,sizeof(msgbuf)-msgpos);
memcpy(&msgbuf[msgpos],msg+2,len);
msgpos += len;
return(outsize);
}
-
extern int max_recv;
extern fstring global_myworkgroup;
extern fstring remote_machine;
-extern dfs_internal dfs_struct;
/****************************************************************************
reply for the core protocol
static int reply_nt1(char *outbuf)
{
/* dual names + lock_and_read + nt SMBs + remote API calls */
+ int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
+ (lp_nt_smb_support() ? CAP_NT_SMBS | CAP_RPC_REMOTE_APIS : 0) |
+ (SMB_OFF_T_BITS == 64 ? CAP_LARGE_FILES : 0);
+
+
+/*
+ other valid capabilities which we may support at some time...
+ CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
+ */
+
int secword=0;
BOOL doencrypt = SMBENCRYPT();
time_t t = time(NULL);
char cryptkey[8];
char crypt_len = 0;
- int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
-
- if (lp_nt_smb_support())
- {
- capabilities |= CAP_NT_SMBS | CAP_RPC_REMOTE_APIS;
- }
-
- if (SMB_OFF_T_BITS == 64)
- {
- capabilities |= CAP_LARGE_FILES;
- }
-
- if (dfs_struct.ready==True)
- {
- capabilities |= CAP_DFS;
- }
-
-/*
- other valid capabilities which we may support at some time...
- CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
- */
if (doencrypt) {
crypt_len = 8;
capabilities |= CAP_RAW_MODE;
}
+#ifdef MS_DFS
+ if(lp_host_msdfs())
+ capabilities |= CAP_DFS;
+#endif
+
if (lp_security() >= SEC_USER) secword |= 1;
if (doencrypt) secword |= 2;
protocol [LANMAN2.1]
protocol [NT LM 0.12]
+Win2K:
+protocol [PC NETWORK PROGRAM 1.0]
+protocol [LANMAN1.0]
+protocol [Windows for Workgroups 3.1a]
+protocol [LM1.2X002]
+protocol [LANMAN2.1]
+protocol [NT LM 0.12]
+
OS/2:
protocol [PC NETWORK PROGRAM 1.0]
protocol [XENIX CORE]
*
* This appears to be the matrix of which protocol is used by which
* MS product.
- Protocol WfWg Win95 WinNT OS/2
- PC NETWORK PROGRAM 1.0 1 1 1 1
+ Protocol WfWg Win95 WinNT Win2K OS/2
+ PC NETWORK PROGRAM 1.0 1 1 1 1 1
XENIX CORE 2 2
MICROSOFT NETWORKS 3.0 2 2
DOS LM1.2X002 3 3
MICROSOFT NETWORKS 1.03 3
DOS LANMAN2.1 4 4
- LANMAN1.0 4 3
- Windows for Workgroups 3.1a 5 5 5
- LM1.2X002 6 4
- LANMAN2.1 7 5
- NT LM 0.12 6 8
+ LANMAN1.0 4 2 3
+ Windows for Workgroups 3.1a 5 5 5 3
+ LM1.2X002 6 4 4
+ LANMAN2.1 7 5 5
+ NT LM 0.12 6 8 6
*
* tim@fsg.com 09/29/95
+ * Win2K added by matty 17/7/99
*/
#define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
#define ARCH_WIN95 0x2
-#define ARCH_OS2 0xC /* Again OS/2 is like NT */
-#define ARCH_WINNT 0x8
-#define ARCH_SAMBA 0x10
+#define ARCH_WINNT 0x4
+#define ARCH_WIN2K 0xC /* Win2K is like NT */
+#define ARCH_OS2 0x14 /* Again OS/2 is like NT */
+#define ARCH_SAMBA 0x20
-#define ARCH_ALL 0x1F
+#define ARCH_ALL 0x3F
/* List of supported protocols, most desired first */
static struct {
{"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
{"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
{"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
- {NULL,NULL},
+ {NULL,NULL,NULL,0},
};
Index++;
DEBUG(3,("Requested protocol [%s]\n",p));
if (strcsequal(p,"Windows for Workgroups 3.1a"))
- arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
+ arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K );
else if (strcsequal(p,"DOS LM1.2X002"))
arch &= ( ARCH_WFWG | ARCH_WIN95 );
else if (strcsequal(p,"DOS LANMAN2.1"))
arch &= ( ARCH_WFWG | ARCH_WIN95 );
else if (strcsequal(p,"NT LM 0.12"))
- arch &= ( ARCH_WIN95 | ARCH_WINNT );
+ arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K );
else if (strcsequal(p,"LANMAN2.1"))
- arch &= ( ARCH_WINNT | ARCH_OS2 );
+ arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
else if (strcsequal(p,"LM1.2X002"))
- arch &= ( ARCH_WINNT | ARCH_OS2 );
+ arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
arch &= ARCH_WINNT;
else if (strcsequal(p,"XENIX CORE"))
set_remote_arch(RA_WIN95);
break;
case ARCH_WINNT:
+ if(SVAL(inbuf,smb_flg2)==FLAGS2_WIN2K_SIGNATURE)
+ set_remote_arch(RA_WIN2K);
+ else
set_remote_arch(RA_WINNT);
break;
+ case ARCH_WIN2K:
+ set_remote_arch(RA_WIN2K);
+ break;
case ARCH_OS2:
set_remote_arch(RA_OS2);
break;
#include "includes.h"
#include "nterr.h"
+#include "sids.h"
extern int DEBUGLEVEL;
extern int Protocol;
extern int Client;
extern int smb_read_error;
extern int global_oplock_break;
-extern int chain_size;
extern BOOL case_sensitive;
extern BOOL case_preserve;
extern BOOL short_case_preserve;
static char *known_nt_pipes[] = {
"\\LANMAN",
"\\srvsvc",
- "\\svcctl",
"\\samr",
"\\wkssvc",
- "\\browser",
"\\NETLOGON",
"\\ntlsa",
"\\ntsvcs",
HACK ! Always assumes smb_setup field is zero.
****************************************************************************/
-static int send_nt_replies(char *outbuf, int bufsize, char *params,
+static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, uint32 nt_error, char *params,
int paramsize, char *pdata, int datasize)
{
extern int max_send;
set_message(outbuf,18,0,True);
+ if(nt_error != 0) {
+ /* NT Error. */
+ SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
+
+ ERROR(0,nt_error);
+ }
+
/*
* If there genuinely are no parameters or data to send just send
* the empty packet.
strings in NT calls AND DOESN'T SET THE UNICODE BIT !!!!!!!
****************************************************************************/
-static void my_wcstombs(char *dst, uint16 *src, size_t len)
+static void get_filename( char *fname, char *inbuf, int data_offset, int data_len, int fname_len)
{
- size_t i;
+ /*
+ * We need various heuristics here to detect a unicode string... JRA.
+ */
- for(i = 0; i < len; i++)
- dst[i] = (char)SVAL(src,i*2);
-}
+ DEBUG(10,("get_filename: data_offset = %d, data_len = %d, fname_len = %d\n",
+ data_offset, data_len, fname_len ));
-static void get_filename( char *fname, char *inbuf, int data_offset, int data_len, int fname_len)
-{
if(data_len - fname_len > 1) {
/*
* NT 5.0 Beta 2 has kindly sent us a UNICODE string
fname_len = fname_len/2;
if(data_offset & 1)
data_offset++;
- my_wcstombs( fname, (uint16 *)(inbuf+data_offset), fname_len);
+ pstrcpy(fname, dos_unistrn2((uint16 *)(inbuf+data_offset), fname_len));
+ } else {
+ StrnCpy(fname,inbuf+data_offset,fname_len);
+ fname[fname_len] = '\0';
+ }
+}
+
+/****************************************************************************
+ Fix bugs in Win2000 final release. In trans calls this OS sends unicode
+ strings AND DOESN'T SET THE UNICODE BIT !!!!!!!
+****************************************************************************/
+
+static void get_filename_transact( char *fname, char *inbuf, int data_offset, int data_len, int fname_len)
+{
+ /*
+ * We need various heuristics here to detect a unicode string... JRA.
+ */
+
+ DEBUG(10,("get_filename_transact: data_offset = %d, data_len = %d, fname_len = %d\n",
+ data_offset, data_len, fname_len ));
+
+ /*
+ * Win2K sends a unicode filename plus one extra alingment byte.
+ * WinNT4.x send an ascii string with multiple garbage bytes on
+ * the end here.
+ */
+
+ if((data_len - fname_len == 1) || (inbuf[data_offset] == '\0')) {
+ /*
+ * Ensure that the data offset is aligned
+ * on a 2 byte boundary - add one if not.
+ */
+ fname_len = fname_len/2;
+ if(data_offset & 1)
+ data_offset++;
+ pstrcpy(fname, dos_unistrn2((uint16 *)(inbuf+data_offset), fname_len));
} else {
StrnCpy(fname,inbuf+data_offset,fname_len);
+ fname[fname_len] = '\0';
}
- fname[fname_len] = '\0';
}
/****************************************************************************
Utility function to map share modes.
****************************************************************************/
-static int map_share_mode( char *fname, uint32 desired_access, uint32 share_access, uint32 file_attributes)
+static int map_share_mode( BOOL *pstat_open_only, char *fname,
+ uint32 desired_access, uint32 share_access, uint32 file_attributes)
{
int smb_open_mode = -1;
- switch( desired_access & (FILE_READ_DATA|FILE_WRITE_DATA) ) {
+ *pstat_open_only = False;
+
+ switch( desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA) ) {
case FILE_READ_DATA:
smb_open_mode = DOS_OPEN_RDONLY;
break;
case FILE_WRITE_DATA:
+ case FILE_APPEND_DATA:
+ case FILE_WRITE_DATA|FILE_APPEND_DATA:
smb_open_mode = DOS_OPEN_WRONLY;
break;
case FILE_READ_DATA|FILE_WRITE_DATA:
+ case FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA:
+ case FILE_READ_DATA|FILE_APPEND_DATA:
smb_open_mode = DOS_OPEN_RDWR;
break;
}
*/
if (smb_open_mode == -1) {
+ if(desired_access == WRITE_DAC_ACCESS || desired_access == READ_CONTROL_ACCESS)
+ *pstat_open_only = True;
+
if(desired_access & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|
FILE_EXECUTE|FILE_READ_ATTRIBUTES|
+ FILE_READ_EA|FILE_WRITE_EA|SYSTEM_SECURITY_ACCESS|
FILE_WRITE_ATTRIBUTES|READ_CONTROL_ACCESS))
smb_open_mode = DOS_OPEN_RDONLY;
else {
void fail_next_srvsvc_open(void)
{
+ /* Check client is WinNT proper; Win2K doesn't like Jeremy's hack - matty */
+ if (get_remote_arch() != RA_WINNT)
+ return;
+
fail_next_srvsvc = True;
fail_time = time(NULL);
DEBUG(10,("fail_next_srvsvc_open: setting up timeout close of \\srvsvc pipe for print fix.\n"));
}
+/*
+ * HACK alert.... see above - JRA.
+ */
+
+BOOL should_fail_next_srvsvc_open(const char *pipename)
+{
+
+ DEBUG(10,("should_fail_next_srvsvc_open: fail = %d, pipe = %s\n",
+ (int)fail_next_srvsvc, pipename));
+
+ if(fail_next_srvsvc && (time(NULL) > fail_time + HACK_FAIL_TIME)) {
+ fail_next_srvsvc = False;
+ fail_time = (time_t)0;
+ DEBUG(10,("should_fail_next_srvsvc_open: End of timeout close of \\srvsvc pipe for print fix.\n"));
+ }
+
+ if(fail_next_srvsvc && strequal(pipename, "srvsvc")) {
+ fail_next_srvsvc = False;
+ DEBUG(10,("should_fail_next_srvsvc_open: Deliberately failing open of \\srvsvc pipe for print fix.\n"));
+ return True;
+ }
+ return False;
+}
+
+
/****************************************************************************
Reply to an NT create and X call on a pipe.
****************************************************************************/
static int nt_open_pipe(char *fname, connection_struct *conn,
char *inbuf, char *outbuf, int *ppnum)
{
- vuser_key key;
pipes_struct *p = NULL;
-
+ vuser_key key;
uint16 vuid = SVAL(inbuf, smb_uid);
int i;
if( strequal(fname,known_nt_pipes[i]))
break;
- /*
- * HACK alert.... see above - JRA.
- */
-
- if(fail_next_srvsvc && (time(NULL) > fail_time + HACK_FAIL_TIME)) {
- fail_next_srvsvc = False;
- fail_time = (time_t)0;
- DEBUG(10,("nt_open_pipe: End of timeout close of \\srvsvc pipe for print fix.\n"));
- }
-
- if(fail_next_srvsvc && strequal(fname, "\\srvsvc")) {
- fail_next_srvsvc = False;
- DEBUG(10,("nt_open_pipe: Deliberately failing open of \\srvsvc pipe for print fix.\n"));
- return(ERROR(ERRSRV,ERRaccess));
- }
-
- /*
- * End hack alert.... see above - JRA.
- */
-
if ( known_nt_pipes[i] == NULL )
return(ERROR(ERRSRV,ERRaccess));
/* Strip \\ off the name. */
fname++;
+ if(should_fail_next_srvsvc_open(fname))
+ return (ERROR(ERRSRV,ERRaccess));
+
DEBUG(3,("nt_open_pipe: Known pipe %s opening.\n", fname));
key.pid = getpid();
/* Breakout the oplock request bits so we can set the
reply bits separately. */
int oplock_request = 0;
- mode_t unixmode;
+ mode_t unixmode;
int pnum = -1;
int fmode=0,rmode=0;
SMB_OFF_T file_len = 0;
BOOL bad_path = False;
files_struct *fsp=NULL;
char *p = NULL;
+ BOOL stat_open_only = False;
/*
* We need to construct the open_and_X ofun value from the
files_struct *dir_fsp = file_fsp(inbuf,smb_ntcreate_RootDirectoryFid);
size_t dir_name_len;
- if(!dir_fsp || !dir_fsp->is_directory)
+ if(!dir_fsp)
+ return(ERROR(ERRDOS,ERRbadfid));
+
+ if(!dir_fsp->is_directory) {
+ /*
+ * Check to see if this is a mac fork of some kind.
+ */
+
+ get_filename(&fname[0], inbuf, smb_buf(inbuf)-inbuf,
+ smb_buflen(inbuf),fname_len);
+
+ if( fname[0] == ':') {
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_OBJECT_PATH_NOT_FOUND));
+ }
return(ERROR(ERRDOS,ERRbadfid));
+ }
/*
* Copy in the base directory name.
dir_name_len++;
}
+ /*
+ * This next calculation can refuse a correct filename if we're dealing
+ * with the Win2k unicode bug, but that would be rare. JRA.
+ */
+
if(fname_len + dir_name_len >= sizeof(pstring))
return(ERROR(ERRSRV,ERRfilespecs));
get_filename(&fname[dir_name_len], inbuf, smb_buf(inbuf)-inbuf,
smb_buflen(inbuf),fname_len);
-#if 0
- StrnCpy(&fname[dir_name_len], smb_buf(inbuf),fname_len);
- fname[dir_name_len+fname_len] = '\0';
-#endif
} else {
get_filename(fname, inbuf, smb_buf(inbuf)-inbuf,
smb_buflen(inbuf),fname_len);
-
-#if 0
- StrnCpy(fname,smb_buf(inbuf),fname_len);
- fname[fname_len] = '\0';
-#endif
}
/* If it's an IPC, use the pipe handler. */
- if (IS_IPC(conn) && lp_nt_pipe_support() && lp_security() != SEC_SHARE)
- {
+ if (IS_IPC(conn) && lp_nt_pipe_support()) {
+
int ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum);
if(ret != 0)
return ret;
* Now contruct the smb_open_mode value from the filename,
* desired access and the share access.
*/
-
- if((smb_open_mode = map_share_mode(fname, desired_access,
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
+ if((smb_open_mode = map_share_mode(&stat_open_only, fname, desired_access,
share_access,
- file_attributes)) == -1) {
+ file_attributes)) == -1)
return(ERROR(ERRDOS,ERRbadaccess));
- }
+
+ oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
+ oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
/*
* Ordinary file or directory.
set_posix_case_semantics(file_attributes);
- if (!unix_dfs_convert(fname,conn,0,&bad_path,NULL))
- {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
- }
+ unix_convert(fname,conn,0,&bad_path,NULL);
fsp = file_new();
if (!fsp) {
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- unixmode = unix_mode(conn,smb_attr | aARCH);
+ unixmode = unix_mode(conn,smb_attr | aARCH, fname);
- oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
- oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
-
/*
* If it's a request for a directory open, deal with it separately.
*/
if(create_options & FILE_DIRECTORY_FILE) {
oplock_request = 0;
- open_directory(fsp, conn, fname, smb_ofun, unixmode,
- &smb_action);
+ open_directory(fsp, conn, fname, smb_ofun,
+ unixmode, &smb_action);
restore_case_semantics(file_attributes);
* before issuing an oplock break request to
* our client. JRA. */
- open_file_shared(fsp,conn,fname,smb_open_mode,
- smb_ofun,unixmode,
- oplock_request,&rmode,&smb_action);
+ open_file_shared(fsp,conn,fname,smb_open_mode,
+ smb_ofun,unixmode, oplock_request,&rmode,&smb_action);
if (!fsp->open) {
- /* We cheat here. The only case we
- * care about is a directory rename,
+ /* We cheat here. There are two cases we
+ * care about. One is a directory rename,
* where the NT client will attempt to
* open the source directory for
* DELETE access. Note that when the
* will generate an EISDIR error, so
* we can catch this here and open a
* pseudo handle that is flagged as a
- * directory. JRA. */
+ * directory. The second is an open
+ * for a permissions read only, which
+ * we handle in the open_file_stat case. JRA.
+ */
if(errno == EISDIR) {
+
+ /*
+ * Fail the open if it was explicitly a non-directory file.
+ */
+
+ if (create_options & FILE_NON_DIRECTORY_FILE) {
+ file_free(fsp);
+ restore_case_semantics(file_attributes);
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_FILE_IS_A_DIRECTORY));
+ }
+
oplock_request = 0;
+ open_directory(fsp, conn, fname, smb_ofun, unixmode, &smb_action);
- open_directory(fsp, conn, fname,
- smb_ofun, unixmode,
- &smb_action);
-
if(!fsp->open) {
file_free(fsp);
restore_case_semantics(file_attributes);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
+#ifdef EROFS
+ } else if (((errno == EACCES) || (errno == EROFS)) && stat_open_only) {
+#else /* !EROFS */
+ } else if (errno == EACCES && stat_open_only) {
+#endif
+ /*
+ * We couldn't open normally and all we want
+ * are the permissions. Try and do a stat open.
+ */
+
+ oplock_request = 0;
+
+ open_file_stat(fsp,conn,fname,smb_open_mode,&sbuf,&smb_action);
+
+ if(!fsp->open) {
+ file_free(fsp);
+ restore_case_semantics(file_attributes);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
} else {
+
if((errno == ENOENT) && bad_path) {
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
if(fsp->is_directory) {
- if(fsp->conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name, False),
- &sbuf) != 0) {
- close_directory(fsp);
+ if(conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name, False), &sbuf) != 0) {
+ close_file(fsp,True);
restore_case_semantics(file_attributes);
return(ERROR(ERRDOS,ERRnoaccess));
}
} else {
- if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf)
- != 0) {
+ if (conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
close_file(fsp,False);
restore_case_semantics(file_attributes);
return(ERROR(ERRDOS,ERRnoaccess));
if (oplock_request && lp_fake_oplocks(SNUM(conn)))
smb_action |= EXTENDED_OPLOCK_GRANTED;
- if(oplock_request && fsp->granted_oplock)
+ if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
smb_action |= EXTENDED_OPLOCK_GRANTED;
-
+
set_message(outbuf,34,0,True);
p = outbuf + smb_vwv2;
* Currently as we don't support level II oplocks we just report
* exclusive & batch here.
*/
+
+ if (smb_action & EXTENDED_OPLOCK_GRANTED)
+ SCVAL(p,0, BATCH_OPLOCK_RETURN);
+ else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
+ SCVAL(p,0, LEVEL_II_OPLOCK_RETURN);
+ else
+ SCVAL(p,0,NO_OPLOCK_RETURN);
- SCVAL(p,0, (smb_action & EXTENDED_OPLOCK_GRANTED ? 1 : 0));
p++;
SSVAL(p,0,fsp->fnum);
p += 2;
/****************************************************************************
Reply to a NT_TRANSACT_CREATE call (needs to process SD's).
****************************************************************************/
+
static int call_nt_transact_create(connection_struct *conn,
- char *inbuf, char *outbuf, int length,
- int bufsize,
- char **ppsetup, char **ppparams,
- char **ppdata)
+ char *inbuf, char *outbuf, int length,
+ int bufsize, char **ppsetup, char **ppparams,
+ char **ppdata)
{
pstring fname;
char *params = *ppparams;
- uint32 flags = IVAL(params,0);
- uint32 desired_access = IVAL(params,8);
- uint32 file_attributes = IVAL(params,20);
- uint32 share_access = IVAL(params,24);
- uint32 create_disposition = IVAL(params,28);
- uint32 create_options = IVAL(params,32);
- uint32 fname_len = MIN(((uint32)IVAL(params,44)),
- ((uint32)sizeof(fname)-1));
- uint16 root_dir_fid = (uint16)IVAL(params,4);
- int smb_ofun;
- int smb_open_mode;
- int smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK);
+ int total_parameter_count = (int)IVAL(inbuf, smb_nt_TotalParameterCount);
/* Breakout the oplock request bits so we can set the
reply bits separately. */
int oplock_request = 0;
BOOL bad_path = False;
files_struct *fsp = NULL;
char *p = NULL;
+ BOOL stat_open_only = False;
+ uint32 flags;
+ uint32 desired_access;
+ uint32 file_attributes;
+ uint32 share_access;
+ uint32 create_disposition;
+ uint32 create_options;
+ uint32 fname_len;
+ uint16 root_dir_fid;
+ int smb_ofun;
+ int smb_open_mode;
+ int smb_attr;
+
+ DEBUG(5,("call_nt_transact_create\n"));
+
+ /*
+ * Ensure minimum number of parameters sent.
+ */
+
+ if(total_parameter_count < 54) {
+ DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)total_parameter_count));
+ return(ERROR(ERRDOS,ERRbadaccess));
+ }
+
+ flags = IVAL(params,0);
+ desired_access = IVAL(params,8);
+ file_attributes = IVAL(params,20);
+ share_access = IVAL(params,24);
+ create_disposition = IVAL(params,28);
+ create_options = IVAL(params,32);
+ fname_len = MIN(((uint32)IVAL(params,44)),((uint32)sizeof(fname)-1));
+ root_dir_fid = (uint16)IVAL(params,4);
+ smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK);
/*
* We need to construct the open_and_X ofun value from the
*/
if((smb_ofun = map_create_disposition( create_disposition )) == -1)
- return(ERROR(ERRDOS,ERRbadaccess));
+ return(ERROR(ERRDOS,ERRbadmem));
/*
* Get the file name.
files_struct *dir_fsp = file_fsp(params,4);
size_t dir_name_len;
- if(!dir_fsp || !dir_fsp->is_directory)
+ if(!dir_fsp)
+ return(ERROR(ERRDOS,ERRbadfid));
+
+ if(!dir_fsp->is_directory) {
+ /*
+ * Check to see if this is a mac fork of some kind.
+ */
+
+ get_filename_transact(&fname[0], params, 53,
+ total_parameter_count - 53 - fname_len, fname_len);
+
+ if( fname[0] == ':') {
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_OBJECT_PATH_NOT_FOUND));
+ }
+
return(ERROR(ERRDOS,ERRbadfid));
+ }
/*
* Copy in the base directory name.
dir_name_len++;
}
+ /*
+ * This next calculation can refuse a correct filename if we're dealing
+ * with the Win2k unicode bug, but that would be rare. JRA.
+ */
+
if(fname_len + dir_name_len >= sizeof(pstring))
return(ERROR(ERRSRV,ERRfilespecs));
- StrnCpy(&fname[dir_name_len], params+53, fname_len);
- fname[dir_name_len+fname_len] = '\0';
+ get_filename_transact(&fname[dir_name_len], params, 53,
+ total_parameter_count - 53 - fname_len, fname_len);
} else {
- StrnCpy(fname,params+53,fname_len);
- fname[fname_len] = '\0';
+ get_filename_transact(&fname[0], params, 53,
+ total_parameter_count - 53 - fname_len, fname_len);
}
/* If it's an IPC, use the pipe handler. */
return ret;
smb_action = FILE_WAS_OPENED;
} else {
+
+ /*
+ * Now contruct the smb_open_mode value from the desired access
+ * and the share access.
+ */
+
+ if((smb_open_mode = map_share_mode( &stat_open_only, fname, desired_access,
+ share_access, file_attributes)) == -1)
+ return(ERROR(ERRDOS,ERRbadaccess));
+
+ oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
+ oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
+
/*
* Check if POSIX semantics are wanted.
*/
set_posix_case_semantics(file_attributes);
+
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
- if (!unix_dfs_convert(fname,conn,0,&bad_path,NULL))
- {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
- }
+ unix_convert(fname,conn,0,&bad_path,NULL);
fsp = file_new();
if (!fsp) {
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- unixmode = unix_mode(conn,smb_attr | aARCH);
+ unixmode = unix_mode(conn,smb_attr | aARCH, fname);
- oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
- oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
-
- /*
- * Now contruct the smb_open_mode value from the desired access
- * and the share access.
- */
-
- if((smb_open_mode = map_share_mode( fname, desired_access, share_access, file_attributes)) == -1)
- return(ERROR(ERRDOS,ERRbadaccess));
-
/*
* If it's a request for a directory open, deal with it separately.
*/
if(!fsp->open) {
file_free(fsp);
+ restore_case_semantics(file_attributes);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
+
+ if(conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name, False),
+ &sbuf) != 0) {
+ close_file(fsp,True);
+ restore_case_semantics(file_attributes);
+ return(ERROR(ERRDOS,ERRnoaccess));
+ }
+
} else {
/*
* Ordinary file case.
*/
- open_file_shared(fsp,conn,fname,smb_open_mode,smb_ofun,
- unixmode,oplock_request,&rmode,&smb_action);
+ open_file_shared(fsp,conn,fname,smb_open_mode,smb_ofun,unixmode,
+ oplock_request,&rmode,&smb_action);
if (!fsp->open) {
- if((errno == ENOENT) && bad_path) {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- file_free(fsp);
- restore_case_semantics(file_attributes);
+ if(errno == EISDIR) {
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
- close_file(fsp,False);
+ /*
+ * Fail the open if it was explicitly a non-directory file.
+ */
- restore_case_semantics(file_attributes);
+ if (create_options & FILE_NON_DIRECTORY_FILE) {
+ file_free(fsp);
+ restore_case_semantics(file_attributes);
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_FILE_IS_A_DIRECTORY));
+ }
+
+ oplock_request = 0;
+ open_directory(fsp, conn, fname, smb_ofun, unixmode, &smb_action);
+
+ if(!fsp->open) {
+ file_free(fsp);
+ restore_case_semantics(file_attributes);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+#ifdef EROFS
+ } else if (((errno == EACCES) || (errno == EROFS)) && stat_open_only) {
+#else /* !EROFS */
+ } else if (errno == EACCES && stat_open_only) {
+#endif
- return(ERROR(ERRDOS,ERRnoaccess));
+ /*
+ * We couldn't open normally and all we want
+ * are the permissions. Try and do a stat open.
+ */
+
+ oplock_request = 0;
+
+ open_file_stat(fsp,conn,fname,smb_open_mode,&sbuf,&smb_action);
+
+ if(!fsp->open) {
+ file_free(fsp);
+ restore_case_semantics(file_attributes);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+ } else {
+
+ if((errno == ENOENT) && bad_path) {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadpath;
+ }
+ file_free(fsp);
+
+ restore_case_semantics(file_attributes);
+
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
}
+ if(fsp->is_directory) {
+ if(conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name,False), &sbuf) != 0) {
+ close_file(fsp,True);
+ restore_case_semantics(file_attributes);
+ return(ERROR(ERRDOS,ERRnoaccess));
+ }
+ } else {
+ if (!fsp->stat_open && conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
+ close_file(fsp,False);
+ restore_case_semantics(file_attributes);
+ return(ERROR(ERRDOS,ERRnoaccess));
+ }
+ }
+
file_len = sbuf.st_size;
fmode = dos_mode(conn,fname,&sbuf);
if(fmode == 0)
if (oplock_request && lp_fake_oplocks(SNUM(conn)))
smb_action |= EXTENDED_OPLOCK_GRANTED;
- if(oplock_request && fsp->granted_oplock)
+ if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
smb_action |= EXTENDED_OPLOCK_GRANTED;
}
}
if(params == NULL)
return(ERROR(ERRDOS,ERRnomem));
+ memset((char *)params,'\0',69);
+
p = params;
- SCVAL(p,0, (smb_action & EXTENDED_OPLOCK_GRANTED ? 1 : 0));
+ if (smb_action & EXTENDED_OPLOCK_GRANTED)
+ SCVAL(p,0, BATCH_OPLOCK_RETURN);
+ else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
+ SCVAL(p,0, LEVEL_II_OPLOCK_RETURN);
+ else
+ SCVAL(p,0,NO_OPLOCK_RETURN);
+
p += 2;
if (IS_IPC(conn)) {
SSVAL(p,0,pnum);
SOFF_T(p,0,file_len);
}
+ DEBUG(5,("call_nt_transact_create: open name = %s\n", fname));
+
/* Send the required number of replies */
- send_nt_replies(outbuf, bufsize, params, 69, *ppdata, 0);
+ send_nt_replies(inbuf, outbuf, bufsize, 0, params, 69, *ppdata, 0);
return -1;
}
/****************************************************************************
Reply to an NT transact rename command.
****************************************************************************/
+
static int call_nt_transact_rename(connection_struct *conn,
char *inbuf, char *outbuf, int length,
int bufsize,
/*
* Rename was successful.
*/
- send_nt_replies(outbuf, bufsize, NULL, 0, NULL, 0);
+ send_nt_replies(inbuf, outbuf, bufsize, 0, NULL, 0, NULL, 0);
DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n",
fsp->fsp_name, new_name));
return(outsize);
}
+/****************************************************************************
+ This is the structure to keep the information needed to
+ determine if a directory has changed.
+*****************************************************************************/
+
+typedef struct {
+ time_t modify_time; /* Info from the directory we're monitoring. */
+ time_t status_time; /* Info from the directory we're monitoring. */
+ time_t total_time; /* Total time of all directory entries - don't care if it wraps. */
+ unsigned int num_entries; /* Zero or the number of files in the directory. */
+} change_hash_data;
+
/****************************************************************************
This is the structure to queue to implement NT change
notify. It consists of smb_size bytes stored from the
ubi_slNode msg_next;
files_struct *fsp;
connection_struct *conn;
+ uint32 flags;
time_t next_check_time;
- time_t modify_time; /* Info from the directory we're monitoring. */
- time_t status_time; /* Info from the directory we're monitoring. */
+ change_hash_data change_data;
char request_buf[smb_size];
} change_notify_buf;
}
/****************************************************************************
- Delete entries by fnum from the change notify pending queue.
+ Create the hash we will use to determine if the contents changed.
*****************************************************************************/
-void remove_pending_change_notify_requests_by_fid(files_struct *fsp)
+
+static BOOL create_directory_notify_hash( change_notify_buf *cnbp, change_hash_data *change_data)
{
- change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
- change_notify_buf *prev = NULL;
+ SMB_STRUCT_STAT st;
+ files_struct *fsp = cnbp->fsp;
- while(cnbp != NULL) {
- if(cnbp->fsp->fnum == fsp->fnum) {
- free((char *)ubi_slRemNext( &change_notify_queue, prev));
- cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
- continue;
- }
+ memset((char *)change_data, '\0', sizeof(change_data));
- prev = cnbp;
- cnbp = (change_notify_buf *)ubi_slNext(cnbp);
+ /*
+ * Store the current timestamp on the directory we are monitoring.
+ */
+
+ if(dos_stat(fsp->fsp_name, &st) < 0) {
+ DEBUG(0,("create_directory_notify_hash: Unable to stat name = %s. \
+Error was %s\n", fsp->fsp_name, strerror(errno) ));
+ return False;
}
-}
+
+ change_data->modify_time = st.st_mtime;
+ change_data->status_time = st.st_ctime;
-/****************************************************************************
- Delete entries by mid from the change notify pending queue. Always send reply.
-*****************************************************************************/
+ /*
+ * If we are to watch for changes that are only stored
+ * in inodes of files, not in the directory inode, we must
+ * scan the directory and produce a unique identifier with
+ * which we can determine if anything changed. We use the
+ * modify and change times from all the files in the
+ * directory, added together (ignoring wrapping if it's
+ * larger than the max time_t value).
+ */
-static void remove_pending_change_notify_requests_by_mid(int mid)
-{
- change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
- change_notify_buf *prev = NULL;
+ if(cnbp->flags & (FILE_NOTIFY_CHANGE_SIZE|FILE_NOTIFY_CHANGE_LAST_WRITE)) {
+ pstring full_name;
+ char *p;
+ char *fname;
+ size_t remaining_len;
+ size_t fullname_len;
+ void *dp = OpenDir(cnbp->conn, fsp->fsp_name, True);
- while(cnbp != NULL) {
- if(SVAL(cnbp->request_buf,smb_mid) == mid) {
- change_notify_reply_packet(cnbp->request_buf,0,NT_STATUS_CANCELLED);
- free((char *)ubi_slRemNext( &change_notify_queue, prev));
- cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
- continue;
+ if(dp == NULL) {
+ DEBUG(0,("create_directory_notify_hash: Unable to open directory = %s. \
+Error was %s\n", fsp->fsp_name, strerror(errno) ));
+ return False;
+ }
+
+ change_data->num_entries = 0;
+
+ pstrcpy(full_name, fsp->fsp_name);
+ pstrcat(full_name, "/");
+
+ fullname_len = strlen(full_name);
+ remaining_len = sizeof(full_name) - fullname_len - 1;
+ p = &full_name[fullname_len];
+
+ while ((fname = ReadDirName(dp))) {
+ if(strequal(fname, ".") || strequal(fname, ".."))
+ continue;
+
+ change_data->num_entries++;
+ safe_strcpy( p, fname, remaining_len);
+
+ memset(&st, '\0', sizeof(st));
+
+ /*
+ * Do the stat - but ignore errors.
+ */
+
+ if(dos_stat(full_name, &st) < 0) {
+ DEBUG(5,("create_directory_notify_hash: Unable to stat content file = %s. \
+Error was %s\n", fsp->fsp_name, strerror(errno) ));
+ }
+ change_data->total_time += (st.st_mtime + st.st_ctime);
+ }
+
+ CloseDir(dp);
+ }
+
+ return True;
+}
+
+/****************************************************************************
+ Delete entries by fnum from the change notify pending queue.
+*****************************************************************************/
+
+void remove_pending_change_notify_requests_by_fid(files_struct *fsp)
+{
+ change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
+ change_notify_buf *prev = NULL;
+
+ while(cnbp != NULL) {
+ if(cnbp->fsp->fnum == fsp->fnum) {
+ free((char *)ubi_slRemNext( &change_notify_queue, prev));
+ cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
+ continue;
+ }
+
+ prev = cnbp;
+ cnbp = (change_notify_buf *)ubi_slNext(cnbp);
+ }
+}
+
+/****************************************************************************
+ Delete entries by mid from the change notify pending queue. Always send reply.
+*****************************************************************************/
+
+static void remove_pending_change_notify_requests_by_mid(int mid)
+{
+ change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
+ change_notify_buf *prev = NULL;
+
+ while(cnbp != NULL) {
+ if(SVAL(cnbp->request_buf,smb_mid) == mid) {
+ change_notify_reply_packet(cnbp->request_buf,0,NT_STATUS_CANCELLED);
+ free((char *)ubi_slRemNext( &change_notify_queue, prev));
+ cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
+ continue;
+ }
+
+ prev = cnbp;
+ cnbp = (change_notify_buf *)ubi_slNext(cnbp);
+ }
+}
+
+/****************************************************************************
+ Delete entries by filename and cnum from the change notify pending queue.
+ Always send reply.
+*****************************************************************************/
+
+void remove_pending_change_notify_requests_by_filename(files_struct *fsp)
+{
+ change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
+ change_notify_buf *prev = NULL;
+
+ while(cnbp != NULL) {
+ /*
+ * We know it refers to the same directory if the connection number and
+ * the filename are identical.
+ */
+ if((cnbp->fsp->conn == fsp->conn) && strequal(cnbp->fsp->fsp_name,fsp->fsp_name)) {
+ change_notify_reply_packet(cnbp->request_buf,0,NT_STATUS_CANCELLED);
+ free((char *)ubi_slRemNext( &change_notify_queue, prev));
+ cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
+ continue;
}
prev = cnbp;
/****************************************************************************
Process the change notify queue. Note that this is only called as root.
+ Returns True if there are still outstanding change notify requests on the
+ queue.
*****************************************************************************/
-void process_pending_change_notify_queue(time_t t)
+BOOL process_pending_change_notify_queue(time_t t)
{
change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
change_notify_buf *prev = NULL;
if(cnbp == NULL)
- return;
+ return False;
if(cnbp->next_check_time >= t)
- return;
+ return True;
/*
* It's time to check. Go through the queue and see if
*/
while((cnbp != NULL) && (cnbp->next_check_time <= t)) {
- SMB_STRUCT_STAT st;
- files_struct *fsp = cnbp->fsp;
+ change_hash_data change_data;
connection_struct *conn = cnbp->conn;
uint16 vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID :
SVAL(cnbp->request_buf,smb_uid);
continue;
}
- if(fsp->conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name, False), &st) < 0) {
- DEBUG(0,("process_pending_change_notify_queue: Unable to stat directory %s. \
-Error was %s.\n", fsp->fsp_name, strerror(errno) ));
+ if(!create_directory_notify_hash( cnbp, &change_data)) {
+ DEBUG(0,("process_pending_change_notify_queue: Unable to create change data for \
+directory %s\n", cnbp->fsp->fsp_name ));
/*
* Remove the entry and return an error to the client.
*/
continue;
}
- if(cnbp->modify_time != st.st_mtime ||
- cnbp->status_time != st.st_ctime) {
+ if(memcmp( (char *)&cnbp->change_data, (char *)&change_data, sizeof(change_data))) {
/*
* Remove the entry and return a change notify to the client.
*/
- DEBUG(5,("process_pending_change_notify_queue: directory name = %s changed\n",
- fsp->fsp_name ));
+ DEBUG(5,("process_pending_change_notify_queue: directory name = %s changed.\n",
+ cnbp->fsp->fsp_name ));
change_notify_reply_packet(cnbp->request_buf,0,NT_STATUS_NOTIFY_ENUM_DIR);
free((char *)ubi_slRemNext( &change_notify_queue, prev));
cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
prev = cnbp;
cnbp = (change_notify_buf *)ubi_slNext(cnbp);
}
+
+ return (cnbp != NULL);
+}
+
+/****************************************************************************
+ Return true if there are pending change notifies.
+****************************************************************************/
+
+BOOL change_notifies_pending(void)
+{
+ change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
+ return (cnbp != NULL);
}
/****************************************************************************
Reply to a notify change - queue the request and
don't allow a directory to be opened.
****************************************************************************/
+
static int call_nt_transact_notify_change(connection_struct *conn,
- char *inbuf, char *outbuf, int length,
+ char *inbuf, char *outbuf, int length,
int bufsize,
char **ppsetup,
- char **ppparams, char **ppdata)
+ char **ppparams, char **ppdata)
{
char *setup = *ppsetup;
files_struct *fsp;
change_notify_buf *cnbp;
- SMB_STRUCT_STAT st;
fsp = file_fsp(setup,4);
*/
if((cnbp = (change_notify_buf *)malloc(sizeof(change_notify_buf))) == NULL) {
- DEBUG(0,("call_nt_transact_notify_change: Malloc fail (2) !\n" ));
+ DEBUG(0,("call_nt_transact_notify_change: malloc fail !\n" ));
return -1;
}
- /*
- * Store the current timestamp on the directory we are monitoring.
- */
+ memset((char *)cnbp, '\0', sizeof(change_notify_buf));
- if(fsp->conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name, False), &st) < 0) {
- DEBUG(0,("call_nt_transact_notify_change: Unable to stat name = %s. \
-Error was %s\n", fsp->fsp_name, strerror(errno) ));
- free((char *)cnbp);
- return(UNIXERROR(ERRDOS,ERRbadfid));
- }
-
memcpy(cnbp->request_buf, inbuf, smb_size);
cnbp->fsp = fsp;
cnbp->conn = conn;
- cnbp->modify_time = st.st_mtime;
- cnbp->status_time = st.st_ctime;
-
cnbp->next_check_time = time(NULL) + lp_change_notify_timeout();
+ cnbp->flags = IVAL(setup, 0);
+
+ if(!create_directory_notify_hash( cnbp, &cnbp->change_data )) {
+ free((char *)cnbp);
+ return(UNIXERROR(ERRDOS,ERRbadfid));
+ }
/*
* Adding to the tail enables us to check only
return -1;
}
+/****************************************************************************
+ Map unix perms to NT.
+****************************************************************************/
+
+static SEC_ACCESS map_unix_perms( int *pacl_type, mode_t perm, int r_mask, int w_mask, int x_mask, BOOL is_directory)
+{
+ SEC_ACCESS sa;
+ uint32 nt_mask = 0;
+
+ *pacl_type = SEC_ACE_TYPE_ACCESS_ALLOWED;
+
+ if((perm & (r_mask|w_mask|x_mask)) == (r_mask|w_mask|x_mask)) {
+ nt_mask = UNIX_ACCESS_RWX;
+ } else if((perm & (r_mask|w_mask|x_mask)) == 0) {
+ nt_mask = UNIX_ACCESS_NONE;
+ } else {
+ nt_mask |= (perm & r_mask) ? UNIX_ACCESS_R : 0;
+ if(is_directory)
+ nt_mask |= (perm & w_mask) ? UNIX_ACCESS_W : 0;
+ else
+ nt_mask |= (perm & w_mask) ? UNIX_ACCESS_W : 0;
+ nt_mask |= (perm & x_mask) ? UNIX_ACCESS_X : 0;
+ }
+ make_sec_access(&sa,nt_mask);
+ return sa;
+}
+
+/****************************************************************************
+ Function to create owner and group SIDs from a SMB_STRUCT_STAT.
+****************************************************************************/
+
+static BOOL create_file_sids(SMB_STRUCT_STAT *psbuf, DOM_SID *powner_sid, DOM_SID *pgroup_sid)
+{
+ POSIX_ID id;
+
+ ZERO_STRUCTP(powner_sid);
+ ZERO_STRUCTP(pgroup_sid);
+ DEBUG(0,("TODO: create_file_sids: not ok to assume gid is NT group\n"));
+
+ id.type = SURS_POSIX_UID_AS_USR;
+ id.id = (uint32)psbuf->st_uid;
+
+ if (!surs_unixid_to_sam_sid(&id, powner_sid, False))
+ {
+ DEBUG(3,("create_file_sids: map uid %d failed\n",
+ (int)psbuf->st_uid));
+ return False;
+ }
+
+ id.type = SURS_POSIX_GID_AS_GRP;
+ id.id = (uint32)psbuf->st_gid;
+
+ if (!surs_unixid_to_sam_sid(&id, pgroup_sid, False))
+ {
+ DEBUG(3,("create_file_sids: map gid %d to group failed\n",
+ (int)psbuf->st_gid));
+
+ id.type = SURS_POSIX_GID_AS_ALS;
+ id.id = (uint32)psbuf->st_gid;
+
+ if (surs_unixid_to_sam_sid(&id, pgroup_sid, False))
+ {
+ return True;
+ }
+ DEBUG(3,("create_file_sids: map gid %d to alias failed\n",
+ (int)psbuf->st_gid));
+ return False;
+ }
+ return True;
+}
+
+/****************************************************************************
+ Reply to query a security descriptor from an fsp. If it succeeds it allocates
+ the space for the return elements and returns True.
+****************************************************************************/
+
+static size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
+{
+ SMB_STRUCT_STAT sbuf;
+ SEC_ACE *ace_list = NULL;
+ DOM_SID owner_sid;
+ DOM_SID group_sid;
+ size_t sec_desc_size;
+ SEC_ACL *psa = NULL;
+ SEC_ACCESS owner_access;
+ int owner_acl_type;
+ SEC_ACCESS group_access;
+ int grp_acl_type;
+ SEC_ACCESS other_access;
+ int other_acl_type;
+ int num_acls = 0;
+
+ (*ppdesc) = NULL;
+
+ if(!lp_nt_acl_support()) {
+ sid_copy( &owner_sid, global_sid_everyone);
+ sid_copy( &group_sid, global_sid_everyone);
+ } else {
+
+ if(fsp->is_directory || fsp->fd_ptr == NULL) {
+ if(dos_stat(fsp->fsp_name, &sbuf) != 0)
+ {
+ return 0;
+ }
+ } else {
+ if(fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
+ return 0;
+ }
+ }
+
+ /*
+ * Get the owner, group and world SIDs.
+ */
+
+ if (!create_file_sids(&sbuf, &owner_sid, &group_sid))
+ {
+ DEBUG(3,("create_file_sids: uid or gid not mapped to SIDS\n"));
+ return 0;
+ }
+
+ /*
+ * Create the generic 3 element UNIX acl.
+ */
+
+ owner_access = map_unix_perms(&owner_acl_type, sbuf.st_mode,
+ S_IRUSR, S_IWUSR, S_IXUSR, fsp->is_directory);
+ group_access = map_unix_perms(&grp_acl_type, sbuf.st_mode,
+ S_IRGRP, S_IWGRP, S_IXGRP, fsp->is_directory);
+ other_access = map_unix_perms(&other_acl_type, sbuf.st_mode,
+ S_IROTH, S_IWOTH, S_IXOTH, fsp->is_directory);
+
+ if(owner_access.mask)
+ {
+ ace_list = g_renew(SEC_ACE, ace_list, num_acls+1);
+ if (ace_list == NULL)
+ {
+ return 0;
+ }
+ make_sec_ace(&ace_list[num_acls++], &owner_sid, owner_acl_type,
+ owner_access, 0);
+ }
+
+ if(group_access.mask)
+ {
+ ace_list = g_renew(SEC_ACE, ace_list, num_acls+1);
+ if (ace_list == NULL)
+ {
+ return 0;
+ }
+
+ make_sec_ace(&ace_list[num_acls++], &group_sid, grp_acl_type,
+ group_access, 0);
+ }
+
+ if(other_access.mask)
+ {
+ ace_list = g_renew(SEC_ACE, ace_list, num_acls+1);
+ if (ace_list == NULL)
+ {
+ return 0;
+ }
+
+ make_sec_ace(&ace_list[num_acls++], global_sid_everyone, other_acl_type,
+ other_access, 0);
+ }
+
+ if(fsp->is_directory) {
+ /*
+ * For directory ACLs we also add in the inherited permissions
+ * ACE entries. These are the permissions a file would get when
+ * being created in the directory.
+ */
+ mode_t mode = unix_mode( fsp->conn, FILE_ATTRIBUTE_ARCHIVE, fsp->fsp_name);
+
+ owner_access = map_unix_perms(&owner_acl_type, mode,
+ S_IRUSR, S_IWUSR, S_IXUSR, fsp->is_directory);
+ group_access = map_unix_perms(&grp_acl_type, mode,
+ S_IRGRP, S_IWGRP, S_IXGRP, fsp->is_directory);
+ other_access = map_unix_perms(&other_acl_type, mode,
+ S_IROTH, S_IWOTH, S_IXOTH, fsp->is_directory);
+
+ if(owner_access.mask)
+ {
+ ace_list = g_renew(SEC_ACE, ace_list, num_acls+1);
+ if (ace_list == NULL)
+ {
+ return 0;
+ }
+
+ make_sec_ace(&ace_list[num_acls++], &owner_sid, owner_acl_type,
+ owner_access, SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
+ }
+
+ if(group_access.mask)
+ {
+ ace_list = g_renew(SEC_ACE, ace_list, num_acls+1);
+ if (ace_list == NULL)
+ {
+ return 0;
+ }
+
+ make_sec_ace(&ace_list[num_acls++], &group_sid, grp_acl_type,
+ group_access, SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
+ }
+
+ if(other_access.mask)
+ {
+ ace_list = g_renew(SEC_ACE, ace_list, num_acls+1);
+ if (ace_list == NULL)
+ {
+ return 0;
+ }
+
+ make_sec_ace(&ace_list[num_acls++], global_sid_everyone, other_acl_type,
+ other_access, SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
+ }
+ }
+
+ if(num_acls)
+ {
+ psa = g_new(SEC_ACL, 1);
+ if (psa == NULL)
+ {
+ safe_free(ace_list);
+ }
+ if (!make_sec_acl( psa, 3, num_acls, ace_list))
+ {
+ DEBUG(0,("get_nt_acl: Unable to malloc space for acl.\n"));
+ safe_free(ace_list);
+ safe_free(psa);
+ return 0;
+ }
+ }
+ }
+
+ (*ppdesc) = g_new(SEC_DESC, 1);
+
+ if((*ppdesc) == NULL)
+ {
+ DEBUG(0,("get_nt_acl: Unable to malloc space for security descriptor.\n"));
+ sec_desc_size = 0;
+ free_sec_acl(psa);
+ safe_free(psa);
+ return 0;
+ }
+
+ sec_desc_size = make_sec_desc( (*ppdesc), 1,
+ SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT,
+ sid_dup(&owner_sid),
+ sid_dup(&group_sid),
+ NULL, psa);
+
+ return sec_desc_size;
+}
+
/****************************************************************************
Reply to query a security descriptor - currently this is not implemented (it
- is planned to be though).
+ is planned to be though). Right now it just returns the same thing NT would
+ when queried on a FAT filesystem. JRA.
****************************************************************************/
+
static int call_nt_transact_query_security_desc(connection_struct *conn,
- char *inbuf, char *outbuf,
- int length,
- int bufsize,
+ char *inbuf, char *outbuf,
+ int length, int bufsize,
char **ppsetup, char **ppparams, char **ppdata)
{
- static BOOL logged_message = False;
+ uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
+ char *params = *ppparams;
+ char *data = *ppdata;
+ prs_struct pd;
+ SEC_DESC *psd = NULL;
+ size_t sec_desc_size;
- if(!logged_message) {
- DEBUG(0,("call_nt_transact_query_security_desc: Currently not implemented.\n"));
- logged_message = True; /* Only print this once... */
+ files_struct *fsp = file_fsp(params,0);
+
+ if(!fsp)
+ return(ERROR(ERRDOS,ERRbadfid));
+
+ DEBUG(3,("call_nt_transact_query_security_desc: file = %s\n", fsp->fsp_name ));
+
+ params = *ppparams = Realloc(*ppparams, 4);
+ if(params == NULL)
+ return(ERROR(ERRDOS,ERRnomem));
+
+ /*
+ * Get the permissions to return.
+ */
+
+ if((sec_desc_size = get_nt_acl(fsp, &psd)) == 0)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+
+ DEBUG(3,("call_nt_transact_query_security_desc: sec_desc_size = %d.\n",(int)sec_desc_size));
+
+ SIVAL(params,0,(uint32)sec_desc_size);
+
+ if(max_data_count < sec_desc_size) {
+
+ free_sec_desc(psd);
+ safe_free(psd);
+
+ send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_BUFFER_TOO_SMALL,
+ params, 4, *ppdata, 0);
+ return -1;
}
- return(ERROR(ERRSRV,ERRnosupport));
+ /*
+ * Allocate the data we will point this at.
+ */
+
+ data = *ppdata = Realloc(*ppdata, sec_desc_size);
+ if(data == NULL) {
+ free_sec_desc(psd);
+ safe_free(psd);
+ return(ERROR(ERRDOS,ERRnomem));
+ }
+
+ memset(data, '\0', sec_desc_size);
+
+ /*
+ * Init the parse struct we will marshall into.
+ */
+
+ prs_init(&pd, sec_desc_size, 4, MARSHALL);
+
+ /*
+ * Finally, linearize into the outgoing buffer.
+ */
+
+ if(!sec_io_desc( "sd data", psd, &pd, 1))
+ {
+ free_sec_desc(psd);
+ safe_free(psd);
+ prs_mem_free(&pd);
+ DEBUG(0,("call_nt_transact_query_security_desc: Error in marshalling \
+security descriptor.\n"));
+ /*
+ * Return access denied for want of a better error message..
+ */
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ /*
+ * copy the data out of the marshalled structure
+ */
+
+ prs_link(NULL, &pd, NULL);
+ prs_buf_copy(data, &pd, 0, sec_desc_size);
+
+ /*
+ * Now we can delete the security descriptor.
+ */
+
+ prs_mem_free(&pd);
+ free_sec_desc(psd);
+ safe_free(psd);
+
+ send_nt_replies(inbuf, outbuf, bufsize, 0, params, 4, data, (int)sec_desc_size);
+ return -1;
+}
+
+/****************************************************************************
+ Map NT perms to UNIX.
+****************************************************************************/
+
+#define FILE_SPECIFIC_READ_BITS (FILE_READ_DATA|FILE_READ_EA|FILE_READ_ATTRIBUTES)
+#define FILE_SPECIFIC_WRITE_BITS (FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_WRITE_EA|FILE_WRITE_ATTRIBUTES)
+#define FILE_SPECIFIC_EXECUTE_BITS (FILE_EXECUTE)
+
+static mode_t map_nt_perms( SEC_ACCESS sec_access, int type)
+{
+ mode_t mode = 0;
+
+ switch(type) {
+ case S_IRUSR:
+ if(sec_access.mask & GENERIC_ALL_ACCESS)
+ mode = S_IRUSR|S_IWUSR|S_IXUSR;
+ else {
+ mode |= (sec_access.mask & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IRUSR : 0;
+ mode |= (sec_access.mask & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWUSR : 0;
+ mode |= (sec_access.mask & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXUSR : 0;
+ }
+ break;
+ case S_IRGRP:
+ if(sec_access.mask & GENERIC_ALL_ACCESS)
+ mode = S_IRGRP|S_IWGRP|S_IXGRP;
+ else {
+ mode |= (sec_access.mask & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IRGRP : 0;
+ mode |= (sec_access.mask & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWGRP : 0;
+ mode |= (sec_access.mask & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXGRP : 0;
+ }
+ break;
+ case S_IROTH:
+ if(sec_access.mask & GENERIC_ALL_ACCESS)
+ mode = S_IROTH|S_IWOTH|S_IXOTH;
+ else {
+ mode |= (sec_access.mask & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IROTH : 0;
+ mode |= (sec_access.mask & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWOTH : 0;
+ mode |= (sec_access.mask & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXOTH : 0;
+ }
+ break;
+ }
+
+ return mode;
}
+
+/****************************************************************************
+ Unpack a SEC_DESC into a owner, group and set of UNIX permissions.
+****************************************************************************/
+
+static BOOL unpack_nt_permissions(SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *pgrp, mode_t *pmode,
+ uint32 security_info_sent, SEC_DESC *psd, BOOL is_directory)
+{
+ DOM_SID file_owner_sid;
+ DOM_SID file_grp_sid;
+ SEC_ACL *dacl = psd->dacl;
+ BOOL all_aces_are_inherit_only = (is_directory ? True : False);
+ int i;
+ POSIX_ID id;
+
+ *pmode = 0;
+ *puser = (uid_t)-1;
+ *pgrp = (gid_t)-1;
+
+ if(security_info_sent == 0) {
+ DEBUG(0,("unpack_nt_permissions: no security info sent !\n"));
+ return False;
+ }
+
+ /*
+ * Windows 2000 sends the owner and group SIDs as the logged in
+ * user, not the connected user. But it still sends the file
+ * owner SIDs on an ACL set. So we need to check for the file
+ * owner and group SIDs as well as the owner SIDs. JRA.
+ */
+
+ if (!create_file_sids(psbuf, &file_owner_sid, &file_grp_sid))
+ {
+ DEBUG(3,("create_file_sids: uid or gid not mapped to SIDS\n"));
+ return 0;
+ }
+
+ /*
+ * Don't immediately fail if the owner sid cannot be validated.
+ * This may be a group chown only set.
+ */
+
+ DEBUG(0,("TODO: LsaLookupSids to find type of owner_sid\n"));
+
+ if (security_info_sent & OWNER_SECURITY_INFORMATION &&
+ surs_sam_sid_to_unixid( psd->owner_sid, &id, False) &&
+ id.type == SURS_POSIX_UID_AS_USR)
+ {
+ *puser = (uid_t)id.id;
+ }
+
+ /*
+ * Don't immediately fail if the group sid cannot be validated.
+ * This may be an owner chown only set.
+ */
+
+ /*
+ * assume support for RID_TYPE_ALIAS and RID_TYPE_GROUP only.
+ * also assume that calls to sur_sam_sid_to_unixid are exclusive
+ * and one will fail where the other succeeds
+ */
+ if (security_info_sent & GROUP_SECURITY_INFORMATION &&
+ surs_sam_sid_to_unixid( psd->grp_sid, &id, False) &&
+ (id.type == SURS_POSIX_GID_AS_GRP || id.type == SURS_POSIX_GID_AS_ALS))
+ {
+ *pgrp = (gid_t)id.id;
+ }
+
+ /*
+ * If no DACL then this is a chown only security descriptor.
+ */
+
+ if(!(security_info_sent & DACL_SECURITY_INFORMATION) || !dacl) {
+ *pmode = 0;
+ return True;
+ }
+
+ /*
+ * Now go through the DACL and ensure that
+ * any owner/group sids match.
+ */
+
+ for(i = 0; i < dacl->num_aces; i++) {
+ DOM_SID ace_sid;
+ SEC_ACE *psa = &dacl->ace[i];
+
+ if((psa->type != SEC_ACE_TYPE_ACCESS_ALLOWED) &&
+ (psa->type != SEC_ACE_TYPE_ACCESS_DENIED)) {
+ DEBUG(3,("unpack_nt_permissions: unable to set anything but an ALLOW or DENY ACE.\n"));
+ return False;
+ }
+
+ /*
+ * Ignore or remove bits we don't care about on a directory ACE.
+ */
+
+ if(is_directory) {
+ if(psa->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
+ DEBUG(3,("unpack_nt_permissions: ignoring inherit only ACE.\n"));
+ continue;
+ }
+
+ /*
+ * At least one of the ACE entries wasn't inherit only.
+ * Flag this so we know the returned mode is valid.
+ */
+
+ all_aces_are_inherit_only = False;
+ }
+
+ /*
+ * Windows 2000 sets these flags even on *file* ACE's. This is wrong
+ * but we can ignore them for now. Revisit this when we go to POSIX
+ * ACLs on directories.
+ */
+
+ psa->flags &= ~(SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT);
+
+ if(psa->flags != 0) {
+ DEBUG(1,("unpack_nt_permissions: unable to set ACE flags (%x).\n",
+ (unsigned int)psa->flags));
+ return False;
+ }
+
+ /*
+ * The security mask may be UNIX_ACCESS_NONE which should map into
+ * no permissions (we overload the WRITE_OWNER bit for this) or it
+ * should be one of the ALL/EXECUTE/READ/WRITE bits. Arrange for this
+ * to be so. Any other bits override the UNIX_ACCESS_NONE bit.
+ */
+
+ psa->info.mask &= (GENERIC_ALL_ACCESS|GENERIC_EXECUTE_ACCESS|GENERIC_WRITE_ACCESS|
+ GENERIC_READ_ACCESS|UNIX_ACCESS_NONE|FILE_ALL_ATTRIBUTES);
+
+ if(psa->info.mask != UNIX_ACCESS_NONE)
+ psa->info.mask &= ~UNIX_ACCESS_NONE;
+
+ sid_copy(&ace_sid, &psa->sid);
+
+ if(sid_equal(&ace_sid, &file_owner_sid)) {
+ /*
+ * Map the desired permissions into owner perms.
+ */
+
+ if(psa->type == SEC_ACE_TYPE_ACCESS_ALLOWED)
+ *pmode |= map_nt_perms( psa->info, S_IRUSR);
+ else
+ *pmode &= ~(map_nt_perms( psa->info, S_IRUSR));
+
+ } else if( sid_equal(&ace_sid, &file_grp_sid)) {
+ /*
+ * Map the desired permissions into group perms.
+ */
+
+ if(psa->type == SEC_ACE_TYPE_ACCESS_ALLOWED)
+ *pmode |= map_nt_perms( psa->info, S_IRGRP);
+ else
+ *pmode &= ~(map_nt_perms( psa->info, S_IRGRP));
+
+ } else if( sid_equal(&ace_sid, global_sid_everyone)) {
+ /*
+ * Map the desired permissions into other perms.
+ */
+
+ if(psa->type == SEC_ACE_TYPE_ACCESS_ALLOWED)
+ *pmode |= map_nt_perms( psa->info, S_IROTH);
+ else
+ *pmode &= ~(map_nt_perms( psa->info, S_IROTH));
+
+ } else {
+ DEBUG(0,("unpack_nt_permissions: unknown SID used in ACL.\n"));
+ return False;
+ }
+ }
+
+ if (is_directory && all_aces_are_inherit_only) {
+ /*
+ * Windows 2000 is doing one of these weird 'inherit acl'
+ * traverses to conserve NTFS ACL resources. Just pretend
+ * there was no DACL sent. JRA.
+ */
+
+ DEBUG(10,("unpack_nt_permissions: Win2k inherit acl traverse. Ignoring DACL.\n"));
+ free_sec_acl(psd->dacl);
+ safe_free(psd->dacl);
+ psd->dacl = NULL;
+ }
+
+ return True;
+}
+
/****************************************************************************
- Reply to set a security descriptor - currently this is not implemented (it
- is planned to be though).
+ Reply to set a security descriptor. Map to UNIX perms.
****************************************************************************/
+
static int call_nt_transact_set_security_desc(connection_struct *conn,
- char *inbuf, char *outbuf,
- int length,
- int bufsize,
- char **ppsetup,
- char **ppparams, char **ppdata)
+ char *inbuf, char *outbuf, int length,
+ int bufsize, char **ppsetup,
+ char **ppparams, char **ppdata)
{
- static BOOL logged_message = False;
+ uint32 total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
+ char *params= *ppparams;
+ char *data = *ppdata;
+ prs_struct pd;
+ SEC_DESC psd;
+ uint32 total_data_count = (uint32)IVAL(inbuf, smb_nts_TotalDataCount);
+ uid_t user = (uid_t)-1;
+ gid_t grp = (gid_t)-1;
+ mode_t perms = 0;
+ SMB_STRUCT_STAT sbuf;
+ files_struct *fsp = NULL;
+ uint32 security_info_sent = 0;
+ BOOL got_dacl = False;
- if(!logged_message) {
- DEBUG(0,("call_nt_transact_set_security_desc: Currently not implemented.\n"));
- logged_message = True; /* Only print this once... */
+ if(!lp_nt_acl_support())
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+
+ if(total_parameter_count < 8)
+ return(ERROR(ERRDOS,ERRbadfunc));
+
+ if((fsp = file_fsp(params,0)) == NULL)
+ return(ERROR(ERRDOS,ERRbadfid));
+
+ security_info_sent = IVAL(params,4);
+
+ DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", fsp->fsp_name,
+ (unsigned int)security_info_sent ));
+
+ /*
+ * Init the parse struct we will unmarshall from.
+ */
+
+ prs_init(&pd, 0, 4, UNMARSHALL);
+
+ /*
+ * Setup the prs_struct with a copy of the memory we just
+ * allocated. unmarshall from the beginning.
+ */
+
+ prs_append_data(&pd, data, total_data_count);
+
+ /*
+ * Finally, unmarshall from the data buffer.
+ */
+
+ if(!sec_io_desc( "sd data", &psd, &pd, 1))
+ {
+ free_sec_desc(&psd);
+ prs_mem_free(&pd);
+ DEBUG(0,("call_nt_transact_set_security_desc: Error in unmarshalling \
+security descriptor.\n"));
+ /*
+ * Return access denied for want of a better error message..
+ */
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- return(ERROR(ERRSRV,ERRnosupport));
+
+ /*
+ * finished with the marshalling structure, already
+ */
+
+ prs_mem_free(&pd);
+
+ /*
+ * Get the current state of the file.
+ */
+
+ if(fsp->is_directory) {
+ if(dos_stat(fsp->fsp_name, &sbuf) != 0) {
+ free_sec_desc(&psd);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+ } else {
+
+ int ret;
+
+ if(fsp->fd_ptr == NULL)
+ ret = conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name,False), &sbuf);
+ else
+ ret = conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf);
+
+ if(ret != 0) {
+ free_sec_desc(&psd);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+ }
+
+ /*
+ * Unpack the user/group/world id's and permissions.
+ */
+
+ if(!unpack_nt_permissions( &sbuf, &user, &grp, &perms, security_info_sent, &psd, fsp->is_directory)) {
+ free_sec_desc(&psd);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ if (psd.dacl != NULL)
+ got_dacl = True;
+
+ free_sec_desc(&psd);
+
+ /*
+ * Do we need to chown ?
+ */
+
+ if((user != (uid_t)-1 || grp != (uid_t)-1) && (sbuf.st_uid != user || sbuf.st_gid != grp)) {
+
+ DEBUG(3,("call_nt_transact_set_security_desc: chown %s. uid = %u, gid = %u.\n",
+ fsp->fsp_name, (unsigned int)user, (unsigned int)grp ));
+
+ if(dos_chown( fsp->fsp_name, user, grp) == -1) {
+ DEBUG(3,("call_nt_transact_set_security_desc: chown %s, %u, %u failed. Error = %s.\n",
+ fsp->fsp_name, (unsigned int)user, (unsigned int)grp, strerror(errno) ));
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ /*
+ * Recheck the current state of the file, which may have changed.
+ * (suid/sgid bits, for instance)
+ */
+
+ if(fsp->is_directory) {
+ if(dos_stat(fsp->fsp_name, &sbuf) != 0) {
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+ } else {
+
+ int ret;
+
+ if(fsp->fd_ptr == NULL)
+ ret = conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name,False), &sbuf);
+ else
+ ret = conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf);
+
+ if(ret != 0)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+ }
+
+ /*
+ * Only change security if we got a DACL.
+ */
+
+ if((security_info_sent & DACL_SECURITY_INFORMATION) && got_dacl) {
+
+ /*
+ * Check to see if we need to change anything.
+ * Enforce limits on modified bits *only*. Don't enforce masks
+ * on bits not changed by the user.
+ */
+
+ if(fsp->is_directory) {
+
+ perms &= (lp_dir_security_mask(SNUM(conn)) | sbuf.st_mode);
+ perms |= (lp_force_dir_security_mode(SNUM(conn)) & ( perms ^ sbuf.st_mode ));
+
+ } else {
+
+ perms &= (lp_security_mask(SNUM(conn)) | sbuf.st_mode);
+ perms |= (lp_force_security_mode(SNUM(conn)) & ( perms ^ sbuf.st_mode ));
+
+ }
+
+ /*
+ * Preserve special bits.
+ */
+
+ perms |= (sbuf.st_mode & ~0777);
+
+ /*
+ * Do we need to chmod ?
+ */
+
+ if(sbuf.st_mode != perms) {
+
+ DEBUG(3,("call_nt_transact_set_security_desc: chmod %s. perms = 0%o.\n",
+ fsp->fsp_name, (unsigned int)perms ));
+
+ if(conn->vfs_ops.chmod(dos_to_unix(fsp->fsp_name, False), perms) == -1) {
+ DEBUG(3,("call_nt_transact_set_security_desc: chmod %s, 0%o failed. Error = %s.\n",
+ fsp->fsp_name, (unsigned int)perms, strerror(errno) ));
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+ }
+ }
+
+ send_nt_replies(inbuf, outbuf, bufsize, 0, NULL, 0, NULL, 0);
+ return -1;
}
/****************************************************************************
length, bufsize,
&setup, ¶ms, &data);
break;
-
default:
/* Error in request */
DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n", function_code));
extern pstring sesssetup_user;
extern uint16 global_oplock_port;
-
+extern BOOL global_client_failed_oplock_break;
/****************************************************************************
fd support routines - attempt to do a dos_open
char tmp = p[max_len];
p[max_len] = '\0';
- if ((fd = conn->vfs_ops.open(dos_to_unix(fname,False),flags,mode))
- == -1)
+ if ((fd = conn->vfs_ops.open(dos_to_unix(fname,False),flags,mode)) == -1)
p[max_len] = tmp;
}
}
Cache a uid_t currently with this file open. This is an optimization only
used when multiple sessionsetup's have been done to one smbd.
****************************************************************************/
+
void fd_add_to_uid_cache(file_fd_struct *fd_ptr, uid_t u)
{
if(fd_ptr->uid_cache_count >= sizeof(fd_ptr->uid_users_cache)/sizeof(uid_t))
Remove a uid_t that currently has this file open. This is an optimization only
used when multiple sessionsetup's have been done to one smbd.
****************************************************************************/
+
static void fd_remove_from_uid_cache(file_fd_struct *fd_ptr, uid_t u)
{
int i;
Check if a uid_t that currently has this file open is present. This is an
optimization only used when multiple sessionsetup's have been done to one smbd.
****************************************************************************/
+
static BOOL fd_is_in_uid_cache(file_fd_struct *fd_ptr, uid_t u)
{
int i;
return False;
}
-
/****************************************************************************
fd support routines - attempt to re-open an already open fd as O_RDWR.
Save the already open fd (we cannot close due to POSIX file locking braindamage.
****************************************************************************/
-static void fd_attempt_reopen(char *fname, mode_t mode, file_fd_struct *fd_ptr)
+
+static void fd_attempt_reopen(char *fname, mode_t mode, files_struct *fsp)
{
- int fd = dos_open( fname, O_RDWR, mode);
+ int fd = fsp->conn->vfs_ops.open(dos_to_unix(fname, False), O_RDWR, mode);
+ file_fd_struct *fd_ptr = fsp->fd_ptr;
if(fd == -1)
return;
fd support routines - attempt to close the file referenced by this fd.
Decrements the ref_count and returns it.
****************************************************************************/
-uint16 fd_attempt_close(files_struct *fsp)
+uint16 fd_attempt_close(files_struct *fsp, int *err_ret)
{
extern struct current_user current_user;
- file_fd_struct *fd_ptr = fsp->fd_ptr;
+ file_fd_struct *fd_ptr;
uint16 ret_ref;
- if (fd_ptr != NULL) {
- ret_ref = fd_ptr->ref_count;
- } else {
+ *err_ret = 0;
+
+ if ((fsp == NULL) || (fsp->fd_ptr == NULL)) {
return 0;
}
+ fd_ptr = fsp->fd_ptr;
+ ret_ref = fd_ptr->ref_count;
+
DEBUG(3,("fd_attempt_close fd = %d, dev = %x, inode = %.0f, open_flags = %d, ref_count = %d.\n",
fd_ptr->fd, (unsigned int)fd_ptr->dev, (double)fd_ptr->inode,
fd_ptr->real_open_flags,
ret_ref = fd_ptr->ref_count;
if(fd_ptr->ref_count == 0) {
- if(fd_ptr->fd != -1)
- fsp->conn->vfs_ops.close(fd_ptr->fd);
- if(fd_ptr->fd_readonly != -1)
- fsp->conn->vfs_ops.close(fd_ptr->fd_readonly);
- if(fd_ptr->fd_writeonly != -1)
- fsp->conn->vfs_ops.close(fd_ptr->fd_writeonly);
+
+ if(fd_ptr->fd != -1) {
+ if(fsp->conn->vfs_ops.close(fd_ptr->fd) < 0)
+ *err_ret = errno;
+ }
+
+ if(fd_ptr->fd_readonly != -1) {
+ if(fsp->conn->vfs_ops.close(fd_ptr->fd_readonly) < 0) {
+ if(*err_ret == 0)
+ *err_ret = errno;
+ }
+ }
+
+ if(fd_ptr->fd_writeonly != -1) {
+ if(fsp->conn->vfs_ops.close(fd_ptr->fd_writeonly) < 0) {
+ if(*err_ret == 0)
+ *err_ret = errno;
+ }
+ }
+
/*
* Delete this fd_ptr.
*/
fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
}
- return ret_ref;
+ return ret_ref;
}
/****************************************************************************
{
pid_t child_pid;
+ /*
+ * We need to temporarily stop CatchChild from eating
+ * SIGCLD signals as it also eats the exit status code. JRA.
+ */
+
+ CatchChildLeaveStatus();
+
if((child_pid = fork()) < 0) {
DEBUG(0,("check_access_allowed_for_current_user: fork failed.\n"));
+ CatchChild();
return False;
}
*/
pid_t wpid;
int status_code;
- if ((wpid = sys_waitpid(child_pid, &status_code, 0)) < 0) {
- DEBUG(0,("check_access_allowed_for_current_user: The process is no longer waiting!\n"));
+
+ while ((wpid = sys_waitpid(child_pid, &status_code, 0)) < 0) {
+ if(errno == EINTR) {
+ errno = 0;
+ continue;
+ }
+ DEBUG(0,("check_access_allowed_for_current_user: The process \
+is no longer waiting ! Error = %s\n", strerror(errno) ));
+ CatchChild();
return(False);
}
+ /*
+ * Go back to ignoring children.
+ */
+ CatchChild();
+
if (child_pid != wpid) {
DEBUG(0,("check_access_allowed_for_current_user: We were waiting for the wrong process ID\n"));
return(False);
/* Access denied. */
_exit(EACCES);
}
- close(fd);
+ conn->vfs_ops.close(fd);
DEBUG(9,("check_access_allowed_for_current_user: Child - returning ok.\n"));
_exit(0);
}
/****************************************************************************
check a filename for the pipe string
****************************************************************************/
+
static void check_for_pipe(char *fname)
{
/* special case of pipe opens */
char s[10];
- StrnCpy(s,fname,9);
+ StrnCpy(s,fname,sizeof(s)-1);
strlower(s);
if (strstr(s,"pipe/")) {
DEBUG(3,("Rejecting named pipe open for %s\n",fname));
/****************************************************************************
open a file
****************************************************************************/
+
static void open_file(files_struct *fsp,connection_struct *conn,
char *fname1,int flags,mode_t mode, SMB_STRUCT_STAT *sbuf)
{
fsp->open = False;
fsp->fd_ptr = 0;
- fsp->granted_oplock = False;
+ fsp->oplock_type = NO_OPLOCK;
errno = EPERM;
pstrcpy(fname,fname1);
* JRA.
*/
- if (conn->read_only && !conn->printer) {
+ if (!CAN_WRITE(conn) && !conn->printer) {
/* It's a read-only share - fail if we wanted to write. */
if(accmode != O_RDONLY) {
DEBUG(3,("Permission denied opening %s\n",fname));
* between the last open and now.
*/
if(fd_ptr->real_open_flags != O_RDWR)
- fd_attempt_reopen(fname, mode, fd_ptr);
+ fd_attempt_reopen(fname, mode, fsp);
/*
* Ensure that if we wanted write access
pstrcpy(dname,fname);
p = strrchr(dname,'/');
if (p) *p = 0;
- if (conn->vfs_ops.disk_free(dos_to_unix(dname,False),&dum1,&dum2,&dum3) <
+ if (conn->vfs_ops.disk_free(dos_to_unix(dname,False),False,&dum1,&dum2,&dum3) <
(SMB_BIG_UINT)lp_minprintspace(SNUM(conn))) {
- if(fd_attempt_close(fsp) == 0)
- conn->vfs_ops.unlink(dos_to_unix(fname,False));
+ int err;
+ if(fd_attempt_close(fsp, &err) == 0)
+ conn->vfs_ops.unlink(dos_to_unix(fname, False));
fsp->fd_ptr = 0;
errno = ENOSPC;
return;
if (fd_ptr->fd < 0)
{
+ int err;
DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
fname,strerror(errno),flags));
/* Ensure the ref_count is decremented. */
- fd_attempt_close(fsp);
+ fd_attempt_close(fsp,&err);
check_for_pipe(fname);
return;
}
if(sbuf == 0) {
/* Do the fstat */
if(conn->vfs_ops.fstat(fd_ptr->fd, &statbuf) == -1) {
+ int err;
/* Error - backout !! */
DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
fd_ptr->fd, fname,strerror(errno)));
/* Ensure the ref_count is decremented. */
- fd_attempt_close(fsp);
+ fd_attempt_close(fsp,&err);
return;
}
sbuf = &statbuf;
fsp->size = 0;
fsp->pos = -1;
fsp->open = True;
- fsp->mmap_ptr = NULL;
- fsp->mmap_size = 0;
fsp->can_lock = True;
fsp->can_read = ((flags & O_WRONLY)==0);
fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
fsp->share_mode = 0;
fsp->print_file = conn->printer;
fsp->modified = False;
- fsp->granted_oplock = False;
- fsp->sent_oplock_break = False;
+ fsp->oplock_type = NO_OPLOCK;
+ fsp->sent_oplock_break = NO_BREAK_SENT;
fsp->is_directory = False;
+ fsp->stat_open = False;
+ fsp->directory_delete_on_close = False;
fsp->conn = conn;
/*
* Note that the file name here is the *untranslated* name
*/
string_set(&fsp->fsp_name,fname);
fsp->wbmpx_ptr = NULL;
+ fsp->wcp = NULL; /* Write cache pointer. */
/*
* If the printer is marked as postscript output a leading
}
}
-/****************************************************************************
- If it's a read-only file, and we were compiled with mmap enabled,
- try and mmap the file. This is split out from open_file() above
- as mmap'ing the file can cause the kernel reference count to
- be incremented, which can cause kernel oplocks to be refused.
- Splitting this call off allows the kernel oplock to be granted, then
- the file mmap'ed.
-****************************************************************************/
-
-static void mmap_open_file(files_struct *fsp)
-{
-#if WITH_MMAP
- /* mmap it if read-only */
- if (!fsp->can_write) {
- fsp->mmap_size = dos_file_size(fsp->fsp_name);
- if (fsp->mmap_size < MAX_MMAP_SIZE) {
- fsp->mmap_ptr = (char *)sys_mmap(NULL,fsp->mmap_size,
- PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,(SMB_OFF_T)0);
-
- if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr) {
- DEBUG(3,("Failed to mmap() %s - %s\n",
- fsp->fsp_name,strerror(errno)));
- fsp->mmap_ptr = NULL;
- }
- }
- }
-#endif
-}
-
/****************************************************************************
C. Hoch 11/22/95
Helper for open_file_shared.
Truncate a file after checking locking; close file if locked.
**************************************************************************/
-static void truncate_unless_locked(files_struct *fsp, connection_struct *conn,
+
+static void truncate_unless_locked(files_struct *fsp, connection_struct *conn, int token,
BOOL *share_locked)
{
if (fsp->can_write){
SMB_OFF_T mask2 = ((SMB_OFF_T)0x3) << (SMB_OFF_T_BITS-4);
SMB_OFF_T mask = (mask2<<2);
- if (is_locked(fsp,conn,~mask,0,F_WRLCK)){
+ if (is_locked(fsp,conn,~mask,0,WRITE_LOCK)){
/* If share modes are in force for this connection we
have the share entry locked. Unlock it before closing. */
if (*share_locked && lp_share_modes(SNUM(conn)))
}
+/*******************************************************************
+return True if the filename is one of the special executable types
+********************************************************************/
+static BOOL is_executable(char *fname)
+{
+ if ((fname = strrchr(fname,'.'))) {
+ if (strequal(fname,".com") ||
+ strequal(fname,".dll") ||
+ strequal(fname,".exe") ||
+ strequal(fname,".sym")) {
+ return True;
+ }
+ }
+ return False;
+}
+
enum {AFAIL,AREAD,AWRITE,AALL};
/*******************************************************************
reproduce the share mode access table
+this is horrendoously complex, and really can't be justified on any
+rational grounds except that this is _exactly_ what NT does. See
+the DENY1 and DENY2 tests in smbtorture for a comprehensive set of
+test routines.
********************************************************************/
static int access_table(int new_deny,int old_deny,int old_mode,
- int share_pid,char *fname)
+ BOOL same_pid, BOOL isexe)
{
- if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
-
- if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
- int pid = getpid();
- if (old_deny == new_deny && share_pid == pid)
- return(AALL);
-
- if (old_mode == 0) return(AREAD);
-
- /* the new smbpub.zip spec says that if the file extension is
- .com, .dll, .exe or .sym then allow the open. I will force
- it to read-only as this seems sensible although the spec is
- a little unclear on this. */
- if ((fname = strrchr(fname,'.'))) {
- if (strequal(fname,".com") ||
- strequal(fname,".dll") ||
- strequal(fname,".exe") ||
- strequal(fname,".sym"))
- return(AREAD);
- }
+ if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
- return(AFAIL);
- }
+ if (same_pid) {
+ if (isexe && old_mode == DOS_OPEN_RDONLY &&
+ old_deny == DENY_DOS && new_deny == DENY_READ) {
+ return AFAIL;
+ }
+ if (!isexe && old_mode == DOS_OPEN_RDONLY &&
+ old_deny == DENY_DOS && new_deny == DENY_DOS) {
+ return AREAD;
+ }
+ if (new_deny == DENY_FCB && old_deny == DENY_DOS) {
+ if (isexe) return AFAIL;
+ if (old_mode == DOS_OPEN_RDONLY) return AFAIL;
+ return AALL;
+ }
+ if (old_mode == DOS_OPEN_RDONLY && old_deny == DENY_DOS) {
+ if (new_deny == DENY_FCB || new_deny == DENY_READ) {
+ if (isexe) return AREAD;
+ return AFAIL;
+ }
+ }
+ if (old_deny == DENY_FCB) {
+ if (new_deny == DENY_DOS || new_deny == DENY_FCB) return AALL;
+ return AFAIL;
+ }
+ }
- switch (new_deny)
- {
- case DENY_WRITE:
- if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
- if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
- if (old_deny==DENY_NONE && old_mode==0) return(AALL);
- return(AFAIL);
- case DENY_READ:
- if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
- if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
- if (old_deny==DENY_NONE && old_mode==1) return(AALL);
- return(AFAIL);
- case DENY_NONE:
- if (old_deny==DENY_WRITE) return(AREAD);
- if (old_deny==DENY_READ) return(AWRITE);
- if (old_deny==DENY_NONE) return(AALL);
- return(AFAIL);
- }
- return(AFAIL);
+ if (old_deny == DENY_DOS || new_deny == DENY_DOS ||
+ old_deny == DENY_FCB || new_deny == DENY_FCB) {
+ if (isexe) {
+ if (old_deny == DENY_FCB || new_deny == DENY_FCB) {
+ return AFAIL;
+ }
+ if (old_deny == DENY_DOS) {
+ if (new_deny == DENY_READ &&
+ (old_mode == DOS_OPEN_RDONLY ||
+ old_mode == DOS_OPEN_RDWR)) {
+ return AFAIL;
+ }
+ if (new_deny == DENY_WRITE &&
+ (old_mode == DOS_OPEN_WRONLY ||
+ old_mode == DOS_OPEN_RDWR)) {
+ return AFAIL;
+ }
+ return AALL;
+ }
+ if (old_deny == DENY_NONE) return AALL;
+ if (old_deny == DENY_READ) return AWRITE;
+ if (old_deny == DENY_WRITE) return AREAD;
+ }
+ /* it isn't a exe, dll, sym or com file */
+ if (old_deny == new_deny && same_pid)
+ return(AALL);
+
+ if (old_deny == DENY_READ || new_deny == DENY_READ) return AFAIL;
+ if (old_mode == DOS_OPEN_RDONLY) return(AREAD);
+
+ return(AFAIL);
+ }
+
+ switch (new_deny)
+ {
+ case DENY_WRITE:
+ if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_RDONLY) return(AREAD);
+ if (old_deny==DENY_READ && old_mode==DOS_OPEN_RDONLY) return(AWRITE);
+ if (old_deny==DENY_NONE && old_mode==DOS_OPEN_RDONLY) return(AALL);
+ return(AFAIL);
+ case DENY_READ:
+ if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_WRONLY) return(AREAD);
+ if (old_deny==DENY_READ && old_mode==DOS_OPEN_WRONLY) return(AWRITE);
+ if (old_deny==DENY_NONE && old_mode==DOS_OPEN_WRONLY) return(AALL);
+ return(AFAIL);
+ case DENY_NONE:
+ if (old_deny==DENY_WRITE) return(AREAD);
+ if (old_deny==DENY_READ) return(AWRITE);
+ if (old_deny==DENY_NONE) return(AALL);
+ return(AFAIL);
+ }
+ return(AFAIL);
}
/****************************************************************************
check if we can open a file with a share mode
****************************************************************************/
+
static int check_share_mode( share_mode_entry *share, int deny_mode,
char *fname,
BOOL fcbopen, int *flags)
return False;
}
- if (old_deny_mode > 4 || old_open_mode > 2)
- {
- DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
- deny_mode,old_deny_mode,old_open_mode,fname));
-
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadshare;
-
- return False;
- }
-
{
int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
- share->pid,fname);
+ (share->pid == getpid()),is_executable(fname));
if ((access_allowed == AFAIL) ||
(!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
- (access_allowed == AREAD && *flags == O_WRONLY) ||
- (access_allowed == AWRITE && *flags == O_RDONLY))
+ (access_allowed == AREAD && *flags != O_RDONLY) ||
+ (access_allowed == AWRITE && *flags != O_WRONLY))
{
DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
deny_mode,old_deny_mode,old_open_mode,
- share->pid,fname, fcbopen, *flags, access_allowed));
+ (int)share->pid,fname, fcbopen, *flags, access_allowed));
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadshare;
return True;
}
-
/****************************************************************************
open a file with a share mode
****************************************************************************/
-void open_file_shared(files_struct *fsp, connection_struct *conn,
- char *fname, int share_mode, int ofun,
- mode_t mode, int oplock_request, int *Access,
- int *action)
+
+void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int share_mode,int ofun,
+ mode_t mode,int oplock_request, int *Access,int *action)
{
int flags=0;
int flags2=0;
int deny_mode = GET_DENY_MODE(share_mode);
BOOL allow_share_delete = GET_ALLOW_SHARE_DELETE(share_mode);
SMB_STRUCT_STAT sbuf;
- BOOL file_existed = vfs_file_exist(conn, dos_to_unix(fname,False), &sbuf);
+ BOOL file_existed = vfs_file_exist(conn, fname, &sbuf);
BOOL share_locked = False;
BOOL fcbopen = False;
+ int token = 0;
SMB_DEV_T dev = 0;
SMB_INO_T inode = 0;
int num_share_modes = 0;
-
+ int oplock_contention_count = 0;
+ BOOL all_current_opens_are_level_II = False;
fsp->open = False;
fsp->fd_ptr = 0;
DEBUG(10,("open_file_shared: fname = %s, share_mode = %x, ofun = %x, mode = %o, oplock request = %d\n",
fname, share_mode, ofun, (int)mode, oplock_request ));
+
+ /* ignore any oplock requests if oplocks are disabled */
+ if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break) {
+ oplock_request = 0;
+ }
+
/* this is for OS/2 EAs - try and say we don't support them */
if (strstr(fname,".+,;=[]."))
{
return;
}
- if (deny_mode == DENY_FCB)
- deny_mode = DENY_DOS;
-
if (lp_share_modes(SNUM(conn)))
{
int i;
{
broke_oplock = False;
+ all_current_opens_are_level_II = True;
+
for(i = 0; i < num_share_modes; i++)
{
share_mode_entry *share_entry = &old_shares[i];
* Check if someone has an oplock on this file. If so we must break
* it before continuing.
*/
- if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
+ if((oplock_request && EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) ||
+ (!oplock_request && (share_entry->op_type != NO_OPLOCK)))
{
DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
}
lock_share_entry(conn, dev, inode);
broke_oplock = True;
+ all_current_opens_are_level_II = False;
break;
+ } else if (!LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
+ all_current_opens_are_level_II = False;
}
/* someone else has a share lock on it, check to see
{
free((char *)old_shares);
num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
+ oplock_contention_count++;
}
} while(broke_oplock);
}
free((char *)old_shares);
}
+ /*
+ * Refuse to grant an oplock in case the contention limit is
+ * reached when going through the lock list multiple times.
+ */
+
+ if(oplock_contention_count >= lp_oplock_contention_limit(SNUM(conn)))
+ {
+ oplock_request = 0;
+ DEBUG(4,("open_file_shared: oplock contention = %d. Not granting oplock.\n",
+ oplock_contention_count ));
+ }
+
DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
flags,flags2,(int)mode));
{
uint16 port = 0;
- /* JRA. Currently this only services Exlcusive and batch
- oplocks (no other opens on this file). This needs to
- be extended to level II oplocks (multiple reader
- oplocks). */
+ /*
+ * Setup the oplock info in both the shared memory and
+ * file structs.
+ */
- if((oplock_request) && (num_share_modes == 0) && lp_oplocks(SNUM(conn)) &&
- !IS_VETO_OPLOCK_PATH(conn,fname) && set_file_oplock(fsp) )
- {
+ if(oplock_request && (num_share_modes == 0) &&
+ !IS_VETO_OPLOCK_PATH(conn,fname) && set_file_oplock(fsp, oplock_request) ) {
port = global_oplock_port;
- }
- else
- {
+ } else if (oplock_request && all_current_opens_are_level_II) {
+ port = global_oplock_port;
+ oplock_request = LEVEL_II_OPLOCK;
+ set_file_oplock(fsp, oplock_request);
+ } else {
port = 0;
oplock_request = 0;
}
}
if ((flags2&O_TRUNC) && file_existed)
- truncate_unless_locked(fsp,conn,&share_locked);
-
- /*
- * Attempt to mmap a read only file.
- * Moved until after a kernel oplock may
- * be granted due to reference count issues. JRA.
- */
- mmap_open_file(fsp);
+ truncate_unless_locked(fsp,conn,token,&share_locked);
}
if (share_locked && lp_share_modes(SNUM(conn)))
unlock_share_entry( conn, dev, inode);
}
+/****************************************************************************
+ Open a file for permissions read only. Return a pseudo file entry
+ with the 'stat_open' flag set and a fd_ptr of NULL.
+****************************************************************************/
+
+int open_file_stat(files_struct *fsp,connection_struct *conn,
+ char *fname, int smb_ofun, SMB_STRUCT_STAT *pst, int *action)
+{
+ extern struct current_user current_user;
+
+ if(conn->vfs_ops.stat(dos_to_unix(fname, False), pst) < 0) {
+ DEBUG(0,("open_file_stat: unable to stat name = %s. Error was %s\n",
+ fname, strerror(errno) ));
+ return -1;
+ }
+
+ if(S_ISDIR(pst->st_mode)) {
+ DEBUG(0,("open_file_stat: %s is a directory !\n", fname ));
+ return -1;
+ }
+
+ *action = FILE_WAS_OPENED;
+
+ DEBUG(5,("open_file_stat: opening file %s as a stat entry\n", fname));
+
+ /*
+ * Setup the files_struct for it.
+ */
+
+ fsp->fd_ptr = NULL;
+ conn->num_files_open++;
+ fsp->mode = 0;
+ GetTimeOfDay(&fsp->open_time);
+ fsp->vuid = current_user.key.vuid;
+ fsp->size = 0;
+ fsp->pos = -1;
+ fsp->open = True;
+ fsp->can_lock = False;
+ fsp->can_read = False;
+ fsp->can_write = False;
+ fsp->share_mode = 0;
+ fsp->print_file = False;
+ fsp->modified = False;
+ fsp->oplock_type = NO_OPLOCK;
+ fsp->sent_oplock_break = NO_BREAK_SENT;
+ fsp->is_directory = False;
+ fsp->stat_open = True;
+ fsp->directory_delete_on_close = False;
+ fsp->conn = conn;
+ /*
+ * Note that the file name here is the *untranslated* name
+ * ie. it is still in the DOS codepage sent from the client.
+ * All use of this filename will pass though the sys_xxxx
+ * functions which will do the dos_to_unix translation before
+ * mapping into a UNIX filename. JRA.
+ */
+ string_set(&fsp->fsp_name,fname);
+ fsp->wbmpx_ptr = NULL;
+ fsp->wcp = NULL; /* Write cache pointer. */
+
+ return 0;
+}
+
/****************************************************************************
Open a directory from an NT SMB call.
****************************************************************************/
{
extern struct current_user current_user;
SMB_STRUCT_STAT st;
+ BOOL got_stat = False;
- if (smb_ofun & 0x10) {
- /*
- * Create the directory.
- */
+ if(conn->vfs_ops.stat(dos_to_unix(fname, False), &st) == 0) {
+ got_stat = True;
+ }
- if(conn->vfs_ops.mkdir(dos_to_unix(fname,False),
- unix_mode(conn,aDIR)) < 0) {
- DEBUG(0,("open_directory: unable to create %s. Error was %s\n",
- fname, strerror(errno) ));
- return -1;
- }
+ if (got_stat && (GET_FILE_OPEN_DISPOSITION(smb_ofun) == FILE_EXISTS_FAIL)) {
+ errno = EEXIST; /* Setup so correct error is returned to client. */
+ return -1;
+ }
+
+ if (GET_FILE_CREATE_DISPOSITION(smb_ofun) == FILE_CREATE_IF_NOT_EXIST) {
+
+ if (got_stat) {
+
+ if(!S_ISDIR(st.st_mode)) {
+ DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
+ errno = EACCES;
+ return -1;
+ }
+ *action = FILE_WAS_OPENED;
+
+ } else {
- *action = FILE_WAS_CREATED;
+ /*
+ * Try and create the directory.
+ */
+
+ if(!CAN_WRITE(conn)) {
+ DEBUG(2,("open_directory: failing create on read-only share\n"));
+ errno = EACCES;
+ return -1;
+ }
+
+ if(conn->vfs_ops.mkdir(dos_to_unix(fname, False),
+ unix_mode(conn,aDIR, fname)) < 0) {
+ DEBUG(0,("open_directory: unable to create %s. Error was %s\n",
+ fname, strerror(errno) ));
+ return -1;
+ }
+ *action = FILE_WAS_CREATED;
+
+ }
} else {
+
/*
- * Check that it *was* a directory.
+ * Don't create - just check that it *was* a directory.
*/
- if(conn->vfs_ops.stat(dos_to_unix(fname,False), &st) < 0) {
+ if(!got_stat) {
DEBUG(0,("open_directory: unable to stat name = %s. Error was %s\n",
fname, strerror(errno) ));
return -1;
DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
return -1;
}
+
*action = FILE_WAS_OPENED;
}
fsp->size = 0;
fsp->pos = -1;
fsp->open = True;
- fsp->mmap_ptr = NULL;
- fsp->mmap_size = 0;
fsp->can_lock = True;
fsp->can_read = False;
fsp->can_write = False;
fsp->share_mode = 0;
fsp->print_file = False;
fsp->modified = False;
- fsp->granted_oplock = False;
- fsp->sent_oplock_break = False;
+ fsp->oplock_type = NO_OPLOCK;
+ fsp->sent_oplock_break = NO_BREAK_SENT;
fsp->is_directory = True;
+ fsp->directory_delete_on_close = False;
fsp->conn = conn;
/*
* Note that the file name here is the *untranslated* name
return 0;
}
-
/*******************************************************************
-check if the share mode on a file allows it to be deleted or unlinked
-return True if sharing doesn't prevent the operation
+ Check if the share mode on a file allows it to be deleted or unlinked.
+ Return True if sharing doesn't prevent the operation.
********************************************************************/
BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op)
share_mode_entry *old_shares = 0;
int num_share_modes;
SMB_STRUCT_STAT sbuf;
- int pid = getpid();
+ pid_t pid = getpid();
SMB_DEV_T dev;
SMB_INO_T inode;
* Check if someone has an oplock on this file. If so we must
* break it before continuing.
*/
- if(share_entry->op_type & BATCH_OPLOCK)
+ if(BATCH_OPLOCK_TYPE(share_entry->op_type))
{
+#if 0
+
+/* JRA. Try removing this code to see if the new oplock changes
+ fix the problem. I'm dubious, but Andrew is recommending we
+ try this....
+*/
+
/*
* It appears that the NT redirector may have a bug, in that
* it tries to do an SMBmv on a file that it has open with a
continue;
}
else
+#endif /* 0 */
{
DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
* if we can too.
*/
- if ((GET_DENY_MODE(share_entry->share_mode) != DENY_DOS) || (share_entry->pid != pid))
+ if ((GET_DENY_MODE(share_entry->share_mode) != DENY_DOS) ||
+ (share_entry->pid != pid))
goto free_and_exit;
} /* end for */
/* Oplock ipc UDP socket. */
static int oplock_sock = -1;
uint16 global_oplock_port = 0;
-#if defined(HAVE_KERNEL_OPLOCKS)
static int oplock_pipe_read = -1;
+
+#if defined(HAVE_KERNEL_OPLOCKS)
static int oplock_pipe_write = -1;
-#endif /* HAVE_KERNEL_OPLOCKS */
+#endif
/* Current number of oplocks we have outstanding. */
-int32 global_oplocks_open = 0;
+static int32 exclusive_oplocks_open = 0;
+static int32 level_II_oplocks_open = 0;
+BOOL global_client_failed_oplock_break = False;
BOOL global_oplock_break = False;
extern int smb_read_error;
-static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval);
+static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, BOOL local);
+
+/****************************************************************************
+ Get the number of current exclusive oplocks.
+****************************************************************************/
+
+int32 get_number_of_exclusive_open_oplocks(void)
+{
+ return exclusive_oplocks_open;
+}
/****************************************************************************
Setup the kernel level oplock backchannel for this process.
}
/****************************************************************************
- open the oplock IPC socket communication
+ Open the oplock IPC socket communication.
****************************************************************************/
+
BOOL open_oplock_ipc(void)
{
struct sockaddr_in sock_name;
int selrtn;
int maxfd = oplock_sock;
-#if defined(HAVE_KERNEL_OPLOCKS)
- if(lp_kernel_oplocks())
+ if(lp_kernel_oplocks() && (oplock_pipe_read != -1))
maxfd = MAX(maxfd, oplock_pipe_read);
-#endif /* HAVE_KERNEL_OPLOCKS */
to.tv_sec = timeout / 1000;
to.tv_usec = (timeout % 1000) * 1000;
- selrtn = sys_select(maxfd+1,fds,NULL, &to);
+ selrtn = sys_select(maxfd+1,fds,NULL,&to);
/* Check if error */
if(selrtn == -1) {
}
dev = (SMB_DEV_T)os.os_dev;
- inode = (SMB_DEV_T)os.os_ino;
+ inode = (SMB_INO_T)os.os_ino;
DEBUG(5,("receive_local_message: kernel oplock break request received for \
dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode ));
buffer += OPBRK_CMD_HEADER_LEN;
SSVAL(buffer,OPBRK_MESSAGE_CMD_OFFSET,KERNEL_OPLOCK_BREAK_CMD);
- SIVAL(buffer,KERNEL_OPLOCK_BREAK_DEV_OFFSET,dev);
-#ifdef LARGE_SMB_INO_T
- SIVAL(buffer,KERNEL_OPLOCK_BREAK_INODE_OFFSET,inode & 0xFFFFFFFF);
- SIVAL(buffer,KERNEL_OPLOCK_BREAK_INODE_OFFSET+4, (inode >> 32 ) & 0xFFFFFFFF );
-#else /* LARGE_SMB_INO_T */
- SIVAL(buffer,KERNEL_OPLOCK_BREAK_INODE_OFFSET,inode);
-#endif /* LARGE_SMB_INO_T */
+ memcpy(buffer + KERNEL_OPLOCK_BREAK_DEV_OFFSET, (char *)&dev, sizeof(dev));
+ memcpy(buffer + KERNEL_OPLOCK_BREAK_INODE_OFFSET, (char *)&inode, sizeof(inode));
return True;
}
}
/****************************************************************************
- Attempt to set an oplock on a file. Always succeeds if kernel oplocks are
- disabled (just sets flags). Returns True if oplock set.
+ Attempt to set an kernel oplock on a file. Always returns True if kernel
+ oplocks not available.
****************************************************************************/
-BOOL set_file_oplock(files_struct *fsp)
+static BOOL set_kernel_oplock(files_struct *fsp, int oplock_type)
{
#if defined(HAVE_KERNEL_OPLOCKS)
if(lp_kernel_oplocks()) {
}
#endif /* HAVE_KERNEL_OPLOCKS */
+ return True;
+}
- DEBUG(5,("set_file_oplock: granted oplock on file %s, dev = %x, inode = %.0f\n",
- fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev, (double)fsp->fd_ptr->inode));
+/****************************************************************************
+ Attempt to set an oplock on a file. Always succeeds if kernel oplocks are
+ disabled (just sets flags). Returns True if oplock set.
+****************************************************************************/
- fsp->granted_oplock = True;
- fsp->sent_oplock_break = False;
- global_oplocks_open++;
+BOOL set_file_oplock(files_struct *fsp, int oplock_type)
+{
+ if (!set_kernel_oplock(fsp, oplock_type))
+ return False;
+
+ fsp->oplock_type = oplock_type;
+ fsp->sent_oplock_break = NO_BREAK_SENT;
+ if ( oplock_type == LEVEL_II_OPLOCK)
+ level_II_oplocks_open++;
+ else
+ exclusive_oplocks_open++;
+
+ DEBUG(5,("set_file_oplock: granted oplock on file %s, dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
+ fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev, (double)fsp->fd_ptr->inode,
+ (int)fsp->open_time.tv_sec, (int)fsp->open_time.tv_usec ));
return True;
}
/****************************************************************************
- Attempt to release an oplock on a file. Always succeeds if kernel oplocks are
- disabled (just clears flags).
+ Release a kernel oplock on a file.
****************************************************************************/
-static void release_file_oplock(files_struct *fsp)
+static void release_kernel_oplock(files_struct *fsp)
{
#if defined(HAVE_KERNEL_OPLOCKS)
* oplock state of this file.
*/
int state = fcntl(fsp->fd_ptr->fd, F_OPLKACK, -1);
- dbgtext("release_file_oplock: file %s, dev = %x, inode = %.0f has kernel \
+ dbgtext("release_kernel_oplock: file %s, dev = %x, inode = %.0f has kernel \
oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev,
(double)fsp->fd_ptr->inode, state );
}
/*
- * Remote the kernel oplock on this file.
+ * Remove the kernel oplock on this file.
*/
if(fcntl(fsp->fd_ptr->fd, F_OPLKACK, OP_REVOKE) < 0)
{
if( DEBUGLVL( 0 ))
{
- dbgtext("release_file_oplock: Error when removing kernel oplock on file " );
+ dbgtext("release_kernel_oplock: Error when removing kernel oplock on file " );
dbgtext("%s, dev = %x, inode = %.0f. Error was %s\n",
fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev,
(double)fsp->fd_ptr->inode, strerror(errno) );
}
}
#endif /* HAVE_KERNEL_OPLOCKS */
+}
+
+
+/****************************************************************************
+ Attempt to release an oplock on a file. Decrements oplock count.
+****************************************************************************/
+
+void release_file_oplock(files_struct *fsp)
+{
+ release_kernel_oplock(fsp);
+
+ if (fsp->oplock_type == LEVEL_II_OPLOCK)
+ level_II_oplocks_open--;
+ else
+ exclusive_oplocks_open--;
+
+ fsp->oplock_type = NO_OPLOCK;
+ fsp->sent_oplock_break = NO_BREAK_SENT;
+
+ flush_write_cache(fsp, OPLOCK_RELEASE_FLUSH);
+}
+
+/****************************************************************************
+ Attempt to downgrade an oplock on a file. Doesn't decrement oplock count.
+****************************************************************************/
+
+static void downgrade_file_oplock(files_struct *fsp)
+{
+ release_kernel_oplock(fsp);
+ fsp->oplock_type = LEVEL_II_OPLOCK;
+ exclusive_oplocks_open--;
+ level_II_oplocks_open++;
+ fsp->sent_oplock_break = NO_BREAK_SENT;
+}
+
+/****************************************************************************
+ Remove a file oplock. Copes with level II and exclusive.
+ Locks then unlocks the share mode lock.
+****************************************************************************/
+
+BOOL remove_oplock(files_struct *fsp)
+{
+ SMB_DEV_T dev = fsp->fd_ptr->dev;
+ SMB_INO_T inode = fsp->fd_ptr->inode;
+ BOOL ret = True;
+
+ /* Remove the oplock flag from the sharemode. */
+ if (lock_share_entry(fsp->conn, dev, inode) == False) {
+ DEBUG(0,("remove_oplock: failed to lock share entry for file %s\n",
+ fsp->fsp_name ));
+ ret = False;
+ }
+
+ if (fsp->sent_oplock_break == EXCLUSIVE_BREAK_SENT) {
+
+ /*
+ * Deal with a reply when a break-to-none was sent.
+ */
+
+ if(remove_share_oplock(fsp)==False) {
+ DEBUG(0,("remove_oplock: failed to remove share oplock for file %s fnum %d, \
+dev = %x, inode = %.0f\n", fsp->fsp_name, fsp->fnum, (unsigned int)dev, (double)inode));
+ ret = False;
+ }
+
+ release_file_oplock(fsp);
+
+ } else {
+
+ /*
+ * Deal with a reply when a break-to-level II was sent.
+ */
+
+ if(downgrade_share_oplock(fsp)==False) {
+ DEBUG(0,("remove_oplock: failed to downgrade share oplock for file %s fnum %d, \
+dev = %x, inode = %.0f\n", fsp->fsp_name, fsp->fnum, (unsigned int)dev, (double)inode));
+ ret = False;
+ }
- fsp->granted_oplock = False;
- fsp->sent_oplock_break = False;
- global_oplocks_open--;
+ downgrade_file_oplock(fsp);
+ }
+
+ unlock_share_entry(fsp->conn, dev, inode);
+ return ret;
}
/****************************************************************************
int setup_oplock_select_set( fd_set *fds)
{
int maxfd = oplock_sock;
+
+ if(oplock_sock == -1)
+ return 0;
+
FD_SET(oplock_sock,fds);
-#if defined(HAVE_KERNEL_OPLOCKS)
- if(lp_kernel_oplocks()) {
+ if(lp_kernel_oplocks() && (oplock_pipe_read != -1)) {
FD_SET(oplock_pipe_read,fds);
maxfd = MAX(maxfd,oplock_pipe_read);
}
-#endif /* HAVE_KERNEL_OPLOCKS */
return maxfd;
}
char *msg_start;
SMB_DEV_T dev;
SMB_INO_T inode;
- uint32 remotepid;
+ pid_t remotepid;
struct timeval tval;
struct timeval *ptval = NULL;
+ uint16 break_cmd_type;
msg_len = IVAL(buffer,OPBRK_CMD_LEN_OFFSET);
from_port = SVAL(buffer,OPBRK_CMD_PORT_OFFSET);
* Pull the info out of the requesting packet.
*/
- switch(SVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET))
+ break_cmd_type = SVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET);
+
+ switch(break_cmd_type)
{
#if defined(HAVE_KERNEL_OPLOCKS)
case KERNEL_OPLOCK_BREAK_CMD:
return False;
}
{
- /*
- * Warning - beware of SMB_INO_T <> 4 bytes. !!
- */
-#ifdef LARGE_SMB_INO_T
- SMB_INO_T inode_low = IVAL(msg_start, KERNEL_OPLOCK_BREAK_INODE_OFFSET);
- SMB_INO_T inode_high = IVAL(msg_start, KERNEL_OPLOCK_BREAK_INODE_OFFSET + 4);
- inode = inode_low | (inode_high << 32);
-#else /* LARGE_SMB_INO_T */
- inode = IVAL(msg_start, KERNEL_OPLOCK_BREAK_INODE_OFFSET);
-#endif /* LARGE_SMB_INO_T */
-
- dev = IVAL(msg_start,KERNEL_OPLOCK_BREAK_DEV_OFFSET);
+ memcpy((char *)&inode, msg_start+KERNEL_OPLOCK_BREAK_INODE_OFFSET, sizeof(inode));
+ memcpy((char *)&dev, msg_start+KERNEL_OPLOCK_BREAK_DEV_OFFSET, sizeof(dev));
ptval = NULL;
#endif /* HAVE_KERNEL_OPLOCKS */
case OPLOCK_BREAK_CMD:
+ case LEVEL_II_OPLOCK_BREAK_CMD:
+
/* Ensure that the msg length is correct. */
if(msg_len != OPLOCK_BREAK_MSG_LEN)
{
- DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
-should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
+ DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, should be %d).\n",
+ (int)msg_len, (int)OPLOCK_BREAK_MSG_LEN));
return False;
}
{
- /*
- * Warning - beware of SMB_INO_T <> 4 bytes. !!
- */
-#ifdef LARGE_SMB_INO_T
- SMB_INO_T inode_low = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
- SMB_INO_T inode_high = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET + 4);
- inode = inode_low | (inode_high << 32);
-#else /* LARGE_SMB_INO_T */
- inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
-#endif /* LARGE_SMB_INO_T */
+ long usec;
+ time_t sec;
- dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
-
- tval.tv_sec = (time_t)IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
- tval.tv_usec = (long)IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
+ memcpy((char *)&inode, msg_start+OPLOCK_BREAK_INODE_OFFSET,sizeof(inode));
+ memcpy((char *)&dev, msg_start+OPLOCK_BREAK_DEV_OFFSET,sizeof(dev));
+ memcpy((char *)&sec, msg_start+OPLOCK_BREAK_SEC_OFFSET,sizeof(sec));
+ tval.tv_sec = sec;
+ memcpy((char *)&usec, msg_start+OPLOCK_BREAK_USEC_OFFSET, sizeof(usec));
+ tval.tv_usec = usec;
ptval = &tval;
- remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
+ memcpy((char *)&remotepid, msg_start+OPLOCK_BREAK_PID_OFFSET,sizeof(remotepid));
- DEBUG(5,("process_local_message: oplock break request from \
-pid %d, port %d, dev = %x, inode = %.0f\n", remotepid, from_port, (unsigned int)dev, (double)inode));
+ DEBUG(5,("process_local_message: (%s) oplock break request from \
+pid %d, port %d, dev = %x, inode = %.0f\n",
+ (break_cmd_type == OPLOCK_BREAK_CMD) ? "exclusive" : "level II",
+ (int)remotepid, from_port, (unsigned int)dev, (double)inode));
}
break;
if(msg_len != OPLOCK_BREAK_MSG_LEN)
{
DEBUG(0,("process_local_message: ubr: incorrect length for reply \
-(was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
+(was %d, should be %d).\n", (int)msg_len, (int)OPLOCK_BREAK_MSG_LEN));
return False;
}
{
- /*
- * Warning - beware of SMB_INO_T <> 4 bytes. !!
- */
-#ifdef LARGE_SMB_INO_T
- SMB_INO_T inode_low = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
- SMB_INO_T inode_high = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET + 4);
- inode = inode_low | (inode_high << 32);
-#else /* LARGE_SMB_INO_T */
- inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
-#endif /* LARGE_SMB_INO_T */
-
- remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
- dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
+ memcpy((char *)&inode, msg_start+OPLOCK_BREAK_INODE_OFFSET,sizeof(inode));
+ memcpy((char *)&remotepid, msg_start+OPLOCK_BREAK_PID_OFFSET,sizeof(remotepid));
+ memcpy((char *)&dev, msg_start+OPLOCK_BREAK_DEV_OFFSET,sizeof(dev));
DEBUG(0,("process_local_message: unsolicited oplock break reply from \
-pid %d, port %d, dev = %x, inode = %.0f\n", remotepid, from_port, (unsigned int)dev, (double)inode));
+pid %d, port %d, dev = %x, inode = %.0f\n", (int)remotepid, from_port, (unsigned int)dev, (double)inode));
}
return False;
* Now actually process the break request.
*/
- if(global_oplocks_open != 0)
+ if((exclusive_oplocks_open + level_II_oplocks_open) != 0)
{
- if(oplock_break(dev, inode, ptval) == False)
+ if (oplock_break(dev, inode, ptval, False) == False)
{
DEBUG(0,("process_local_message: oplock break failed.\n"));
return False;
}
/*
- * Do the appropriate reply - none in the kernel case.
+ * Do the appropriate reply - none in the kernel or level II case.
*/
if(SVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET) == OPLOCK_BREAK_CMD)
/* Send the message back after OR'ing in the 'REPLY' bit. */
SSVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
- ZERO_STRUCT(toaddr);
+ memset((char *)&toaddr,'\0',sizeof(toaddr));
toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
toaddr.sin_port = htons(from_port);
toaddr.sin_family = AF_INET;
(struct sockaddr *)&toaddr, sizeof(toaddr)) < 0)
{
DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
- remotepid, strerror(errno)));
+ (int)remotepid, strerror(errno)));
return False;
}
DEBUG(5,("process_local_message: oplock break reply sent to \
pid %d, port %d, for file dev = %x, inode = %.0f\n",
- remotepid, from_port, (unsigned int)dev, (double)inode));
+ (int)remotepid, from_port, (unsigned int)dev, (double)inode));
}
return True;
}
/****************************************************************************
- Process an oplock break directly.
+ Set up an oplock break message.
****************************************************************************/
-static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval)
+static void prepare_break_message(char *outbuf, files_struct *fsp, BOOL level2)
+{
+ memset(outbuf,'\0',smb_size);
+ set_message(outbuf,8,0,True);
+
+ SCVAL(outbuf,smb_com,SMBlockingX);
+ SSVAL(outbuf,smb_tid,fsp->conn->cnum);
+ SSVAL(outbuf,smb_pid,0xFFFF);
+ SSVAL(outbuf,smb_uid,0);
+ SSVAL(outbuf,smb_mid,0xFFFF);
+ SCVAL(outbuf,smb_vwv0,0xFF);
+ SSVAL(outbuf,smb_vwv2,fsp->fnum);
+ SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
+ SCVAL(outbuf,smb_vwv3+1,level2 ? OPLOCKLEVEL_II : OPLOCKLEVEL_NONE);
+}
+
+/****************************************************************************
+ Function to do the waiting before sending a local break.
+****************************************************************************/
+
+static void wait_before_sending_break(BOOL local_request)
+{
+ extern struct timeval smb_last_time;
+
+ if(local_request) {
+ struct timeval cur_tv;
+ long wait_left = (long)lp_oplock_break_wait_time();
+
+ GetTimeOfDay(&cur_tv);
+
+ wait_left -= ((cur_tv.tv_sec - smb_last_time.tv_sec)*1000) +
+ ((cur_tv.tv_usec - smb_last_time.tv_usec)/1000);
+
+ if(wait_left > 0) {
+ wait_left = MIN(wait_left, 1000);
+ sys_usleep(wait_left * 1000);
+ }
+ }
+}
+
+/****************************************************************************
+ Ensure that we have a valid oplock.
+****************************************************************************/
+
+static files_struct *initial_break_processing(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval)
{
- extern struct current_user current_user;
- extern int Client;
- char *inbuf = NULL;
- char *outbuf = NULL;
files_struct *fsp = NULL;
- time_t start_time;
- BOOL shutdown_server = False;
- connection_struct *saved_conn;
- int saved_vuid;
- pstring saved_dir;
- int break_counter = OPLOCK_BREAK_RESENDS;
if( DEBUGLVL( 3 ) )
{
- dbgtext( "oplock_break: called for dev = %x, inode = %.0f.\n", (unsigned int)dev, (double)inode );
- dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
+ dbgtext( "initial_break_processing: called for dev = %x, inode = %.0f tv_sec = %x, tv_usec = %x.\n",
+ (unsigned int)dev, (double)inode, tval ? (int)tval->tv_sec : 0,
+ tval ? (int)tval->tv_usec : 0);
+ dbgtext( "Current oplocks_open (exclusive = %d, levelII = %d)\n",
+ exclusive_oplocks_open, level_II_oplocks_open );
}
/* We need to search the file open table for the
if(fsp == NULL)
{
/* The file could have been closed in the meantime - return success. */
- if( DEBUGLVL( 0 ) )
+ if( DEBUGLVL( 3 ) )
{
- dbgtext( "oplock_break: cannot find open file with " );
+ dbgtext( "initial_break_processing: cannot find open file with " );
dbgtext( "dev = %x, inode = %.0f ", (unsigned int)dev, (double)inode);
dbgtext( "allowing break to succeed.\n" );
}
- return True;
+ return NULL;
}
/* Ensure we have an oplock on the file */
as we may have just freed it.
*/
- if(!fsp->granted_oplock)
+ if(fsp->oplock_type == NO_OPLOCK)
{
- if( DEBUGLVL( 0 ) )
+ if( DEBUGLVL( 3 ) )
{
- dbgtext( "oplock_break: file %s ", fsp->fsp_name );
+ dbgtext( "initial_break_processing: file %s ", fsp->fsp_name );
dbgtext( "(dev = %x, inode = %.0f) has no oplock.\n", (unsigned int)dev, (double)inode );
dbgtext( "Allowing break to succeed regardless.\n" );
}
- return True;
+ return NULL;
}
- /* mark the oplock break as sent - we don't want to send twice! */
+ return fsp;
+}
+
+/****************************************************************************
+ Process a level II oplock break directly.
+****************************************************************************/
+
+BOOL oplock_break_level2(files_struct *fsp, BOOL local_request, int token)
+{
+ extern int Client;
+ extern uint32 global_client_caps;
+ char outbuf[128];
+ BOOL got_lock = False;
+ SMB_DEV_T dev = fsp->fd_ptr->dev;
+ SMB_INO_T inode = fsp->fd_ptr->inode;
+
+ /*
+ * We can have a level II oplock even if the client is not
+ * level II oplock aware. In this case just remove the
+ * flags and don't send the break-to-none message to
+ * the client.
+ */
+
+ if (global_client_caps & CAP_LEVEL_II_OPLOCKS) {
+ /*
+ * If we are sending an oplock break due to an SMB sent
+ * by our own client we ensure that we wait at leat
+ * lp_oplock_break_wait_time() milliseconds before sending
+ * the packet. Sending the packet sooner can break Win9x
+ * and has reported to cause problems on NT. JRA.
+ */
+
+ wait_before_sending_break(local_request);
+
+ /* Prepare the SMBlockingX message. */
+
+ prepare_break_message( outbuf, fsp, False);
+ send_smb(Client, outbuf);
+ }
+
+ /*
+ * Now we must update the shared memory structure to tell
+ * everyone else we no longer have a level II oplock on
+ * this open file. If local_request is true then token is
+ * the existing lock on the shared memory area.
+ */
+
+ if(!local_request && lock_share_entry(fsp->conn, dev, inode) == False) {
+ DEBUG(0,("oplock_break_level2: unable to lock share entry for file %s\n", fsp->fsp_name ));
+ } else {
+ got_lock = True;
+ }
+
+ if(remove_share_oplock(fsp)==False) {
+ DEBUG(0,("oplock_break_level2: unable to remove level II oplock for file %s\n", fsp->fsp_name ));
+ }
+
+ if (!local_request && got_lock)
+ unlock_share_entry(fsp->conn, dev, inode);
+
+ fsp->oplock_type = NO_OPLOCK;
+ level_II_oplocks_open--;
+
+ if(level_II_oplocks_open < 0)
+ {
+ DEBUG(0,("oplock_break_level2: level_II_oplocks_open < 0 (%d). PANIC ERROR\n",
+ level_II_oplocks_open));
+ abort();
+ }
+
+ if( DEBUGLVL( 3 ) )
+ {
+ dbgtext( "oplock_break_level2: returning success for " );
+ dbgtext( "dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
+ dbgtext( "Current level II oplocks_open = %d\n", level_II_oplocks_open );
+ }
+
+ return True;
+}
+
+/****************************************************************************
+ Process an oplock break directly.
+****************************************************************************/
+
+static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, BOOL local_request)
+{
+ extern uint32 global_client_caps;
+ extern struct current_user current_user;
+ extern int Client;
+ char *inbuf = NULL;
+ char *outbuf = NULL;
+ files_struct *fsp = NULL;
+ time_t start_time;
+ BOOL shutdown_server = False;
+ BOOL oplock_timeout = False;
+ connection_struct *saved_conn;
+ int saved_vuid;
+ pstring saved_dir;
+ int timeout = (OPLOCK_BREAK_TIMEOUT * 1000);
+ pstring file_name;
+ BOOL using_levelII;
+
+ if((fsp = initial_break_processing(dev, inode, tval)) == NULL)
+ return True;
+
+ /*
+ * Deal with a level II oplock going break to none separately.
+ */
+
+ if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
+ return oplock_break_level2(fsp, local_request, -1);
+
+ /* Mark the oplock break as sent - we don't want to send twice! */
if (fsp->sent_oplock_break)
{
if( DEBUGLVL( 0 ) )
return False;
}
+ if(global_oplock_break) {
+ DEBUG(0,("ABORT : ABORT : recursion in oplock_break !!!!!\n"));
+ abort();
+ }
+
/* Now comes the horrid part. We must send an oplock break to the client,
and then process incoming messages until we get a close or oplock release.
At this point we know we need a new inbuf/outbuf buffer pair.
return False;
}
+ /*
+ * If we are sending an oplock break due to an SMB sent
+ * by our own client we ensure that we wait at leat
+ * lp_oplock_break_wait_time() milliseconds before sending
+ * the packet. Sending the packet sooner can break Win9x
+ * and has reported to cause problems on NT. JRA.
+ */
+
+ wait_before_sending_break(local_request);
+
/* Prepare the SMBlockingX message. */
- memset(outbuf, 0, smb_size);
- set_message(outbuf,8,0,True);
- SCVAL(outbuf,smb_com,SMBlockingX);
- SSVAL(outbuf,smb_tid,fsp->conn->cnum);
- SSVAL(outbuf,smb_pid,0xFFFF);
- SSVAL(outbuf,smb_uid,0);
- SSVAL(outbuf,smb_mid,0xFFFF);
- SCVAL(outbuf,smb_vwv0,0xFF);
- SSVAL(outbuf,smb_vwv2,fsp->fnum);
- SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
- /* Change this when we have level II oplocks. */
- SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
-
- send_smb(Client, outbuf);
+ if ((global_client_caps & CAP_LEVEL_II_OPLOCKS) && !lp_kernel_oplocks() && lp_level2_oplocks(SNUM(fsp->conn))) {
+ using_levelII = True;
+ } else {
+ using_levelII = False;
+ }
+
+ prepare_break_message( outbuf, fsp, using_levelII);
+ /* Remember if we just sent a break to level II on this file. */
+ fsp->sent_oplock_break = using_levelII?
+ LEVEL_II_BREAK_SENT:EXCLUSIVE_BREAK_SENT;
- /* Remember we just sent an oplock break on this file. */
- fsp->sent_oplock_break = True;
+ send_smb(Client, outbuf);
/* We need this in case a readraw crosses on the wire. */
global_oplock_break = True;
/* Save the chain fnum. */
file_chain_save();
- while(OPEN_FSP(fsp) && fsp->granted_oplock)
- {
- if(receive_smb(Client,inbuf,
- (OPLOCK_BREAK_TIMEOUT/OPLOCK_BREAK_RESENDS) * 1000) == False)
- {
+ /*
+ * From Charles Hoch <hoch@exemplary.com>. If the break processing
+ * code closes the file (as it often does), then the fsp pointer here
+ * points to free()'d memory. We *must* revalidate fsp each time
+ * around the loop.
+ */
- /* Isaac suggestd that if a MS client doesn't respond to a
- oplock break request then we might try resending
- it. Certainly it's no worse than just dropping the
- socket! */
- if (smb_read_error == READ_TIMEOUT && break_counter--) {
- DEBUG(2, ( "oplock_break resend\n" ) );
- send_smb(Client, outbuf);
- continue;
- }
+ pstrcpy(file_name, fsp->fsp_name);
+ while((fsp = initial_break_processing(dev, inode, tval)) &&
+ OPEN_FSP(fsp) && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+ {
+ if(receive_smb(Client,inbuf, timeout) == False)
+ {
/*
* Die if we got an error.
*/
- if (smb_read_error == READ_EOF)
+ if (smb_read_error == READ_EOF) {
DEBUG( 0, ( "oplock_break: end of file from client\n" ) );
-
- if (smb_read_error == READ_ERROR)
+ shutdown_server = True;
+ } else if (smb_read_error == READ_ERROR) {
DEBUG( 0, ("oplock_break: receive_smb error (%s)\n", strerror(errno)) );
-
- if (smb_read_error == READ_TIMEOUT)
+ shutdown_server = True;
+ } else if (smb_read_error == READ_TIMEOUT) {
DEBUG( 0, ( "oplock_break: receive_smb timed out after %d seconds.\n",
OPLOCK_BREAK_TIMEOUT ) );
+ oplock_timeout = True;
+ }
- DEBUGADD( 0, ( "oplock_break failed for file %s ", fsp->fsp_name ) );
+ DEBUGADD( 0, ( "oplock_break failed for file %s ", file_name ) );
DEBUGADD( 0, ( "(dev = %x, inode = %.0f).\n", (unsigned int)dev, (double)inode));
- shutdown_server = True;
break;
}
if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
{
if( DEBUGLVL( 0 ) )
- {
+ {
dbgtext( "oplock_break: no break received from client " );
dbgtext( "within %d seconds.\n", OPLOCK_BREAK_TIMEOUT );
dbgtext( "oplock_break failed for file %s ", fsp->fsp_name );
dbgtext( "(dev = %x, inode = %.0f).\n", (unsigned int)dev, (double)inode );
- }
- shutdown_server = True;
+ }
+ oplock_timeout = True;
break;
}
}
global_oplock_break = False;
/*
- * If the client did not respond we must die.
+ * If the client timed out then clear the oplock (or go to level II)
+ * and continue. This seems to be what NT does and is better than dropping
+ * the connection.
+ */
+
+ if(oplock_timeout && (fsp = initial_break_processing(dev, inode, tval)) &&
+ OPEN_FSP(fsp) && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+ {
+ DEBUG(0,("oplock_break: client failure in oplock break in file %s\n", fsp->fsp_name));
+ remove_oplock(fsp);
+ global_client_failed_oplock_break = True; /* Never grant this client an oplock again. */
+ }
+
+ /*
+ * If the client had an error we must die.
*/
if(shutdown_server)
exit_server("oplock break failure");
}
- if(OPEN_FSP(fsp))
- {
- /* The lockingX reply will have removed the oplock flag
- from the sharemode. */
- release_file_oplock(fsp);
- }
-
/* Santity check - remove this later. JRA */
- if(global_oplocks_open < 0)
+ if(exclusive_oplocks_open < 0)
{
- DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
- global_oplocks_open));
- exit_server("oplock_break: global_oplocks_open < 0");
+ DEBUG(0,("oplock_break: exclusive_oplocks_open < 0 (%d). PANIC ERROR\n",
+ exclusive_oplocks_open));
+ abort();
}
-
if( DEBUGLVL( 3 ) )
{
dbgtext( "oplock_break: returning success for " );
dbgtext( "dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
- dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
+ dbgtext( "Current exclusive_oplocks_open = %d\n", exclusive_oplocks_open );
}
return True;
{
char op_break_msg[OPLOCK_BREAK_MSG_LEN];
struct sockaddr_in addr_out;
- int pid = getpid();
+ pid_t pid = getpid();
time_t start_time;
int time_left;
+ long usec;
+ time_t sec;
if(pid == share_entry->pid)
{
if(share_entry->op_port != global_oplock_port)
{
DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
-should be %d\n", pid, share_entry->op_port, global_oplock_port));
+should be %d\n", (int)pid, share_entry->op_port, global_oplock_port));
return False;
}
DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
/* Call oplock break direct. */
- return oplock_break(dev, inode, &share_entry->time);
+ return oplock_break(dev, inode, &share_entry->time, True);
}
/* We need to send a OPLOCK_BREAK_CMD message to the
port in the share mode entry. */
- SSVAL(op_break_msg,OPBRK_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
- SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
- SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
- SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
- SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
- /*
- * WARNING - beware of SMB_INO_T <> 4 bytes.
- */
-#ifdef LARGE_SMB_INO_T
- SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,(inode & 0xFFFFFFFFL));
- SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET+4,((inode >> 32) & 0xFFFFFFFFL));
-#else /* LARGE_SMB_INO_T */
- SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
-#endif /* LARGE_SMB_INO_T */
+ if (LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
+ SSVAL(op_break_msg,OPBRK_MESSAGE_CMD_OFFSET,LEVEL_II_OPLOCK_BREAK_CMD);
+ } else {
+ SSVAL(op_break_msg,OPBRK_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
+ }
+ memcpy(op_break_msg+OPLOCK_BREAK_PID_OFFSET,(char *)&pid,sizeof(pid));
+ sec = (time_t)share_entry->time.tv_sec;
+ memcpy(op_break_msg+OPLOCK_BREAK_SEC_OFFSET,(char *)&sec,sizeof(sec));
+ usec = (long)share_entry->time.tv_usec;
+ memcpy(op_break_msg+OPLOCK_BREAK_USEC_OFFSET,(char *)&usec,sizeof(usec));
+ memcpy(op_break_msg+OPLOCK_BREAK_DEV_OFFSET,(char *)&dev,sizeof(dev));
+ memcpy(op_break_msg+OPLOCK_BREAK_INODE_OFFSET,(char *)&inode,sizeof(inode));
/* set the address and port */
- ZERO_STRUCT(addr_out);
+ memset((char *)&addr_out,'\0',sizeof(addr_out));
addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr_out.sin_port = htons( share_entry->op_port );
addr_out.sin_family = AF_INET;
if( DEBUGLVL( 3 ) )
{
dbgtext( "request_oplock_break: sending a oplock break message to " );
- dbgtext( "pid %d on port %d ", share_entry->pid, share_entry->op_port );
- dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
+ dbgtext( "pid %d on port %d ", (int)share_entry->pid, share_entry->op_port );
+ dbgtext( "for dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
+ (unsigned int)dev, (double)inode, (int)share_entry->time.tv_sec,
+ (int)share_entry->time.tv_usec );
+
}
if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
if( DEBUGLVL( 0 ) )
{
dbgtext( "request_oplock_break: failed when sending a oplock " );
- dbgtext( "break message to pid %d ", share_entry->pid );
+ dbgtext( "break message to pid %d ", (int)share_entry->pid );
dbgtext( "on port %d ", share_entry->op_port );
- dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
+ dbgtext( "for dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
+ (unsigned int)dev, (double)inode, (int)share_entry->time.tv_sec,
+ (int)share_entry->time.tv_usec );
dbgtext( "Error was %s\n", strerror(errno) );
}
return False;
}
+ /*
+ * If we just sent a message to a level II oplock share entry then
+ * we are done and may return.
+ */
+
+ if (LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
+ DEBUG(3,("request_oplock_break: sent break message to level II entry.\n"));
+ return True;
+ }
+
/*
* Now we must await the oplock broken message coming back
* from the target smbd process. Timeout if it fails to
FD_ZERO(&fds);
FD_SET(oplock_sock,&fds);
-#if defined(HAVE_KERNEL_OPLOCKS)
- if(lp_kernel_oplocks())
+ if(lp_kernel_oplocks() && (oplock_pipe_read != -1))
FD_SET(oplock_pipe_read,&fds);
-#endif /* HAVE_KERNEL_OPLOCKS */
if(receive_local_message(&fds, op_break_reply, sizeof(op_break_reply),
time_left ? time_left * 1000 : 1) == False)
if( DEBUGLVL( 0 ) )
{
dbgtext( "request_oplock_break: no response received to oplock " );
- dbgtext( "break request to pid %d ", share_entry->pid );
+ dbgtext( "break request to pid %d ", (int)share_entry->pid );
dbgtext( "on port %d ", share_entry->op_port );
dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
+ dbgtext( "for dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
+ (unsigned int)dev, (double)inode, (int)share_entry->time.tv_sec,
+ (int)share_entry->time.tv_usec );
}
/*
if( DEBUGLVL( 0 ) )
{
dbgtext( "request_oplock_break: error in response received " );
- dbgtext( "to oplock break request to pid %d ", share_entry->pid );
+ dbgtext( "to oplock break request to pid %d ", (int)share_entry->pid );
dbgtext( "on port %d ", share_entry->op_port );
- dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
+ dbgtext( "for dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
+ (unsigned int)dev, (double)inode, (int)share_entry->time.tv_sec,
+ (int)share_entry->time.tv_usec );
dbgtext( "Error was (%s).\n", strerror(errno) );
}
return False;
Used as a last ditch attempt to free a space in the
file table when we have run out.
****************************************************************************/
+
BOOL attempt_close_oplocked_file(files_struct *fsp)
{
DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->fsp_name));
- if (fsp->open && fsp->granted_oplock && !fsp->sent_oplock_break && (fsp->fd_ptr != NULL)) {
+ if (fsp->open && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !fsp->sent_oplock_break && (fsp->fd_ptr != NULL)) {
/* Try and break the oplock. */
file_fd_struct *fd_ptr = fsp->fd_ptr;
- if(oplock_break( fd_ptr->dev, fd_ptr->inode, &fsp->open_time)) {
+ if(oplock_break( fd_ptr->dev, fd_ptr->inode, &fsp->open_time, True)) {
if(!fsp->open) /* Did the oplock break close the file ? */
return True;
}
extern int Protocol;
/* users from session setup */
-static pstring session_users="";
+static pstring session_users = "";
extern pstring scope;
extern pstring global_myname;
****************************************************************************/
void add_session_user(char *user)
{
- fstring suser;
- StrnCpy(suser,user,sizeof(suser)-1);
+ fstring suser;
+ StrnCpy(suser, user, sizeof(suser) - 1);
- if (!Get_Pwnam(suser,True)) return;
+ if (!Get_Pwnam(suser, True))
+ return;
- if (suser && *suser && !in_list(suser,session_users,False))
- {
- if (strlen(suser) + strlen(session_users) + 2 >= sizeof(pstring))
- DEBUG(1,("Too many session users??\n"));
- else
+ if (suser && *suser && !in_list(suser, session_users, False))
{
- pstrcat(session_users," ");
- pstrcat(session_users,suser);
+ if (strlen(suser) + strlen(session_users) + 2 >=
+ sizeof(pstring))
+ DEBUG(1, ("Too many session users??\n"));
+ else
+ {
+ pstrcat(session_users, " ");
+ pstrcat(session_users, suser);
+ }
}
- }
}
/****************************************************************************
return True if the password is correct, False otherwise
****************************************************************************/
BOOL password_ok(const char *orig_user, const char *domain,
- const char *smb_apasswd, int smb_apasslen,
- const char *smb_ntpasswd, int smb_ntpasslen,
- struct passwd *pwd,
- NET_USER_INFO_3 *info3)
+ const char *smb_apasswd, int smb_apasslen,
+ const char *smb_ntpasswd, int smb_ntpasslen,
+ struct passwd *pwd, NET_USER_INFO_3 * info3)
{
uchar last_chal[8];
BOOL cleartext = smb_apasslen != 24 && smb_ntpasslen == 0;
if (info3 == NULL)
{
- DEBUG(0,("password_ok: no NET_USER_INFO_3 parameter!\n"));
+ DEBUG(0, ("password_ok: no NET_USER_INFO_3 parameter!\n"));
return False;
}
(lp_encrypted_passwords() && smb_apasslen == 0 &&
lp_null_passwords()))
{
- DEBUG(10,("password_ok: check SMB auth\n"));
+ DEBUG(10, ("password_ok: check SMB auth\n"));
/* check security = user / domain */
if ((!cleartext) && last_challenge(last_chal))
smb_ntpasswd, smb_ntpasslen,
info3) == 0x0)
{
- DEBUG(10,("password_ok: domain auth succeeded\n"));
+ DEBUG(10, ("password_ok: domain auth succeeded\n"));
return True;
}
}
- DEBUG(10,("password_ok: check Unix auth\n"));
+ DEBUG(10, ("password_ok: check Unix auth\n"));
/*
* unix password check
*/
if (!lp_update_encrypted())
{
- if (pass_check(orig_user, smb_apasswd, smb_apasslen, pwd, NULL))
+ if (pass_check
+ (orig_user, smb_apasswd, smb_apasslen, pwd, NULL))
{
- DEBUG(10,("password_ok: Unix auth succeeded\n"));
+ DEBUG(10, ("password_ok: Unix auth succeeded\n"));
return True;
}
}
}
-
-
/****************************************************************************
validate a group username entry. Return the username or NULL
****************************************************************************/
-static char *validate_group(char *group,char *password,int pwlen,int snum,
- NET_USER_INFO_3 *info3)
+static char *validate_group(char *group, char *password, int pwlen, int snum,
+ NET_USER_INFO_3 *info3)
{
-#if defined(HAVE_NETGROUP) && defined(HAVE_GETNETGRENT) && defined(HAVE_SETNETGRENT) && defined(HAVE_ENDNETGRENT)
- {
- char *host, *user, *domain;
- setnetgrent(group);
- while (getnetgrent(&host, &user, &domain)) {
- if (user) {
- if (user_ok(user, snum) &&
- password_ok(user,NULL,password,pwlen,NULL,0,NULL,info3))
+#ifdef HAVE_NETGROUP
+ char *host, *user, *domain;
+#endif
+#ifdef HAVE_GETGRENT
+ struct group *gptr;
+ pstring member_list;
+ char *member;
+ size_t copied_len = 0;
+ int i;
+#endif
+
+#ifdef HAVE_NETGROUP
+
+ setnetgrent(group);
+ while (getnetgrent(&host, &user, &domain))
{
- endnetgrent();
- return(user);
+ if (user)
+ {
+ if (user_ok(user, snum) &&
+ password_ok(user, NULL, password, pwlen,
+ NULL, 0, NULL, info3))
+ {
+ endnetgrent();
+ return (user);
+ }
+ }
}
- }
- }
- endnetgrent();
- }
+ endnetgrent();
#endif
-
-#ifdef HAVE_GETGRNAM
- {
- struct group *gptr = (struct group *)getgrnam(group);
- char **member;
- if (gptr)
- {
- member = gptr->gr_mem;
- while (member && *member)
- {
- static fstring name;
- fstrcpy(name,*member);
- if (user_ok(name,snum) &&
- password_ok(name,NULL,password,pwlen,NULL,0,NULL, info3))
- return(&name[0]);
- member++;
- }
-#ifdef GROUP_CHECK_PWENT
+
+#ifdef HAVE_GETGRENT
+
+ setgrent();
+ while ((gptr = (struct group *)getgrent()))
+ {
+ if (strequal(gptr->gr_name, group))
+ break;
+ }
+
+ /*
+ * As user_ok can recurse doing a getgrent(), we must
+ * copy the member list into a pstring on the stack before
+ * use. Bug pointed out by leon@eatworms.swmed.edu.
+ */
+
+ if (gptr == NULL)
+ {
+ endgrent();
+ return NULL;
+ }
+
+ *member_list = '\0';
+ member = member_list;
+
+ for (i = 0; gptr->gr_mem && gptr->gr_mem[i]; i++)
+ {
+ size_t member_len = strlen(gptr->gr_mem[i]) + 1;
+ if (copied_len + member_len < sizeof(pstring))
+ {
+
+ DEBUG(10,
+ ("validate_group: = gr_mem = %s\n",
+ gptr->gr_mem[i]));
+
+ safe_strcpy(member, gptr->gr_mem[i],
+ sizeof(pstring) - copied_len - 1);
+ copied_len += member_len;
+ member += copied_len;
+ }
+ else
+ {
+ *member = '\0';
+ }
+ }
+
+ endgrent();
+
+ member = member_list;
+ while (*member)
{
- struct passwd *pwd;
- static fstring tm;
-
- setpwent ();
- while (pwd = getpwent ()) {
- if (*(pwd->pw_passwd) && pwd->pw_gid == gptr->gr_gid) {
- /* This Entry have PASSWORD and same GID then check pwd */
- if (password_ok(NULL, NULL, password, pwlen, NULL, 0, pwd, user_sess_key)) {
- fstrcpy(tm, pwd->pw_name);
- endpwent ();
- return tm;
- }
- }
- }
- endpwent ();
+ static fstring name;
+ fstrcpy(name, member);
+ if (user_ok(name, snum) &&
+ password_ok(name, NULL, password, pwlen,
+ NULL, 0, NULL, info3))
+ {
+ endgrent();
+ return (&name[0]);
+ }
+
+ DEBUG(10, ("validate_group = member = %s\n", member));
+
+ member += strlen(member) + 1;
}
-#endif /* GROUP_CHECK_PWENT */
- }
- }
#endif
- return(NULL);
+ return (NULL);
}
-
/****************************************************************************
check for authority to login to a service with a given username/password
****************************************************************************/
BOOL authorise_login(int snum, char *user, char *domain,
- char *password, int pwlen,
- BOOL *guest,BOOL *force,
- const vuser_key *key)
+ char *password, int pwlen,
+ BOOL *guest, BOOL *force, const vuser_key * key)
{
BOOL ok = False;
- DEBUG(0,("authorise_login: TODO. split function, it's 6 levels!\n"));
+ DEBUG(0, ("authorise_login: TODO. split function, it's 6 levels!\n"));
*guest = False;
#if DEBUG_PASSWORD
- DEBUG(100,("checking authorisation on user=%s pass=%s\n",user,password));
+ DEBUG(100,
+ ("checking authorisation on user=%s pass=%s\n", user,
+ password));
#endif
- /* there are several possibilities:
- 1) login as the given user with given password
- 2) login as a previously registered username with the given password
- 3) login as a session list username with the given password
- 4) login as a previously validated user/password pair
- 5) login as the "user =" user with given password
- 6) login as the "user =" user with no password (guest connection)
- 7) login as guest user with no password
+ /* there are several possibilities:
+ 1) login as the given user with given password
+ 2) login as a previously registered username with the given password
+ 3) login as a session list username with the given password
+ 4) login as a previously validated user/password pair
+ 5) login as the "user =" user with given password
+ 6) login as the "user =" user with no password (guest connection)
+ 7) login as guest user with no password
- if the service is guest_only then steps 1 to 5 are skipped
- */
+ if the service is guest_only then steps 1 to 5 are skipped
+ */
- if (GUEST_ONLY(snum)) *force = True;
+ if (GUEST_ONLY(snum))
+ *force = True;
if (!(GUEST_ONLY(snum) && GUEST_OK(snum)))
{
user_struct *vuser = get_valid_user_struct(key);
/* check the given username and password */
- if (!ok && (*user) && user_ok(user,snum))
+ if (!ok && (*user) && user_ok(user, snum))
{
- ok = password_ok(user,domain, password, pwlen, NULL, 0, NULL, &vuser->usr);
- if (ok) DEBUG(3,("ACCEPTED: given username password ok\n"));
+ ok =
+ password_ok(user, domain, password, pwlen,
+ NULL, 0, NULL, &vuser->usr);
+ if (ok)
+ DEBUG(3,
+ ("ACCEPTED: given username password ok\n"));
}
/* check for a previously registered guest username */
if (!ok && (vuser != 0) && vuser->guest)
- {
- if (user_ok(vuser->name,snum) &&
- password_ok(vuser->name, domain, password, pwlen, NULL, 0, NULL, &vuser->usr))
+ {
+ if (user_ok(vuser->name, snum) &&
+ password_ok(vuser->name, domain, password, pwlen,
+ NULL, 0, NULL, &vuser->usr))
{
fstrcpy(user, vuser->name);
vuser->guest = False;
- DEBUG(3,("ACCEPTED: given password with registered user %s\n", user));
+ DEBUG(3,
+ ("ACCEPTED: given password with registered user %s\n",
+ user));
ok = True;
}
}
return False;
}
- for (auser=strtok(user_list,LIST_SEP);
- !ok && auser;
- auser = strtok(NULL,LIST_SEP))
+ for (auser = strtok(user_list, LIST_SEP);
+ !ok && auser; auser = strtok(NULL, LIST_SEP))
{
fstring user2;
- fstrcpy(user2,auser);
- if (!user_ok(user2,snum)) continue;
+ fstrcpy(user2, auser);
+ if (!user_ok(user2, snum))
+ continue;
- if (password_ok(user2, domain, password, pwlen, NULL, 0, NULL,
- &vuser->usr))
+ if (password_ok
+ (user2, domain, password, pwlen, NULL, 0,
+ NULL, &vuser->usr))
{
ok = True;
- fstrcpy(user,user2);
- DEBUG(3,("ACCEPTED: session list username and given password ok\n"));
+ fstrcpy(user, user2);
+ DEBUG(3,
+ ("ACCEPTED: session list username and given password ok\n"));
}
}
free(user_list);
}
/* check for a previously validated username/password pair */
- if (!ok && (!lp_revalidate(snum) || lp_security() > SEC_SHARE) &&
- (vuser != 0) && !vuser->guest &&
- user_ok(vuser->name,snum))
+ if (!ok && (!lp_revalidate(snum) || lp_security() > SEC_SHARE)
+ && (vuser != 0) && !vuser->guest
+ && user_ok(vuser->name, snum))
{
- fstrcpy(user,vuser->name);
+ fstrcpy(user, vuser->name);
*guest = False;
- DEBUG(3,("ACCEPTED: validated uid ok as non-guest\n"));
+ DEBUG(3,
+ ("ACCEPTED: validated uid ok as non-guest\n"));
ok = True;
}
/* check for a rhosts entry */
- if (!ok && user_ok(user,snum) && check_hosts_equiv(user))
+ if (!ok && user_ok(user, snum) && check_hosts_equiv(user))
{
ok = True;
- DEBUG(3,("ACCEPTED: hosts equiv or rhosts entry\n"));
+ DEBUG(3, ("ACCEPTED: hosts equiv or rhosts entry\n"));
}
/* check the user= fields and the given password */
{
char *auser;
pstring user_list;
- StrnCpy(user_list,lp_username(snum),sizeof(pstring));
+ StrnCpy(user_list, lp_username(snum),
+ sizeof(pstring));
- string_sub(user_list,"%S",lp_servicename(snum));
+ pstring_sub(user_list, "%S", lp_servicename(snum));
- for (auser=strtok(user_list,LIST_SEP);
- auser && !ok;
- auser = strtok(NULL,LIST_SEP))
+ for (auser = strtok(user_list, LIST_SEP);
+ auser && !ok; auser = strtok(NULL, LIST_SEP))
{
if (*auser == '@')
{
- auser = validate_group(auser+1,password,pwlen,snum, &vuser->usr);
+ auser =
+ validate_group(auser + 1,
+ password,
+ pwlen, snum,
+ &vuser->usr);
if (auser)
{
ok = True;
- fstrcpy(user,auser);
- DEBUG(3,("ACCEPTED: group username and given password ok\n"));
+ fstrcpy(user, auser);
+ DEBUG(3,
+ ("ACCEPTED: group username and given password ok\n"));
}
}
else
{
fstring user2;
- fstrcpy(user2,auser);
- if (user_ok(user2,snum) &&
- password_ok(user2,domain,password,pwlen,NULL, 0,
- NULL, &vuser->usr))
+ fstrcpy(user2, auser);
+ if (user_ok(user2, snum) &&
+ password_ok(user2, domain,
+ password, pwlen, NULL,
+ 0, NULL, &vuser->usr))
{
ok = True;
- fstrcpy(user,user2);
- DEBUG(3,("ACCEPTED: user list username and given password ok\n"));
+ fstrcpy(user, user2);
+ DEBUG(3,
+ ("ACCEPTED: user list username and given password ok\n"));
}
}
}
- }
+ }
if (vuser != NULL)
{
}
vuid_free_user_struct(vuser);
- } /* not guest only */
+ } /* not guest only */
/* check for a normal guest connection */
if (!ok && GUEST_OK(snum))
{
fstring guestname;
- StrnCpy(guestname,lp_guestaccount(snum),sizeof(guestname)-1);
- if (Get_Pwnam(guestname,True))
+ StrnCpy(guestname, lp_guestaccount(snum),
+ sizeof(guestname) - 1);
+ if (Get_Pwnam(guestname, True))
{
- fstrcpy(user,guestname);
+ fstrcpy(user, guestname);
ok = True;
- DEBUG(3,("ACCEPTED: guest account and guest ok\n"));
+ DEBUG(3, ("ACCEPTED: guest account and guest ok\n"));
}
else
- DEBUG(0,("Invalid guest account %s??\n",guestname));
+ DEBUG(0, ("Invalid guest account %s??\n", guestname));
*guest = True;
*force = True;
}
- if (ok && !user_ok(user,snum))
+ if (ok && !user_ok(user, snum))
{
- DEBUG(0,("rejected invalid user %s\n",user));
+ DEBUG(0, ("rejected invalid user %s\n", user));
ok = False;
}
- return(ok);
+ return (ok);
}
-
-/****************************************************************************
-read the a hosts.equiv or .rhosts file and check if it
-allows this user from this machine
-****************************************************************************/
-static BOOL check_user_equiv(char *user, char *remote, char *equiv_file)
+BOOL check_user_equiv_line(char *buf, const char *user, const char *remote,
+ BOOL *plus_allowed, BOOL *ret)
{
- pstring buf;
- int plus_allowed = 1;
- char *file_host;
- char *file_user;
- FILE *fp = sys_fopen(equiv_file, "r");
- DEBUG(5, ("check_user_equiv %s %s %s\n", user, remote, equiv_file));
- if (! fp) return False;
- while(fgets(buf, sizeof(buf), fp))
- {
- trim_string(buf," "," ");
-
- if (buf[0] != '#' && buf[0] != '\n')
- {
- BOOL is_group = False;
- int plus = 1;
- char *bp = buf;
- if (strcmp(buf, "NO_PLUS\n") == 0)
- {
- DEBUG(6, ("check_user_equiv NO_PLUS\n"));
- plus_allowed = 0;
- }
- else {
- if (buf[0] == '+')
+ BOOL is_group = False;
+ int plus = 1;
+ char *bp = buf;
+ char *file_host;
+ char *file_user;
+
+ if (strcmp(buf, "NO_PLUS\n") == 0)
{
- bp++;
- if (*bp == '\n' && plus_allowed)
- {
- /* a bare plus means everbody allowed */
- DEBUG(6, ("check_user_equiv everybody allowed\n"));
- fclose(fp);
- return True;
- }
+ DEBUG(6, ("check_user_equiv NO_PLUS\n"));
+ (*plus_allowed) = 0;
+ return False;
+ }
+
+ if (buf[0] == '+')
+ {
+ bp++;
+ if (*bp == '\n' && (*plus_allowed))
+ {
+ /* a bare plus means everbody allowed */
+ DEBUG(6, ("check_user_equiv everybody allowed\n"));
+ *ret = True;
+ return True;
+ }
}
else if (buf[0] == '-')
{
- bp++;
- plus = 0;
+ bp++;
+ plus = 0;
}
- if (*bp == '@')
+ if (*bp == '@')
{
- is_group = True;
- bp++;
+ is_group = True;
+ bp++;
}
+
file_host = strtok(bp, " \t\n");
file_user = strtok(NULL, " \t\n");
- DEBUG(7, ("check_user_equiv %s %s\n", file_host ? file_host : "(null)",
- file_user ? file_user : "(null)" ));
- if (file_host && *file_host)
- {
- BOOL host_ok = False;
+ DEBUG(7, ("check_user_equiv %s %s\n",
+ file_host ? file_host : "(null)",
+ file_user ? file_user : "(null)"));
+ if (file_host && *file_host)
+ {
+ BOOL host_ok = False;
#if defined(HAVE_NETGROUP) && defined(HAVE_YP_GET_DEFAULT_DOMAIN)
- if (is_group)
- {
- static char *mydomain = NULL;
- if (!mydomain)
- yp_get_default_domain(&mydomain);
- if (mydomain && innetgr(file_host,remote,user,mydomain))
- host_ok = True;
- }
+ if (is_group)
+ {
+ static char *mydomain = NULL;
+ if (!mydomain)
+ yp_get_default_domain(&mydomain);
+ if (mydomain && innetgr(file_host, remote, user,
+ mydomain)) host_ok = True;
+ }
#else
- if (is_group)
- {
- DEBUG(1,("Netgroups not configured\n"));
- continue;
- }
+ if (is_group)
+ {
+ DEBUG(1, ("Netgroups not configured\n"));
+ return False;
+ }
#endif
+ /* is it this host */
+ /* the fact that remote has come from a call of
+ * gethostbyaddr means that it may have the fully
+ * qualified domain name so we could look up the
+ * file version to get it into a canonical form,
+ * but I would rather just type it in full in the
+ * equiv file */
+ if (!host_ok && !is_group && strequal(remote, file_host))
+ {
+ host_ok = True;
+ }
+ if (!host_ok)
+ {
+ return False;
+ }
+ /* is it this user */
+ if (file_user == 0 || strequal(user, file_user))
+ {
+ DEBUG(5, ("check_user_equiv matched %s%s %s\n",
+ (plus ? "+" : "-"), file_host,
+ (file_user ? file_user : "")));
+ *ret = (plus ? True : False);
+ return True;
+ }
+ }
+
+ return False;
+}
+
+/****************************************************************************
+read the a hosts.equiv or .rhosts file and check if it
+allows this user from this machine
+****************************************************************************/
+static BOOL check_user_equiv(char *user, char *remote, char *equiv_file)
+{
+ pstring buf;
+ int plus_allowed = 1;
+ FILE *fp = sys_fopen(equiv_file, "r");
+ DEBUG(5, ("check_user_equiv %s %s %s\n", user, remote, equiv_file));
+ if (!fp)
+ return False;
+ while (fgets(buf, sizeof(buf), fp))
+ {
+ trim_string(buf, " ", " ");
- /* is it this host */
- /* the fact that remote has come from a call of gethostbyaddr
- * means that it may have the fully qualified domain name
- * so we could look up the file version to get it into
- * a canonical form, but I would rather just type it
- * in full in the equiv file
- */
- if (!host_ok && !is_group && strequal(remote, file_host))
- host_ok = True;
-
- if (!host_ok)
- continue;
-
- /* is it this user */
- if (file_user == 0 || strequal(user, file_user))
- {
- fclose(fp);
- DEBUG(5, ("check_user_equiv matched %s%s %s\n",
- (plus ? "+" : "-"), file_host,
- (file_user ? file_user : "")));
- return (plus ? True : False);
- }
+ if (buf[0] != '#' && buf[0] != '\n')
+ {
+ BOOL ret;
+ if (check_user_equiv_line(buf, user, remote,
+ &plus_allowed, &ret))
+ {
+ fclose(fp);
+ return ret;
+ }
+ }
}
- }
- }
- }
- fclose(fp);
- return False;
+ fclose(fp);
+ return False;
}
****************************************************************************/
BOOL check_hosts_equiv(char *user)
{
- char *fname = NULL;
- pstring rhostsfile;
- const struct passwd *pass = Get_Pwnam(user,True);
-
- if (!pass)
- return False;
-
- fname = lp_hosts_equiv();
-
- /* note: don't allow hosts.equiv on root */
- if (fname && *fname && (pass->pw_uid != 0)) {
- if (check_user_equiv(user,client_connection_name(),fname))
- return(True);
- }
-
- if (lp_use_rhosts())
- {
- char *home = get_unixhome_dir(user);
- if (home) {
- slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home);
- if (check_user_equiv(user,client_connection_name(),rhostsfile))
- return(True);
- }
- }
-
- return False;
-}
+ char *fname = NULL;
+ pstring rhostsfile;
+ const struct passwd *pass = Get_Pwnam(user, True);
+
+ if (!pass)
+ return False;
+ fname = lp_hosts_equiv();
+ /* note: don't allow hosts.equiv on root */
+ if (fname && *fname && (pass->pw_uid != 0))
+ {
+ if (check_user_equiv(user, client_connection_name(), fname))
+ return (True);
+ }
+
+ if (lp_use_rhosts())
+ {
+ char *home = get_unixhome_dir(user);
+ if (home)
+ {
+ slprintf(rhostsfile, sizeof(rhostsfile) - 1,
+ "%s/.rhosts", home);
+ if (check_user_equiv
+ (user, client_connection_name(), rhostsfile))
+ return (True);
+ }
+ }
+
+ return False;
+}
This code is basically stolen from reply_open_and_X with some
wrinkles to handle pipes.
****************************************************************************/
-int reply_open_pipe_and_X(connection_struct *conn,
- char *inbuf,char *outbuf,int length,int bufsize)
+int reply_open_pipe_and_X(connection_struct * conn,
+ char *inbuf, char *outbuf, int length, int bufsize)
{
pstring fname;
uint16 vuid = SVAL(inbuf, smb_uid);
pipes_struct *p;
- int smb_ofun = SVAL(inbuf,smb_vwv8);
- int size=0,fmode=0,mtime=0,rmode=0;
+ int smb_ofun = SVAL(inbuf, smb_vwv8);
+ int size = 0, fmode = 0, mtime = 0, rmode = 0;
int i;
vuser_key key;
/* XXXX we need to handle passed times, sattr and flags */
- pstrcpy(fname,smb_buf(inbuf));
+ pstrcpy(fname, smb_buf(inbuf));
/* If the name doesn't start \PIPE\ then this is directed */
/* at a mailslot or something we really, really don't understand, */
/* not just something we really don't understand. */
- if ( strncmp(fname,PIPE,PIPELEN) != 0 )
- return(ERROR(ERRSRV,ERRaccess));
+ if (strncmp(fname, PIPE, PIPELEN) != 0)
+ return (ERROR(ERRSRV, ERRaccess));
- DEBUG(4,("Opening pipe %s.\n", fname));
+ DEBUG(4, ("Opening pipe %s.\n", fname));
/* See if it is one we want to handle. */
- for( i = 0; pipe_names[i].client_pipe ; i++ )
- if( strequal(fname,pipe_names[i].client_pipe) )
+ for (i = 0; pipe_names[i].client_pipe; i++)
+ if (strequal(fname, pipe_names[i].client_pipe))
break;
if (pipe_names[i].client_pipe == NULL)
- return(ERROR(ERRSRV,ERRaccess));
+ return (ERROR(ERRSRV, ERRaccess));
/* Strip \PIPE\ off the name. */
- pstrcpy(fname,smb_buf(inbuf) + PIPELEN);
+ pstrcpy(fname, smb_buf(inbuf) + PIPELEN);
/* Known pipes arrive with DIR attribs. Remove it so a regular file */
/* can be opened and add it in after the open. */
- DEBUG(3,("Known pipe %s opening.\n",fname));
- smb_ofun |= 0x10; /* Add Create it not exists flag */
+ DEBUG(3, ("Known pipe %s opening.\n", fname));
+ smb_ofun |= 0x10; /* Add Create it not exists flag */
key.pid = getpid();
key.vuid = vuid;
p = open_rpc_pipe_p(fname, &key, NULL);
- if (!p) return(ERROR(ERRSRV,ERRnofids));
+ if (!p)
+ return (ERROR(ERRSRV, ERRnofids));
/* Prepare the reply */
- set_message(outbuf,15,0,True);
+ set_message(outbuf, 15, 0, True);
/* Mark the opened file as an existing named pipe in message mode. */
- SSVAL(outbuf,smb_vwv9,2);
- SSVAL(outbuf,smb_vwv10,0xc700);
+ SSVAL(outbuf, smb_vwv9, 2);
+ SSVAL(outbuf, smb_vwv10, 0xc700);
- if (rmode == 2) {
- DEBUG(4,("Resetting open result to open from create.\n"));
+ if (rmode == 2)
+ {
+ DEBUG(4, ("Resetting open result to open from create.\n"));
rmode = 1;
}
- SSVAL(outbuf,smb_vwv2, p->pnum);
- SSVAL(outbuf,smb_vwv3,fmode);
- put_dos_date3(outbuf,smb_vwv4,mtime);
- SIVAL(outbuf,smb_vwv6,size);
- SSVAL(outbuf,smb_vwv8,rmode);
- SSVAL(outbuf,smb_vwv11,0x0001);
+ SSVAL(outbuf, smb_vwv2, p->pnum);
+ SSVAL(outbuf, smb_vwv3, fmode);
+ put_dos_date3(outbuf, smb_vwv4, mtime);
+ SIVAL(outbuf, smb_vwv6, size);
+ SSVAL(outbuf, smb_vwv8, rmode);
+ SSVAL(outbuf, smb_vwv11, 0x0001);
- return chain_reply(inbuf,outbuf,length,bufsize);
+ return chain_reply(inbuf, outbuf, length, bufsize);
}
/****************************************************************************
This code is basically stolen from reply_write with some
wrinkles to handle pipes.
****************************************************************************/
-int reply_pipe_write(char *inbuf,char *outbuf,int length,int bufsize)
+int reply_pipe_write(char *inbuf, char *outbuf, int length, int bufsize)
{
- pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0);
- size_t numtowrite = SVAL(inbuf,smb_vwv1);
+ pipes_struct *p = get_rpc_pipe_p(inbuf, smb_vwv0);
+ size_t numtowrite = SVAL(inbuf, smb_vwv1);
int nwritten = -1;
char *data;
size_t outsize;
- if (!p) return(ERROR(ERRDOS,ERRbadfid));
+ if (!p)
+ return (ERROR(ERRDOS, ERRbadfid));
data = smb_buf(inbuf) + 3;
if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0))
{
- DEBUG(3,("reply_write_pipe: nwritten: %d numtowrite:%d\n",
- nwritten, numtowrite));
- return (UNIXERROR(ERRDOS,ERRnoaccess));
+ DEBUG(3, ("reply_write_pipe: nwritten: %d numtowrite:%d\n",
+ nwritten, numtowrite));
+ return (UNIXERROR(ERRDOS, ERRnoaccess));
}
-
- outsize = set_message(outbuf,1,0,True);
- SSVAL(outbuf,smb_vwv0,nwritten);
+ outsize = set_message(outbuf, 1, 0, True);
+
+ SSVAL(outbuf, smb_vwv0, nwritten);
- DEBUG(3,("write-IPC pnum=%04x nwritten=%d\n",
- p->pnum, nwritten));
+ DEBUG(3, ("write-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten));
return outsize;
}
This code is basically stolen from reply_write_and_X with some
wrinkles to handle pipes.
****************************************************************************/
-int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
+int reply_pipe_write_and_X(char *inbuf, char *outbuf, int length, int bufsize)
{
- pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2);
- size_t numtowrite = SVAL(inbuf,smb_vwv10);
+ pipes_struct *p = get_rpc_pipe_p(inbuf, smb_vwv2);
+ size_t numtowrite = SVAL(inbuf, smb_vwv10);
int nwritten = -1;
int smb_doff = SVAL(inbuf, smb_vwv11);
int write_mode = SVAL(inbuf, smb_vwv7);
char *data;
- if (!p) return(ERROR(ERRDOS,ERRbadfid));
+ /*
+ * start of message mode pipe: indicates start of dce/rpc pdu.
+ */
+
+ BOOL msg;
+ msg = IS_BITS_SET_ALL(write_mode, PIPE_START_MESSAGE | PIPE_RAW_MODE);
+
+ if (!p)
+ return (ERROR(ERRDOS, ERRbadfid));
data = smb_base(inbuf) + smb_doff;
}
else
{
- if (write_mode == 0x000c)
+ if (msg)
{
- nwritten = write_pipe(p, data+2, numtowrite-2);
- if (nwritten != 0)
- {
- nwritten += 2;
- }
+ /*
+ * skip the length-of-pdu, the client could be
+ * a nasty bitch and lie to us, e.g
+ * an nt-smb-writepipe-DoS attack.
+ */
+
+ data += 2;
+ numtowrite -= 2;
}
- else
+
+ nwritten = write_pipe(p, data, numtowrite);
+
+ if (msg && nwritten != 0)
{
- nwritten = write_pipe(p, data, numtowrite);
+ nwritten += 2;
}
}
if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0))
{
- return (UNIXERROR(ERRDOS,ERRnoaccess));
+ return (UNIXERROR(ERRDOS, ERRnoaccess));
}
-
- set_message(outbuf,6,0,True);
- SSVAL(outbuf,smb_vwv2,nwritten);
-
- DEBUG(3,("writeX-IPC pnum=%04x nwritten=%d\n",
- p->pnum, nwritten));
+ set_message(outbuf, 6, 0, True);
+ SSVAL(outbuf, smb_vwv2, nwritten);
+
+ DEBUG(3, ("writeX-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten));
- return chain_reply(inbuf,outbuf,length,bufsize);
+ return chain_reply(inbuf, outbuf, length, bufsize);
}
/****************************************************************************
This code is basically stolen from reply_read_and_X with some
wrinkles to handle pipes.
****************************************************************************/
-int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
+int reply_pipe_read_and_X(char *inbuf, char *outbuf, int length, int bufsize)
{
- pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2);
- int smb_maxcnt = SVAL(inbuf,smb_vwv5);
- int smb_mincnt = SVAL(inbuf,smb_vwv6);
+ pipes_struct *p = get_rpc_pipe_p(inbuf, smb_vwv2);
+ int smb_maxcnt = SVAL(inbuf, smb_vwv5);
+ int smb_mincnt = SVAL(inbuf, smb_vwv6);
int nread = -1;
char *data;
- if (!p) return(ERROR(ERRDOS,ERRbadfid));
+ if (!p)
+ return (ERROR(ERRDOS, ERRbadfid));
- set_message(outbuf,12,0,True);
+ set_message(outbuf, 12, 0, True);
data = smb_buf(outbuf);
nread = read_pipe(p, data, smb_maxcnt);
if (nread < 0)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- SSVAL(outbuf,smb_vwv5,nread);
- SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
- SSVAL(smb_buf(outbuf),-2,nread);
-
- DEBUG(3,("readX-IPC pnum=%04x min=%d max=%d nread=%d\n",
- p->pnum, smb_mincnt, smb_maxcnt, nread));
-
- return chain_reply(inbuf,outbuf,length,bufsize);
+ return (UNIXERROR(ERRDOS, ERRnoaccess));
+
+ SSVAL(outbuf, smb_vwv5, nread);
+ SSVAL(outbuf, smb_vwv6, smb_offset(data, outbuf));
+ SSVAL(smb_buf(outbuf), -2, nread);
+
+ DEBUG(3, ("readX-IPC pnum=%04x min=%d max=%d nread=%d\n",
+ p->pnum, smb_mincnt, smb_maxcnt, nread));
+
+ return chain_reply(inbuf, outbuf, length, bufsize);
}
/****************************************************************************
reply to a close
****************************************************************************/
-int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf)
+int reply_pipe_close(connection_struct * conn, char *inbuf, char *outbuf)
{
- pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0);
- int outsize = set_message(outbuf,0,0,True);
+ pipes_struct *p = get_rpc_pipe_p(inbuf, smb_vwv0);
+ int outsize = set_message(outbuf, 0, 0, True);
- if (!p) return(ERROR(ERRDOS,ERRbadfid));
+ if (!p)
+ return (ERROR(ERRDOS, ERRbadfid));
- DEBUG(5,("reply_pipe_close: pnum:%x\n", p->pnum));
+ DEBUG(5, ("reply_pipe_close: pnum:%x\n", p->pnum));
- if (!close_rpc_pipe_hnd(p)) return(ERROR(ERRDOS,ERRbadfid));
+ if (!close_rpc_pipe_hnd(p))
+ return (ERROR(ERRDOS, ERRbadfid));
- return(outsize);
+ return (outsize);
}
-
static time_t rp_time = 0;
static char *rp_buffer = NULL;
static BOOL predict_skip=False;
-extern time_t smb_last_time;
+extern struct timeval smb_last_time;
/****************************************************************************
handle read prediction on a file
if (fd == rp_fd &&
offset >= rp_offset &&
possible>0 &&
- smb_last_time-rp_time < rp_timeout)
+ smb_last_time.tv_secs - rp_time < rp_timeout)
{
ret = possible;
if (buf)
extern int DEBUGLEVEL;
-time_t smb_last_time=(time_t)0;
+struct timeval smb_last_time;
-char *InBuffer = NULL;
+static char *InBuffer = NULL;
char *OutBuffer = NULL;
char *last_inbuf = NULL;
extern char *InBuffer;
extern char *OutBuffer;
extern int smb_read_error;
-extern BOOL reload_after_sighup;
+extern VOLATILE SIG_ATOMIC_T reload_after_sighup;
extern fstring global_myworkgroup;
extern pstring global_myname;
extern int max_send;
return ret;
}
+/****************************************************************************
+ We're terminating and have closed all our files/connections etc.
+ If there are any pending local messages we need to respond to them
+ before termination so that other smbds don't think we just died whilst
+ holding oplocks.
+****************************************************************************/
+
+void respond_to_all_remaining_local_messages(void)
+{
+ char buffer[1024];
+ fd_set fds;
+
+ /*
+ * Assert we have no exclusive open oplocks.
+ */
+
+ if(get_number_of_exclusive_open_oplocks()) {
+ DEBUG(0,("respond_to_all_remaining_local_messages: PANIC : we have %d exclusive oplocks.\n",
+ get_number_of_exclusive_open_oplocks() ));
+ return;
+ }
+
+ /*
+ * Setup the select read fd set.
+ */
+
+ FD_ZERO(&fds);
+ if(!setup_oplock_select_set(&fds))
+ return;
+
+ /*
+ * Keep doing receive_local_message with a 1 ms timeout until
+ * we have no more messages.
+ */
+
+ while(receive_local_message(&fds, buffer, sizeof(buffer), 1)) {
+ /* Deal with oplock break requests from other smbd's. */
+ process_local_message(buffer, sizeof(buffer));
+
+ FD_ZERO(&fds);
+ (void)setup_oplock_select_set(&fds);
+ }
+
+ return;
+}
+
/*
These flags determine some of the permissions required to do an operation
{SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
{SMBread,"SMBread",reply_read,AS_USER},
- {SMBwrite,"SMBwrite",reply_write,AS_USER | CAN_IPC},
- {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
+ {SMBwrite,"SMBwrite",reply_write,AS_USER | CAN_IPC },
+ {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC },
{SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
{SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
{SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
{SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
{SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
{SMBwritec,"SMBwritec",NULL,AS_USER},
- {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
- {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
- {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
+ {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
+ {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER },
+ {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK},
{SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
{SMBioctls,"SMBioctls",NULL,AS_USER},
{SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
{SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
{SMBreadX,"SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
{SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
- {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
+ {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER },
{SMBffirst,"SMBffirst",reply_search,AS_USER},
{SMBfunique,"SMBfunique",reply_search,AS_USER},
/* LANMAN2.0 PROTOCOL FOLLOWS */
{SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
{SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
- {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER | CAN_IPC},
+ {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER | QUEUE_IN_OPLOCK | CAN_IPC },
{SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
/* NT PROTOCOL FOLLOWS */
{SMBntcreateX, "SMBntcreateX", reply_ntcreate_and_X, AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
- {SMBnttrans, "SMBnttrans", reply_nttrans, AS_USER | CAN_IPC },
+ {SMBnttrans, "SMBnttrans", reply_nttrans, AS_USER | CAN_IPC | QUEUE_IN_OPLOCK},
{SMBnttranss, "SMBnttranss", reply_nttranss, AS_USER | CAN_IPC },
- {SMBntcancel, "SMBntcancel", reply_ntcancel, AS_USER },
+ {SMBntcancel, "SMBntcancel", reply_ntcancel, 0 },
/* messaging routines */
{SMBsends,"SMBsends",reply_sends,AS_GUEST},
****************************************************************************/
static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
{
- static int pid= -1;
+ static pid_t pid= (pid_t)-1;
int outsize = 0;
static int num_smb_messages =
sizeof(smb_messages) / sizeof(struct smb_message_struct);
int match;
extern int Client;
+ extern int global_smbpid;
- if (pid == -1)
+ if (pid == (pid_t)-1)
pid = getpid();
errno = 0;
if (smb_messages[match].code == type)
break;
+ /* yuck! this is an interim measure before we get rid of our
+ current inbuf/outbuf system */
+ global_smbpid = SVAL(inbuf,smb_pid);
+
if (match == num_smb_messages)
{
DEBUG(0,("Unknown message type %d!\n",type));
}
else
{
- DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
+ DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,(int)pid));
- if(global_oplock_break && (smb_messages[match].flags & QUEUE_IN_OPLOCK))
+ if(global_oplock_break)
{
- /*
- * Queue this message as we are the process of an oplock break.
- */
+ int flags = smb_messages[match].flags;
- DEBUG( 2, ( "switch_message: queueing message due to being in " ) );
- DEBUGADD( 2, ( "oplock break state.\n" ) );
+ if(flags & QUEUE_IN_OPLOCK)
+ {
+ /*
+ * Queue this message as we are the process of an oplock break.
+ */
- push_oplock_pending_smb_message( inbuf, size );
- return -1;
- }
+ DEBUG( 2, ( "switch_message: queueing message due to being in " ) );
+ DEBUGADD( 2, ( "oplock break state.\n" ) );
+ push_oplock_pending_smb_message( inbuf, size );
+ return -1;
+ }
+ }
if (smb_messages[match].fn)
{
int flags = smb_messages[match].flags;
* move it unless you know what you're doing... :-).
* JRA.
*/
- if (session_tag != last_session_tag)
- {
+ if (session_tag != last_session_tag) {
user_struct *vuser = NULL;
vuser_key key;
key.pid = pid;
if (flags & AS_GUEST)
flags &= ~AS_USER;
else
- return(ERROR(ERRSRV,ERRinvnid));
+ return(ERROR(ERRSRV,ERRaccess));
}
/* this code is to work around a bug is MS client 3 without
introducing a security hole - it needs to be able to do
int type = CVAL(inbuf,smb_com);
int outsize = 0;
int msg_type = CVAL(inbuf,0);
- extern int chain_size;
- smb_last_time = time(NULL);
+ GetTimeOfDay(&smb_last_time);
chain_size = 0;
file_chain_reset();
name" */
static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
DEBUG( 1, ( "Connection denied from %s\n",
- client_connection_addr() ) );
+ client_addr(Client) ) );
send_smb(Client,(char *)buf);
exit_server("connection denied");
}
void construct_reply_common(char *inbuf,char *outbuf)
{
- memset(outbuf, 0, smb_size);
+ memset(outbuf,'\0',smb_size);
set_message(outbuf,0,0,True);
CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
CVAL(outbuf,smb_reh) = 0;
SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES)); /* bit 7 set
means a reply */
- SSVAL(outbuf,smb_flg2,FLAGS2_LONG_PATH_COMPONENTS); /* say we support long filenames */
+ SSVAL(outbuf,smb_flg2,FLAGS2_LONG_PATH_COMPONENTS);
+ /* say we support long filenames */
+
SSVAL(outbuf,smb_err,SMB_SUCCESS);
SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
int outsize2;
char inbuf_saved[smb_wct];
char outbuf_saved[smb_wct];
- extern int chain_size;
int wct = CVAL(outbuf,smb_wct);
int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
orig_outbuf = outbuf;
}
+ /*
+ * The original Win95 redirector dies on a reply to
+ * a lockingX and read chain unless the chain reply is
+ * 4 byte aligned. JRA.
+ */
+
+ outsize = (outsize + 3) & ~3;
+
/* we need to tell the client where the next part of the reply will be */
SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
CVAL(outbuf,smb_vwv0) = smb_com2;
}
/****************************************************************************
- process commands from the client
+ Setup the needed select timeout.
****************************************************************************/
-void smbd_process(void)
+
+static int setup_select_timeout(void)
{
- extern int Client;
- extern int ClientPort;
+ int change_notify_timeout = lp_change_notify_timeout() * 1000;
+ int select_timeout;
- InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- if ((InBuffer == NULL) || (OutBuffer == NULL))
- return;
+ /*
+ * Increase the select timeout back to SMBD_SELECT_TIMEOUT if we
+ * have removed any blocking locks. JRA.
+ */
- InBuffer += SMB_ALIGNMENT;
- OutBuffer += SMB_ALIGNMENT;
+ select_timeout = blocking_locks_pending() ? SMBD_SELECT_TIMEOUT_WITH_PENDING_LOCKS*1000 :
+ SMBD_SELECT_TIMEOUT*1000;
+
+ if (change_notifies_pending())
+ select_timeout = MIN(select_timeout, change_notify_timeout);
+
+ return select_timeout;
+}
+
+/****************************************************************************
+ Check if services need reloading.
+****************************************************************************/
+
+void check_reload(int t)
+{
+ static time_t last_smb_conf_reload_time = 0;
+
+ if(last_smb_conf_reload_time == 0)
+ last_smb_conf_reload_time = t;
-#if PRIME_NMBD
- DEBUG(3,("priming nmbd\n"));
+ if (reload_after_sighup || (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK))
{
- struct in_addr ip;
- ip = *interpret_addr2("localhost");
- if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
- *OutBuffer = 0;
- send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
+ reload_services(True);
+ reload_after_sighup = False;
+ last_smb_conf_reload_time = t;
}
-#endif
+}
+/****************************************************************************
+ Process any timeout housekeeping. Return False if the caller should exit.
+****************************************************************************/
- max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
+static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_timeout_processing_time)
+{
+ extern int Client;
+ static time_t last_keepalive_sent_time = 0;
+ static time_t last_idle_closed_check = 0;
+ time_t t;
+ BOOL allidle = True;
+ extern int keepalive;
- /* re-initialise the timezone */
- TimeInit();
+ if (smb_read_error == READ_EOF)
+ {
+ DEBUG(3,("end of file from client\n"));
+ return False;
+ }
- /* if connection on port 445, fake session setup... */
- if(ClientPort == 445)
+ if (smb_read_error == READ_ERROR)
{
- extern fstring remote_machine;
- extern fstring local_machine;
+ DEBUG(3,("receive_smb error (%s) exiting\n",
+ strerror(errno)));
+ return False;
+ }
- fstrcpy(remote_machine, dns_to_netbios_name(client_connection_name()));
- fstrcpy(local_machine, global_myname);
- remote_machine[15] = 0;
- local_machine[15] = 0;
- strlower(remote_machine);
- strlower(local_machine);
+ *last_timeout_processing_time = t = time(NULL);
- DEBUG(2, ("smbd_process(): faking session setup\n"
- "client_name: %s my_name: %s\n", remote_machine, local_machine));
+ if(last_keepalive_sent_time == 0)
+ last_keepalive_sent_time = t;
- add_session_user(remote_machine);
+ if(last_idle_closed_check == 0)
+ last_idle_closed_check = t;
- reload_services(True);
- reopen_logs();
+ /* become root again if waiting */
+ unbecome_user();
- if(lp_status(-1)) {
- claim_connection(NULL,"STATUS.",MAXSTATUS,True);
- }
+ /* check if we need to reload services */
+ check_reload(t);
+
+ /* automatic timeout if all connections are closed */
+ if (conn_num_open()==0 && (t - last_idle_closed_check) >= IDLE_CLOSED_TIMEOUT)
+ {
+ DEBUG( 2, ( "Closing idle connection\n" ) );
+ return False;
}
+ else
+ last_idle_closed_check = t;
+
+ if (keepalive && (t - last_keepalive_sent_time)>keepalive)
+ {
+ if (!send_keepalive(Client)) {
+ DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
+ return False;
+ }
+ DEBUG(0,("TODO: send keepalive to all smbd client-side SMB connections\n"));
+ last_keepalive_sent_time = t;
+ }
+
+ /* check for connection timeouts */
+ allidle = conn_idle_all(t, deadtime);
+
+ if (allidle && conn_num_open()>0) {
+ DEBUG(2,("Closing idle connection 2.\n"));
+ return False;
+ }
+
+ /*
+ * Check to see if we have any blocking locks
+ * outstanding on the queue.
+ */
+ process_blocking_lock_queue(t);
+
+ /*
+ * Check to see if we have any change notifies
+ * outstanding on the queue.
+ */
+ process_pending_change_notify_queue(t);
+
+ /*
+ * Modify the select timeout depending upon
+ * what we have remaining in our queues.
+ */
+
+ *select_timeout = setup_select_timeout();
+
+ return True;
+}
+
+/****************************************************************************
+ process commands from the client
+****************************************************************************/
+
+void smbd_process(void)
+{
+ extern int smb_echo_count;
+ time_t last_timeout_processing_time = time(NULL);
+ unsigned int num_smbs = 0;
+
+ InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
+ OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
+ if ((InBuffer == NULL) || (OutBuffer == NULL))
+ return;
+
+ InBuffer += SMB_ALIGNMENT;
+ OutBuffer += SMB_ALIGNMENT;
+
+ max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
+
+ /* re-initialise the timezone */
+ TimeInit();
while (True)
{
int deadtime = lp_deadtime()*60;
- int counter;
- int last_keepalive=0;
- int service_load_counter = 0;
BOOL got_smb = False;
+ int select_timeout = setup_select_timeout();
if (deadtime <= 0)
deadtime = DEFAULT_SMBD_TIMEOUT;
errno = 0;
- for (counter=SMBD_SELECT_LOOP;
- !receive_message_or_smb(InBuffer,BUFFER_SIZE,
- SMBD_SELECT_LOOP*1000,&got_smb);
- counter += SMBD_SELECT_LOOP)
- {
- time_t t;
- BOOL allidle = True;
- extern int keepalive;
-
- if (counter > 365 * 3600) /* big number of seconds. */
- {
- counter = 0;
- service_load_counter = 0;
- }
-
- if (smb_read_error == READ_EOF)
- {
- DEBUG(3,("end of file from client\n"));
- return;
- }
+ /* free up temporary memory */
+ lp_talloc_free();
- if (smb_read_error == READ_ERROR)
- {
- DEBUG(3,("receive_smb error (%s) exiting\n",
- strerror(errno)));
+ while(!receive_message_or_smb(InBuffer,BUFFER_SIZE,select_timeout,&got_smb))
+ {
+ if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
return;
- }
-
- t = time(NULL);
-
- /* become root again if waiting */
- unbecome_user();
-
- /* check for smb.conf reload */
- if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
- {
- service_load_counter = counter;
-
- /* reload services, if files have changed. */
- reload_services(True);
- }
+ num_smbs = 0; /* Reset smb counter. */
+ }
+ if(got_smb) {
/*
- * If reload_after_sighup == True then we got a SIGHUP
- * and are being asked to reload. Fix from <branko.cibej@hermes.si>
- */
+ * Ensure we do timeout processing if the SMB we just got was
+ * only an echo request. This allows us to set the select
+ * timeout in 'receive_message_or_smb()' to any value we like
+ * without worrying that the client will send echo requests
+ * faster than the select timeout, thus starving out the
+ * essential processing (change notify, blocking locks) that
+ * the timeout code does. JRA.
+ */
+ int num_echos = smb_echo_count;
- if (reload_after_sighup)
- {
- DEBUG(0,("Reloading services after SIGHUP\n"));
- reload_services(False);
- reload_after_sighup = False;
- /*
- * Use this as an excuse to print some stats.
- */
- print_stat_cache_statistics();
- }
-
- /* automatic timeout if all connections are closed */
- if (conn_num_open()==0 && counter >= IDLE_CLOSED_TIMEOUT)
- {
- DEBUG( 2, ( "Closing idle connection\n" ) );
- return;
- }
+ process_smb(InBuffer, OutBuffer);
- if (keepalive && (counter-last_keepalive)>keepalive)
- {
- if (!send_keepalive(Client)) {
- DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
- return;
- }
- last_keepalive = counter;
+ if(smb_echo_count != num_echos) {
+ if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
+ return;
+ num_smbs = 0; /* Reset smb counter. */
}
- /* close down all idle client-side MSRPC connections */
- free_connections();
-
- /* check for connection timeouts */
- allidle = conn_idle_all(t, deadtime);
-
- if (allidle && conn_num_open()>0) {
- DEBUG(2,("Closing idle connection 2.\n"));
- return;
- }
+ num_smbs++;
/*
- * Check to see if we have any blocking locks
- * outstanding on the queue.
+ * If we are getting smb requests in a constant stream
+ * with no echos, make sure we attempt timeout processing
+ * every select_timeout milliseconds - but only check for this
+ * every 200 smb requests.
*/
- process_blocking_lock_queue(t);
- /*
- * Check to see if we have any change notifies
- * outstanding on the queue.
- */
- process_pending_change_notify_queue(t);
+ if((num_smbs % 200) == 0) {
+ time_t new_check_time = time(NULL);
+ if(last_timeout_processing_time - new_check_time >= (select_timeout/1000)) {
+ if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
+ return;
+ num_smbs = 0; /* Reset smb counter. */
+ last_timeout_processing_time = new_check_time; /* Reset time. */
+ }
+ }
}
-
- if(got_smb)
- process_smb(InBuffer, OutBuffer);
else
process_local_message(InBuffer, BUFFER_SIZE);
}
extern BOOL case_preserve;
extern BOOL short_case_preserve;
extern pstring sesssetup_user;
+extern pstring global_myname;
extern fstring global_myworkgroup;
-extern fstring global_myname;
extern int Client;
extern int global_oplock_break;
uint32 global_client_caps = 0;
-
+unsigned int smb_echo_count = 0;
/****************************************************************************
report a possible attack via the password buffer overflow bug
*name1 = *name2 = 0;
- memset(outbuf, 0, smb_size);
+ memset(outbuf, '\0', smb_size);
smb_setlen(outbuf, 0);
if (lp_status(-1))
{
- claim_connection(NULL, "STATUS.", MAXSTATUS,
- True);
+ claim_connection(NULL, "", MAXSTATUS, True);
}
break;
static int connection_error(char *inbuf, char *outbuf, int ecode)
{
if (ecode == ERRnoipc)
- {
return (ERROR(ERRDOS, ERRnoipc));
- }
return (ERROR(ERRSRV, ecode));
}
/****************************************************************************
- reply to a tcon
+ Reply to a tcon.
****************************************************************************/
int reply_tcon(connection_struct * conn,
char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
{
+ BOOL doencrypt = SMBENCRYPT();
pstring service;
pstring user;
pstring password;
parse_connect(smb_buf(inbuf) + 1, service, user, password, &pwlen,
dev);
+ /*
+ * map from DOS codepage format to Unix
+ */
+
+ dos_to_unix(user, True);
+ if (!doencrypt)
+ {
+ dos_to_unix(password, True);
+ }
+
map_nt_and_unix_username(global_myworkgroup, user, user, NULL);
- conn =
- make_connection(service, user, global_myworkgroup, password,
+ conn = make_connection(service, user, global_myworkgroup, password,
pwlen, dev, vuid, &ecode);
if (!conn)
StrnCpy(devicename, path + strlen(path) + 1, 6);
DEBUG(4, ("Got device type %s\n", devicename));
+ /*
+ * map from DOS codepage format to Unix
+ */
+
+ dos_to_unix(user, True);
+ if (!doencrypt)
+ {
+ dos_to_unix(password, True);
+ }
+
map_nt_and_unix_username(global_myworkgroup, user, user, NULL);
- conn =
- make_connection(service, user, global_myworkgroup, password,
+ conn = make_connection(service, user, global_myworkgroup, password,
passlen, devicename, vuid, &ecode);
if (!conn)
/* what does setting this bit do? It is set by NT4 and
may affect the ability to autorun mounted cdroms */
SSVAL(outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS);
+
+ init_dfsroot(conn, inbuf, outbuf);
}
DEBUG(3, ("tconX service=%s user=%s\n", service, user));
int reply_ioctl(connection_struct * conn,
char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
{
- DEBUG(3, ("ignoring ioctl\n"));
-#if 0
- /* we just say it succeeds and hope its all OK.
- some day it would be nice to interpret them individually */
- return set_message(outbuf, 1, 0, True);
-#else
- return (ERROR(ERRSRV, ERRnosupport));
-#endif
+ uint16 device = SVAL(inbuf, smb_vwv1);
+ uint16 function = SVAL(inbuf, smb_vwv2);
+ uint32 ioctl_code = (device << 16) + function;
+ int replysize, outsize;
+ char *p;
+
+ DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
+
+ switch (ioctl_code)
+ {
+ case IOCTL_QUERY_JOB_INFO:
+ replysize = 32;
+ break;
+ default:
+ return (ERROR(ERRSRV, ERRnosupport));
+ }
+
+ outsize = set_message(outbuf, 8, replysize + 1, True);
+ SSVAL(outbuf, smb_vwv1, replysize); /* Total data bytes returned */
+ SSVAL(outbuf, smb_vwv5, replysize); /* Data bytes this buffer */
+ SSVAL(outbuf, smb_vwv6, 52); /* Offset to data */
+ p = smb_buf(outbuf) + 1; /* Allow for alignment */
+
+ switch (ioctl_code)
+ {
+ case IOCTL_QUERY_JOB_INFO:
+ SSVAL(p, 0, 1); /* Job number */
+ StrnCpy(p + 2, global_myname, 15); /* Our NetBIOS name */
+ StrnCpy(p + 18, lp_servicename(SNUM(conn)), 13); /* Service name */
+ break;
+ }
+
+ return outsize;
}
/****************************************************************************
enum remote_arch_types ra_type = get_remote_arch();
char *p = smb_buf(inbuf);
- DEBUG(10,
- ("passlen1: %d passlen2: %d\n", passlen1, passlen2));
-
- global_client_caps = IVAL(inbuf, smb_vwv11);
+ if (global_client_caps == 0)
+ global_client_caps = IVAL(inbuf, smb_vwv11);
/* client_caps is used as final determination if client is NT or Win95.
This is needed to return the correct error codes in some
circumstances.
*/
- if (ra_type == RA_WINNT || ra_type == RA_WIN95)
+ if (ra_type == RA_WINNT || ra_type == RA_WIN2K
+ || ra_type == RA_WIN95)
{
- if (global_client_caps & (CAP_NT_SMBS | CAP_STATUS32))
- set_remote_arch(RA_WINNT);
- else
+ if (!
+ (global_client_caps &
+ (CAP_NT_SMBS | CAP_STATUS32)))
+ {
set_remote_arch(RA_WIN95);
+ }
}
if (passlen1 != 24 && passlen2 <= 24)
smb_ntpasslen = passlen2;
memcpy(smb_ntpasswd, p + passlen1, smb_ntpasslen);
smb_ntpasswd[smb_ntpasslen] = 0;
+
+ /*
+ * Ensure the plaintext passwords are in UNIX format.
+ */
+ if (!doencrypt)
+ {
+ dos_to_unix(smb_apasswd, True);
+ dos_to_unix(smb_ntpasswd, True);
+ }
+
}
else
{
/* we use the first password that they gave */
smb_apasslen = passlen1;
StrnCpy(smb_apasswd, p, smb_apasslen);
+ /*
+ * Ensure the plaintext password is in UNIX format.
+ */
+ dos_to_unix(smb_apasswd, True);
/* trim the password */
smb_apasslen = strlen(smb_apasswd);
fstrcpy(user, p);
p = skip_string(p, 1);
+ /*
+ * Incoming user is in DOS codepage format. Convert
+ * to UNIX.
+ */
+ dos_to_unix(user, True);
domain = p;
DEBUG(3,
}
strlower(user);
+
+ /*
+ * map from DOS codepage format to Unix
+ */
+
+ dos_to_unix(user, True);
+
/*
* In share level security, only overwrite sesssetup_use if
* it's a non null-session share. Helps keep %U and %G
SMB_STRUCT_STAT st;
pstrcpy(name, smb_buf(inbuf) + 1);
- if (!unix_dfs_convert(name, conn, 0, &bad_path, &st))
- {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
- }
+
+ RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
+
+ unix_convert(name, conn, 0, &bad_path, &st);
mode = SVAL(inbuf, smb_vwv0);
if (VALID_STAT(st))
ok = S_ISDIR(st.st_mode);
else
- ok = dos_directory_exist(name, NULL);
+ ok = vfs_directory_exist(conn, name, NULL);
}
if (!ok)
pstrcpy(fname, smb_buf(inbuf) + 1);
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
+ /* if((SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES) && dfs_redirect(fname,conn)) return(dfs_path_error(inbuf,outbuf));
+ */
/* dos smetimes asks for a stat of "" - it returns a "hidden directory"
under WfWg - weird! */
if (!(*fname))
}
else
{
- if (!unix_dfs_convert(fname, conn, 0, &bad_path, &sbuf))
- {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return (ERROR
- (0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
- }
+ unix_convert(fname, conn, 0, &bad_path, &sbuf);
if (check_name(fname, conn))
{
- if (VALID_STAT(sbuf)
- || conn->vfs_ops.stat(dos_to_unix(fname, False),
- &sbuf) == 0)
+ if (VALID_STAT(sbuf) || dos_stat(fname, &sbuf) == 0)
{
mode = dos_mode(conn, fname, &sbuf);
size = sbuf.st_size;
put_dos_date3(outbuf, smb_vwv1, mtime & ~1);
else
put_dos_date3(outbuf, smb_vwv1, mtime);
- SIVAL(outbuf, smb_vwv3, (uint32) size);
+ SIVAL(outbuf, smb_vwv3, (uint32)size);
if (Protocol >= PROTOCOL_NT1)
{
DEBUG(3,
("getatr name=%s mode=%d size=%d\n", fname, mode,
- (uint32) size));
+ (uint32)size));
return (outsize);
}
BOOL bad_path = False;
pstrcpy(fname, smb_buf(inbuf) + 1);
- if (!unix_dfs_convert(fname, conn, 0, &bad_path, &st))
- {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
- }
+ unix_convert(fname, conn, 0, &bad_path, &st);
mode = SVAL(inbuf, smb_vwv0);
mtime = make_unix_date3(inbuf + smb_vwv1);
- if (VALID_STAT_OF_DIR(st) || dos_directory_exist(fname, NULL))
+ if (VALID_STAT_OF_DIR(st) || vfs_directory_exist(conn, fname, NULL))
mode |= aDIR;
if (check_name(fname, conn))
ok = (file_chmod(conn, fname, mode, NULL) == 0);
int outsize = 0;
SMB_BIG_UINT dfree, dsize, bsize;
- conn->vfs_ops.disk_free(".", &bsize, &dfree, &dsize);
+ conn->vfs_ops.disk_free(".", True, &bsize, &dfree, &dsize);
outsize = set_message(outbuf, 5, 0, True);
/* dirtype &= ~aDIR; */
- DEBUG(5, ("path=%s status_len=%d\n", path, status_len));
+ DEBUG(5, ("reply_search: path=%s status_len=%d\n", path, status_len));
if (status_len == 0)
pstrcpy(directory, smb_buf(inbuf) + 1);
pstrcpy(dir2, smb_buf(inbuf) + 1);
- if (!unix_dfs_convert(directory, conn, 0, &bad_path, NULL))
- {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return (ERROR
- (0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
- }
+ unix_convert(directory, conn, 0, &bad_path, NULL);
unix_format(dir2);
if (!check_name(directory, conn))
if (strlen(directory) == 0)
pstrcpy(directory, "./");
- memset(status, 0, 21);
+ memset((char *)status, '\0', 21);
CVAL(status, 0) = dirtype;
}
else
p = mask;
while (*p)
{
- if ((skip = skip_multibyte_char(*p)) != 0)
+ if ((skip = get_character_len(*p)) != 0)
{
p += skip;
}
if (status_len == 0)
{
dptr_num =
- dptr_create(conn, directory, expect_close,
- SVAL(inbuf, smb_pid));
+ dptr_create(conn, directory, True,
+ expect_close, SVAL(inbuf,
+ smb_pid));
if (dptr_num < 0)
{
if (dptr_num == -2)
p += DIR_STRUCT_SIZE;
}
}
- }
+ } /* if (ok ) */
}
{
CVAL(outbuf, smb_rcls) = ERRDOS;
SSVAL(outbuf, smb_err, ERRnofiles);
+ dptr_close(&dptr_num);
}
/* If we were called as SMBffirst with smb_search_id == NULL
CVAL(outbuf, smb_rcls) = ERRDOS;
SSVAL(outbuf, smb_err, ERRnofiles);
/* Also close the dptr - we know it's gone */
- dptr_close(dptr_num);
+ dptr_close(&dptr_num);
}
/* If we were called as SMBfunique, then we can close the dirptr now ! */
if (dptr_num >= 0 && CVAL(inbuf, smb_com) == SMBfunique)
- dptr_close(dptr_num);
+ dptr_close(&dptr_num);
SSVAL(outbuf, smb_vwv0, numentries);
SSVAL(outbuf, smb_vwv1, 3 + numentries * DIR_STRUCT_SIZE);
int status_len;
char *path;
char status[21];
- int dptr_num = -1;
+ int dptr_num = -2;
outsize = set_message(outbuf, 1, 0, True);
path = smb_buf(inbuf) + 1;
if (dptr_fetch(status + 12, &dptr_num))
{
/* Close the dptr - we know it's gone */
- dptr_close(dptr_num);
+ dptr_close(&dptr_num);
}
SSVAL(outbuf, smb_vwv0, 0);
share_mode = SVAL(inbuf, smb_vwv0);
pstrcpy(fname, smb_buf(inbuf) + 1);
- if (!unix_dfs_convert(fname, conn, 0, &bad_path, NULL))
- {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
- }
+
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
+ unix_convert(fname, conn, 0, &bad_path, NULL);
fsp = file_new();
if (!fsp)
return (UNIXERROR(ERRDOS, ERRnoaccess));
}
- unixmode = unix_mode(conn, aARCH);
+ unixmode = unix_mode(conn, aARCH, fname);
open_file_shared(fsp, conn, fname, share_mode,
(FILE_FAIL_IF_NOT_EXIST | FILE_EXISTS_OPEN),
put_dos_date3(outbuf, smb_vwv2, mtime & ~1);
else
put_dos_date3(outbuf, smb_vwv2, mtime);
- SIVAL(outbuf, smb_vwv4, (uint32) size);
+ SIVAL(outbuf, smb_vwv4, (uint32)size);
SSVAL(outbuf, smb_vwv6, rmode);
if (oplock_request && lp_fake_oplocks(SNUM(conn)))
CVAL(outbuf, smb_flg) |= CORE_OPLOCK_GRANTED;
}
- if (fsp->granted_oplock)
+ if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
CVAL(outbuf, smb_flg) |= CORE_OPLOCK_GRANTED;
return (outsize);
}
files_struct *fsp;
/* If it's an IPC, pass off the pipe handler. */
- if (IS_IPC(conn) && lp_nt_pipe_support()
- && lp_security() != SEC_SHARE)
- {
+ if (IS_IPC(conn) && lp_nt_pipe_support())
return reply_open_pipe_and_X(conn, inbuf, outbuf, length,
bufsize);
- }
/* XXXX we need to handle passed times, sattr and flags */
pstrcpy(fname, smb_buf(inbuf));
- if (!unix_dfs_convert(fname, conn, 0, &bad_path, NULL))
- {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
- }
+
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
+ unix_convert(fname, conn, 0, &bad_path, NULL);
fsp = file_new();
if (!fsp)
return (UNIXERROR(ERRDOS, ERRnoaccess));
}
- unixmode = unix_mode(conn, smb_attr | aARCH);
+ unixmode = unix_mode(conn, smb_attr | aARCH, fname);
open_file_shared(fsp, conn, fname, smb_mode, smb_ofun, unixmode,
oplock_request, &rmode, &smb_action);
smb_action |= EXTENDED_OPLOCK_GRANTED;
}
- if (ex_oplock_request && fsp->granted_oplock)
+ if (ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
{
smb_action |= EXTENDED_OPLOCK_GRANTED;
}
CVAL(outbuf, smb_flg) |= CORE_OPLOCK_GRANTED;
}
- if (core_oplock_request && fsp->granted_oplock)
+ if (core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
{
CVAL(outbuf, smb_flg) |= CORE_OPLOCK_GRANTED;
}
put_dos_date3(outbuf, smb_vwv4, mtime & ~1);
else
put_dos_date3(outbuf, smb_vwv4, mtime);
- SIVAL(outbuf, smb_vwv6, (uint32) size);
+ SIVAL(outbuf, smb_vwv6, (uint32)size);
SSVAL(outbuf, smb_vwv8, rmode);
SSVAL(outbuf, smb_vwv11, smb_action);
createmode = SVAL(inbuf, smb_vwv0);
pstrcpy(fname, smb_buf(inbuf) + 1);
- if (!unix_dfs_convert(fname, conn, 0, &bad_path, NULL))
- {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
- }
+
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
+ unix_convert(fname, conn, 0, &bad_path, NULL);
if (createmode & aVOLID)
{
fname));
}
- unixmode = unix_mode(conn, createmode);
+ unixmode = unix_mode(conn, createmode, fname);
fsp = file_new();
if (!fsp)
if (com == SMBmknew)
{
/* We should fail if file exists. */
- ofun = 0x10;
+ ofun = FILE_CREATE_IF_NOT_EXIST;
}
else
{
/* SMBcreate - Create if file doesn't exist, truncate if it does. */
- ofun = 0x12;
+ ofun = FILE_CREATE_IF_NOT_EXIST | FILE_EXISTS_TRUNCATE;
}
/* Open file in dos compatibility share mode. */
CVAL(outbuf, smb_flg) |= CORE_OPLOCK_GRANTED;
}
- if (fsp->granted_oplock)
+ if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
CVAL(outbuf, smb_flg) |= CORE_OPLOCK_GRANTED;
DEBUG(2, ("new file %s\n", fname));
createmode = SVAL(inbuf, smb_vwv0);
pstrcpy(fname, smb_buf(inbuf) + 1);
pstrcat(fname, "/TMXXXXXX");
- if (!unix_dfs_convert(fname, conn, 0, &bad_path, NULL))
- {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
- }
- unixmode = unix_mode(conn, createmode);
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
+ unix_convert(fname, conn, 0, &bad_path, NULL);
+
+ unixmode = unix_mode(conn, createmode, fname);
fsp = file_new();
if (fsp)
return (UNIXERROR(ERRDOS, ERRnoaccess));
}
- pstrcpy(fname2, (char *)mktemp(fname));
+ pstrcpy(fname2, (char *)smbd_mktemp(fname));
/* Open file in dos compatibility share mode. */
/* We should fail if file exists. */
CVAL(outbuf, smb_flg) |= CORE_OPLOCK_GRANTED;
}
- if (fsp->granted_oplock)
+ if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
CVAL(outbuf, smb_flg) |= CORE_OPLOCK_GRANTED;
DEBUG(2, ("created temp file %s\n", fname2));
}
/****************************************************************************
- reply to a unlink
+ Reply to a unlink
****************************************************************************/
int reply_unlink(connection_struct * conn, char *inbuf, char *outbuf,
int dum_size, int dum_buffsize)
BOOL has_wild;
BOOL exists = False;
BOOL bad_path = False;
+ BOOL rc = True;
*directory = *mask = 0;
pstrcpy(name, smb_buf(inbuf) + 1);
+ RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
+
DEBUG(3, ("reply_unlink : %s\n", name));
- if (!unix_dfs_convert(name, conn, 0, &bad_path, NULL))
- {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
- }
+ rc = unix_convert(name, conn, 0, &bad_path, NULL);
p = strrchr(name, '/');
if (!p)
pstrcpy(mask, p + 1);
}
- if (is_mangled(mask))
+ /*
+ * We should only check the mangled cache
+ * here if unix_convert failed. This means
+ * that the path in 'mask' doesn't exist
+ * on the file system and so we need to look
+ * for a possible mangle. This patch from
+ * Tine Smukavec <valentin.smukavec@hermes.si>.
+ */
+
+ if (!rc && is_mangled(mask))
check_mangled_cache(mask);
has_wild = strchr(mask, '*') || strchr(mask, '?');
{
pstrcat(directory, "/");
pstrcat(directory, mask);
- if (can_delete(directory, conn, dirtype) &&
- !conn->vfs_ops.unlink(dos_to_unix(directory, False)))
+ if (can_delete(directory, conn, dirtype)
+ && !dos_unlink(directory))
count++;
if (!count)
- exists =
- vfs_file_exist(conn,
- dos_to_unix(directory, False),
- NULL);
+ exists = vfs_file_exist(conn, directory, NULL);
}
else
{
directory, dname);
if (!can_delete(fname, conn, dirtype))
continue;
- if (!conn->vfs_ops.
- unlink(dos_to_unix(fname, False)))
- count++;
+ if (!conn->
+ vfs_ops.unlink(dos_to_unix(fname, False)))
+ count++;
DEBUG(3,
("reply_unlink : doing unlink on %s\n",
fname));
fsp = file_fsp(inbuf, smb_vwv0);
+ if (!FNUM_OK(fsp, conn) || !fsp->can_read)
+ {
+ /*
+ * fsp could be NULL here so use the value from the packet. JRA.
+ */
+ DEBUG(3,
+ ("fnum %d not open in readbraw - cache prime?\n",
+ (int)SVAL(inbuf, smb_vwv0)));
+ _smb_setlen(header, 0);
+ transfer_file(0, Client, (SMB_OFF_T) 0, header, 4, 0);
+ return (-1);
+ }
+
+ CHECK_FSP(fsp, conn);
+
+ flush_write_cache(fsp, READRAW_FLUSH);
+
startpos = IVAL(inbuf, smb_vwv1);
-#ifdef LARGE_SMB_OFF_T
if (CVAL(inbuf, smb_wct) == 10)
{
/*
* This is a large offset (64 bit) read.
*/
+#ifdef LARGE_SMB_OFF_T
+
startpos |= (((SMB_OFF_T) IVAL(inbuf, smb_vwv8)) << 32);
+
+#else /* !LARGE_SMB_OFF_T */
+
+ /*
+ * Ensure we haven't been sent a >32 bit offset.
+ */
+
+ if (IVAL(inbuf, smb_vwv8) != 0)
+ {
+ DEBUG(0,
+ ("readbraw - large offset (%x << 32) used and we don't support \
+64 bit offsets.\n",
+ (unsigned int)IVAL(inbuf, smb_vwv8)));
+ _smb_setlen(header, 0);
+ transfer_file(0, Client, (SMB_OFF_T) 0, header, 4, 0);
+ return (-1);
+ }
+
+#endif /* LARGE_SMB_OFF_T */
+
if (startpos < 0)
{
DEBUG(0,
return (-1);
}
}
-#endif /* LARGE_SMB_OFF_T */
maxcount = (SVAL(inbuf, smb_vwv3) & 0xFFFF);
mincount = (SVAL(inbuf, smb_vwv4) & 0xFFFF);
maxcount = MIN(65535, maxcount);
maxcount = MAX(mincount, maxcount);
- if (!FNUM_OK(fsp, conn) || !fsp->can_read)
- {
- DEBUG(3,
- ("fnum %d not open in readbraw - cache prime?\n",
- fsp->fnum));
- _smb_setlen(header, 0);
- transfer_file(0, Client, (SMB_OFF_T) 0, header, 4, 0);
- return (-1);
- }
-
- if (!is_locked(fsp, conn, maxcount, startpos, F_RDLCK))
+ if (!is_locked(fsp, conn, maxcount, startpos, READ_LOCK))
{
SMB_OFF_T size = fsp->size;
SMB_OFF_T sizeneeded = startpos + maxcount;
nread = 0;
DEBUG(3, ("readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n",
- fsp->fnum, (double)startpos, maxcount, mincount, nread));
+ fsp->fnum, (double)startpos,
+ (int)maxcount, (int)mincount, (int)nread));
#if UNSAFE_READRAW
{
numtoread = MIN(BUFFER_SIZE - outsize, numtoread);
data = smb_buf(outbuf) + 3;
+ /*
+ * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
+ * protocol request that predates the read/write lock concept.
+ * Thus instead of asking for a read lock here we need to ask
+ * for a write lock. JRA.
+ */
+
if (!do_lock
- (fsp, conn, numtoread, startpos, F_RDLCK, &eclass, &ecode))
+ (fsp, conn, numtoread, startpos, WRITE_LOCK, &eclass, &ecode))
{
if ((ecode == ERRlock) && lp_blocking_locks(SNUM(conn)))
{
SSVAL(smb_buf(outbuf), 1, nread);
DEBUG(3, ("lockread fnum=%d num=%d nread=%d\n",
- fsp->fnum, numtoread, nread));
+ fsp->fnum, (int)numtoread, (int)nread));
return (outsize);
}
/****************************************************************************
reply to a read
****************************************************************************/
-int reply_read(connection_struct * conn, char *inbuf, char *outbuf,
- int dum_size, int dum_buffsize)
+
+int reply_read(connection_struct * conn, char *inbuf, char *outbuf, int size,
+ int dum_buffsize)
{
size_t numtoread;
ssize_t nread = 0;
numtoread = MIN(BUFFER_SIZE - outsize, numtoread);
data = smb_buf(outbuf) + 3;
- if (is_locked(fsp, conn, numtoread, startpos, F_RDLCK))
+ if (is_locked(fsp, conn, numtoread, startpos, READ_LOCK))
return (ERROR(ERRDOS, ERRlock));
if (numtoread > 0)
- {
nread = read_file(fsp, data, startpos, numtoread);
- }
if (nread < 0)
return (UNIXERROR(ERRDOS, ERRnoaccess));
SSVAL(smb_buf(outbuf), 1, nread);
DEBUG(3, ("read fnum=%d num=%d nread=%d\n",
- fsp->fnum, numtoread, nread));
+ fsp->fnum, (int)numtoread, (int)nread));
return (outsize);
}
set_message(outbuf, 12, 0, True);
data = smb_buf(outbuf);
-#ifdef LARGE_SMB_OFF_T
if (CVAL(inbuf, smb_wct) == 12)
{
+#ifdef LARGE_SMB_OFF_T
/*
* This is a large offset (64 bit) read.
*/
startpos |= (((SMB_OFF_T) IVAL(inbuf, smb_vwv10)) << 32);
- }
+
+#else /* !LARGE_SMB_OFF_T */
+
+ /*
+ * Ensure we haven't been sent a >32 bit offset.
+ */
+
+ if (IVAL(inbuf, smb_vwv10) != 0)
+ {
+ DEBUG(0,
+ ("reply_read_and_X - large offset (%x << 32) used and we don't support \
+64 bit offsets.\n",
+ (unsigned int)IVAL(inbuf, smb_vwv10)));
+ return (ERROR(ERRDOS, ERRbadaccess));
+ }
#endif /* LARGE_SMB_OFF_T */
- if (is_locked(fsp, conn, smb_maxcnt, startpos, F_RDLCK))
+ }
+
+ if (is_locked(fsp, conn, smb_maxcnt, startpos, READ_LOCK))
return (ERROR(ERRDOS, ERRlock));
nread = read_file(fsp, data, startpos, smb_maxcnt);
SSVAL(smb_buf(outbuf), -2, nread);
DEBUG(3, ("readX fnum=%d min=%d max=%d nread=%d\n",
- fsp->fnum, smb_mincnt, smb_maxcnt, nread));
+ fsp->fnum, (int)smb_mincnt, (int)smb_maxcnt, (int)nread));
return chain_reply(inbuf, outbuf, length, bufsize);
}
reply to a writebraw (core+ or LANMAN1.0 protocol)
****************************************************************************/
int reply_writebraw(connection_struct * conn, char *inbuf, char *outbuf,
- int dum_size, int dum_buffsize)
+ int size, int dum_buffsize)
{
ssize_t nwritten = 0;
ssize_t total_written = 0;
CVAL(inbuf, smb_com) = SMBwritec;
CVAL(outbuf, smb_com) = SMBwritec;
- if (is_locked(fsp, conn, tcount, startpos, F_WRLCK))
+ if (is_locked(fsp, conn, tcount, startpos, WRITE_LOCK))
return (ERROR(ERRDOS, ERRlock));
- if (seek_file(fsp, startpos) == -1)
- {
- DEBUG(0,
- ("couldn't seek to %.0f in writebraw\n",
- (double)startpos));
- return (UNIXERROR(ERRDOS, ERRnoaccess));
- }
-
if (numtowrite > 0)
- nwritten = write_file(fsp, data, numtowrite);
+ nwritten = write_file(fsp, data, startpos, numtowrite);
DEBUG(3, ("writebraw1 fnum=%d start=%.0f num=%d wrote=%d sync=%d\n",
- fsp->fnum, (double)startpos, numtowrite, nwritten,
- write_through));
+ fsp->fnum, (double)startpos, (int)numtowrite, (int)nwritten,
+ (int)write_through));
if (nwritten < numtowrite)
return (UNIXERROR(ERRHRD, ERRdiskfull));
if (tcount > nwritten + numtowrite)
{
DEBUG(3, ("Client overestimated the write %d %d %d\n",
- tcount, nwritten, numtowrite));
+ (int)tcount, (int)nwritten, (int)numtowrite));
}
nwritten = vfs_transfer_file(Client, NULL, -1, fsp,
if ((lp_syncalways(SNUM(conn)) || write_through) &&
lp_strict_sync(SNUM(conn)))
- conn->vfs_ops.sync(fsp->fd_ptr->fd);
+ conn->vfs_ops.fsync(fsp->fd_ptr->fd);
DEBUG(3, ("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n",
- fsp->fnum, (double)startpos, numtowrite, total_written));
+ fsp->fnum, (double)startpos, (int)numtowrite,
+ (int)total_written));
/* we won't return a status if write through is not selected - this
follows what WfWg does */
reply to a writeunlock (core+)
****************************************************************************/
int reply_writeunlock(connection_struct * conn, char *inbuf, char *outbuf,
- int dum_size, int dum_buffsize)
+ int size, int dum_buffsize)
{
ssize_t nwritten = -1;
size_t numtowrite;
startpos = IVAL(inbuf, smb_vwv2);
data = smb_buf(inbuf) + 3;
- if (is_locked(fsp, conn, numtowrite, startpos, F_WRLCK))
+ if (is_locked(fsp, conn, numtowrite, startpos, WRITE_LOCK))
return (ERROR(ERRDOS, ERRlock));
- if (seek_file(fsp, startpos) == -1)
- return (UNIXERROR(ERRDOS, ERRnoaccess));
-
/* The special X/Open SMB protocol handling of
zero length writes is *NOT* done for
this call */
if (numtowrite == 0)
nwritten = 0;
else
- nwritten = write_file(fsp, data, numtowrite);
+ nwritten = write_file(fsp, data, startpos, numtowrite);
- if (lp_syncalways(SNUM(conn)) && lp_strict_sync(SNUM(conn)))
- conn->vfs_ops.sync(fsp->fd_ptr->fd);
+ if (lp_syncalways(SNUM(conn)))
+ conn->vfs_ops.fsync(fsp->fd_ptr->fd);
if (((nwritten == 0) && (numtowrite != 0)) || (nwritten < 0))
return (UNIXERROR(ERRDOS, ERRnoaccess));
SSVAL(outbuf, smb_vwv0, nwritten);
DEBUG(3, ("writeunlock fnum=%d num=%d wrote=%d\n",
- fsp->fnum, numtowrite, nwritten));
+ fsp->fnum, (int)numtowrite, (int)nwritten));
return (outsize);
}
/****************************************************************************
reply to a write
****************************************************************************/
-int reply_write(connection_struct * conn, char *inbuf, char *outbuf,
- int dum_size, int dum_buffsize)
+int reply_write(connection_struct * conn, char *inbuf, char *outbuf, int size,
+ int dum_buffsize)
{
size_t numtowrite;
ssize_t nwritten = -1;
/* If it's an IPC, pass off the pipe handler. */
if (IS_IPC(conn))
- return reply_pipe_write(inbuf, outbuf, dum_size,
- dum_buffsize);
+ return reply_pipe_write(inbuf, outbuf, size, dum_buffsize);
CHECK_FSP(fsp, conn);
CHECK_WRITE(fsp);
startpos = IVAL(inbuf, smb_vwv2);
data = smb_buf(inbuf) + 3;
- if (is_locked(fsp, conn, numtowrite, startpos, F_WRLCK))
+ if (is_locked(fsp, conn, numtowrite, startpos, WRITE_LOCK))
return (ERROR(ERRDOS, ERRlock));
- if (seek_file(fsp, startpos) == -1)
- return (UNIXERROR(ERRDOS, ERRnoaccess));
-
/* X/Open SMB protocol says that if smb_vwv1 is
zero then the file size should be extended or
truncated to the size given in smb_vwv[2-3] */
if (numtowrite == 0)
- nwritten = set_filelen(fsp->fd_ptr->fd, (SMB_OFF_T) startpos);
+ {
+ if (
+ (nwritten =
+ set_filelen(fsp->fd_ptr->fd, (SMB_OFF_T) startpos)) >= 0) /* tpot vfs */
+ set_filelen_write_cache(fsp, startpos);
+ }
else
- nwritten = write_file(fsp, data, numtowrite);
+ nwritten = write_file(fsp, data, startpos, numtowrite);
- if (lp_syncalways(SNUM(conn)) && lp_strict_sync(SNUM(conn)))
- conn->vfs_ops.sync(fsp->fd_ptr->fd);
+ if (lp_syncalways(SNUM(conn)))
+ conn->vfs_ops.fsync(fsp->fd_ptr->fd);
if (((nwritten == 0) && (numtowrite != 0)) || (nwritten < 0))
return (UNIXERROR(ERRDOS, ERRnoaccess));
}
DEBUG(3, ("write fnum=%d num=%d wrote=%d\n",
- fsp->fnum, numtowrite, nwritten));
+ fsp->fnum, (int)numtowrite, (int)nwritten));
return (outsize);
}
data = smb_base(inbuf) + smb_doff;
-#ifdef LARGE_SMB_OFF_T
if (CVAL(inbuf, smb_wct) == 14)
{
+#ifdef LARGE_SMB_OFF_T
/*
* This is a large offset (64 bit) write.
*/
startpos |= (((SMB_OFF_T) IVAL(inbuf, smb_vwv12)) << 32);
- }
+
+#else /* !LARGE_SMB_OFF_T */
+
+ /*
+ * Ensure we haven't been sent a >32 bit offset.
+ */
+
+ if (IVAL(inbuf, smb_vwv12) != 0)
+ {
+ DEBUG(0,
+ ("reply_write_and_X - large offset (%x << 32) used and we don't support \
+64 bit offsets.\n",
+ (unsigned int)IVAL(inbuf, smb_vwv12)));
+ return (ERROR(ERRDOS, ERRbadaccess));
+ }
#endif /* LARGE_SMB_OFF_T */
+ }
- if (is_locked(fsp, conn, numtowrite, startpos, F_WRLCK))
+ if (is_locked(fsp, conn, numtowrite, startpos, WRITE_LOCK))
return (ERROR(ERRDOS, ERRlock));
- if (seek_file(fsp, startpos) == -1)
- return (UNIXERROR(ERRDOS, ERRnoaccess));
-
/* X/Open SMB protocol says that, unlike SMBwrite
if the length is zero then NO truncation is
done, just a write of zero. To truncate a file,
if (numtowrite == 0)
nwritten = 0;
else
- nwritten = write_file(fsp, data, numtowrite);
+ nwritten = write_file(fsp, data, startpos, numtowrite);
if (((nwritten == 0) && (numtowrite != 0)) || (nwritten < 0))
return (UNIXERROR(ERRDOS, ERRnoaccess));
}
DEBUG(3, ("writeX fnum=%d num=%d wrote=%d\n",
- fsp->fnum, numtowrite, nwritten));
+ fsp->fnum, (int)numtowrite, (int)nwritten));
- if ((lp_syncalways(SNUM(conn)) || write_through) &&
- lp_strict_sync(SNUM(conn)))
- conn->vfs_ops.sync(fsp->fd_ptr->fd);
+ if (lp_syncalways(SNUM(conn)) || write_through)
+ conn->vfs_ops.fsync(fsp->fd_ptr->fd);
return chain_reply(inbuf, outbuf, length, bufsize);
}
/****************************************************************************
reply to a lseek
****************************************************************************/
-int reply_lseek(connection_struct * conn, char *inbuf, char *outbuf,
- int dum_size, int dum_buffsize)
+
+int reply_lseek(connection_struct * conn, char *inbuf, char *outbuf, int size,
+ int dum_buffsize)
{
SMB_OFF_T startpos;
SMB_OFF_T res = -1;
CHECK_FSP(fsp, conn);
CHECK_ERROR(fsp);
+ flush_write_cache(fsp, SEEK_FLUSH);
+
mode = SVAL(inbuf, smb_vwv1) & 3;
- startpos = IVAL(inbuf, smb_vwv2);
+ startpos = IVALS(inbuf, smb_vwv2);
- switch (mode & 3)
+ switch (mode)
{
case 0:
umode = SEEK_SET;
if ((res = conn->vfs_ops.lseek(fsp->fd_ptr->fd, startpos, umode)) ==
-1)
- return (UNIXERROR(ERRDOS, ERRnoaccess));
+ {
+ /*
+ * Check for the special case where a seek before the start
+ * of the file sets the offset to zero. Added in the CIFS spec,
+ * section 4.2.7.
+ */
+
+ if (errno == EINVAL)
+ {
+ SMB_OFF_T current_pos = startpos;
+
+ if (umode == SEEK_CUR)
+ {
+
+ if (
+ (current_pos =
+ conn->vfs_ops.lseek(fsp->fd_ptr->fd, 0,
+ SEEK_CUR)) == -1)
+ return (UNIXERROR
+ (ERRDOS, ERRnoaccess));
+
+ current_pos += startpos;
+
+ }
+ else if (umode == SEEK_END)
+ {
+
+ SMB_STRUCT_STAT sbuf;
+
+ if (conn->
+ vfs_ops.fstat(fsp->fd_ptr->fd,
+ &sbuf) == -1)
+ return (UNIXERROR
+ (ERRDOS, ERRnoaccess));
+
+ current_pos += sbuf.st_size;
+ }
+
+ if (current_pos < 0)
+ res =
+ conn->vfs_ops.lseek(fsp->fd_ptr->fd,
+ 0, SEEK_SET);
+ }
+
+ if (res == -1)
+ return (UNIXERROR(ERRDOS, ERRnoaccess));
+ }
fsp->pos = res;
outsize = set_message(outbuf, 2, 0, True);
- SIVALS(outbuf, smb_vwv0, res);
+ SIVAL(outbuf, smb_vwv0, res);
- DEBUG(3, ("lseek fnum=%d ofs=%.0f mode=%d\n",
- fsp->fnum, (double)startpos, mode));
+ DEBUG(3, ("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
+ fsp->fnum, (double)startpos, (double)res, mode));
return (outsize);
}
/****************************************************************************
reply to a flush
****************************************************************************/
-int reply_flush(connection_struct * conn, char *inbuf, char *outbuf,
- int dum_size, int dum_buffsize)
+
+int reply_flush(connection_struct * conn, char *inbuf, char *outbuf, int size,
+ int dum_buffsize)
{
int outsize = set_message(outbuf, 0, 0, True);
files_struct *fsp = file_fsp(inbuf, smb_vwv0);
}
else
{
- conn->vfs_ops.sync(fsp->fd_ptr->fd);
+ conn->vfs_ops.fsync(fsp->fd_ptr->fd);
}
DEBUG(3, ("flush\n"));
/****************************************************************************
Reply to a close - has to deal with closing a directory opened by NT SMB's.
****************************************************************************/
-int reply_close(connection_struct * conn,
- char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
+int reply_close(connection_struct * conn, char *inbuf, char *outbuf, int size,
+ int dum_buffsize)
{
int outsize = 0;
time_t mtime;
/* If it's an IPC, pass off to the pipe handler. */
if (IS_IPC(conn))
- {
return reply_pipe_close(conn, inbuf, outbuf);
- }
fsp = file_fsp(inbuf, smb_vwv0);
err = fsp->wbmpx_ptr->wr_error;
}
- if (fsp->is_directory)
+ if (fsp->is_directory || fsp->stat_open)
{
/*
- * Special case - close NT SMB directory
+ * Special case - close NT SMB directory or stat file
* handle.
*/
- DEBUG(3, ("close directory fnum=%d\n", fsp->fnum));
- close_directory(fsp);
+ DEBUG(3,
+ ("close %s fnum=%d\n",
+ fsp->is_directory ? "directory" : "stat file open",
+ fsp->fnum));
+ close_file(fsp, True);
}
else
{
/*
* Close ordinary file.
*/
+ int close_err;
/*
* If there was a modify time outstanding,
set_filetime(conn, fsp->fsp_name, mtime);
DEBUG(3, ("close fd=%d fnum=%d (numopen=%d)\n",
- fsp->fd_ptr->fd, fsp->fnum, conn->num_files_open));
+ fsp->fd_ptr ? fsp->fd_ptr->fd : -1, fsp->fnum,
+ conn->num_files_open));
- close_file(fsp, True);
+ /*
+ * close_file() returns the unix errno if an error
+ * was detected on close - normally this is due to
+ * a disk full error. If not then it was probably an I/O error.
+ */
+
+ if ((close_err = close_file(fsp, True)) != 0)
+ {
+ errno = close_err;
+ return (UNIXERROR(ERRHRD, ERRgeneral));
+ }
}
/* We have a cached error */
reply to a writeclose (Core+ protocol)
****************************************************************************/
int reply_writeclose(connection_struct * conn,
- char *inbuf, char *outbuf, int dum_size,
- int dum_buffsize)
+ char *inbuf, char *outbuf, int size, int dum_buffsize)
{
size_t numtowrite;
ssize_t nwritten = -1;
int outsize = 0;
+ int close_err = 0;
SMB_OFF_T startpos;
char *data;
time_t mtime;
mtime = make_unix_date3(inbuf + smb_vwv4);
data = smb_buf(inbuf) + 1;
- if (is_locked(fsp, conn, numtowrite, startpos, F_WRLCK))
+ if (is_locked(fsp, conn, numtowrite, startpos, WRITE_LOCK))
return (ERROR(ERRDOS, ERRlock));
- if (seek_file(fsp, startpos) == -1)
- return (UNIXERROR(ERRDOS, ERRnoaccess));
-
- nwritten = write_file(fsp, data, numtowrite);
+ nwritten = write_file(fsp, data, startpos, numtowrite);
set_filetime(conn, fsp->fsp_name, mtime);
- close_file(fsp, True);
+ close_err = close_file(fsp, True);
DEBUG(3, ("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
- fsp->fnum, numtowrite, nwritten, conn->num_files_open));
+ fsp->fnum, (int)numtowrite, (int)nwritten,
+ conn->num_files_open));
if (nwritten <= 0)
return (UNIXERROR(ERRDOS, ERRnoaccess));
+ if (close_err != 0)
+ {
+ errno = close_err;
+ return (UNIXERROR(ERRHRD, ERRgeneral));
+ }
+
outsize = set_message(outbuf, 1, 0, True);
SSVAL(outbuf, smb_vwv0, nwritten);
DEBUG(3, ("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
fsp->fd_ptr->fd, fsp->fnum, (double)offset, (double)count));
- if (!do_lock(fsp, conn, count, offset, F_WRLCK, &eclass, &ecode))
+ if (!do_lock(fsp, conn, count, offset, WRITE_LOCK, &eclass, &ecode))
{
if ((ecode == ERRlock) && lp_blocking_locks(SNUM(conn)))
{
reply to a unlock
****************************************************************************/
int reply_unlock(connection_struct * conn, char *inbuf, char *outbuf,
- int dum_size, int dum_buffsize)
+ int size, int dum_buffsize)
{
int outsize = set_message(outbuf, 0, 0, True);
SMB_OFF_T count, offset;
DEBUG(3, ("echo %d times\n", smb_reverb));
+ smb_echo_count++;
+
return -1;
}
if (!fsp)
return (ERROR(ERRSRV, ERRnofids));
- pstrcpy(fname2, (char *)mktemp(fname));
+ pstrcpy(fname2, (char *)smbd_mktemp(fname));
if (!check_name(fname2, conn))
{
SET_DENY_MODE(DENY_ALL) |
SET_OPEN_MODE(DOS_OPEN_WRONLY),
(FILE_CREATE_IF_NOT_EXIST | FILE_EXISTS_FAIL),
- unix_mode(conn, 0), 0, NULL, NULL);
+ unix_mode(conn, 0, fname2), 0, NULL, NULL);
if (!fsp->open)
{
{
int outsize = set_message(outbuf, 0, 0, True);
files_struct *fsp = file_fsp(inbuf, smb_vwv0);
+ int close_err = 0;
CHECK_FSP(fsp, conn);
CHECK_ERROR(fsp);
DEBUG(3, ("printclose fd=%d fnum=%d\n", fsp->fd_ptr->fd, fsp->fnum));
- close_file(fsp, True);
+ close_err = close_file(fsp, True);
+
+ if (close_err != 0)
+ {
+ errno = close_err;
+ return (UNIXERROR(ERRHRD, ERRgeneral));
+ }
return (outsize);
}
int max_count = SVAL(inbuf, smb_vwv0);
int start_index = SVAL(inbuf, smb_vwv1);
uint16 vuid = SVAL(inbuf, smb_uid);
- VUSER_KEY;
+ vuser_key key;
+ key.pid = conn != NULL ? conn->smbd_pid : getpid();
+ key.vuid = vuid;
/* we used to allow the client to get the cnum wrong, but that
is really quite gross and only worked when there was only
numtowrite = SVAL(smb_buf(inbuf), 1);
data = smb_buf(inbuf) + 3;
- if (write_file(fsp, data, numtowrite) != numtowrite)
+ if (write_file(fsp, data, -1, numtowrite) != numtowrite)
return (UNIXERROR(ERRDOS, ERRnoaccess));
DEBUG(3, ("printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite));
BOOL bad_path = False;
pstrcpy(directory, smb_buf(inbuf) + 1);
- if (!unix_dfs_convert(directory, conn, 0, &bad_path, NULL))
- {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
- }
+ unix_convert(directory, conn, 0, &bad_path, NULL);
if (check_name(directory, conn))
ret = conn->vfs_ops.mkdir(dos_to_unix(directory, False),
- unix_mode(conn, aDIR));
+ unix_mode(conn, aDIR, directory));
if (ret < 0)
{
{
char *dname = NULL;
BOOL ret = False;
- void *dirptr = OpenDir(conn, directory, False);
+ void *dirptr = OpenDir(NULL, directory, False);
if (dirptr == NULL)
return True;
ret = True;
break;
}
- if (conn->vfs_ops.
- rmdir(dos_to_unix(fullname, False)) != 0)
+ if (conn->
+ vfs_ops.rmdir(dos_to_unix(fullname, False)) != 0)
{
ret = True;
break;
}
/****************************************************************************
- reply to a rmdir
+ The internals of the rmdir code - called elsewhere.
****************************************************************************/
-int reply_rmdir(connection_struct * conn, char *inbuf, char *outbuf,
- int dum_size, int dum_buffsize)
+
+BOOL rmdir_internals(connection_struct * conn, char *directory)
{
- pstring directory;
- int outsize = 0;
- BOOL ok = False;
- BOOL bad_path = False;
+ BOOL ok;
- pstrcpy(directory, smb_buf(inbuf) + 1);
- if (!unix_dfs_convert(directory, conn, NULL, &bad_path, NULL))
- {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
- }
-
- if (check_name(directory, conn))
+ ok = (conn->vfs_ops.rmdir(dos_to_unix(directory, False)) == 0);
+ if (!ok && ((errno == ENOTEMPTY) || (errno == EEXIST))
+ && lp_veto_files(SNUM(conn)))
{
+ /*
+ * Check to see if the only thing in this directory are
+ * vetoed files/directories. If so then delete them and
+ * retry. If we fail to delete any of them (and we *don't*
+ * do a recursive delete) then fail the rmdir.
+ */
+ BOOL all_veto_files = True;
+ char *dname;
+ void *dirptr = OpenDir(conn, directory, False);
- dptr_closepath(directory, SVAL(inbuf, smb_pid));
- ok =
- (conn->vfs_ops.rmdir(dos_to_unix(directory, False)) ==
- 0);
- if (!ok && (errno == ENOTEMPTY) && lp_veto_files(SNUM(conn)))
+ if (dirptr != NULL)
{
- /* Check to see if the only thing in this directory are
- vetoed files/directories. If so then delete them and
- retry. If we fail to delete any of them (and we *don't*
- do a recursive delete) then fail the rmdir. */
- BOOL all_veto_files = True;
- char *dname;
- void *dirptr = OpenDir(conn, directory, False);
-
- if (dirptr != NULL)
+ int dirpos = TellDir(dirptr);
+ while ((dname = ReadDirName(dirptr)))
{
- int dirpos = TellDir(dirptr);
+ if ((strcmp(dname, ".") == 0)
+ || (strcmp(dname, "..") == 0))
+ continue;
+ if (!IS_VETO_PATH(conn, dname))
+ {
+ all_veto_files = False;
+ break;
+ }
+ }
+ if (all_veto_files)
+ {
+ SeekDir(dirptr, dirpos);
while ((dname = ReadDirName(dirptr)))
{
+ pstring fullname;
+ SMB_STRUCT_STAT st;
+
if ((strcmp(dname, ".") == 0)
|| (strcmp(dname, "..") == 0))
continue;
- if (!IS_VETO_PATH(conn, dname))
+
+ /* Construct the full name. */
+ if (strlen(directory) +
+ strlen(dname) + 1 >=
+ sizeof(fullname))
{
- all_veto_files = False;
+ errno = ENOMEM;
break;
}
- }
- if (all_veto_files)
- {
- SeekDir(dirptr, dirpos);
- while ((dname = ReadDirName(dirptr)))
+ pstrcpy(fullname, directory);
+ pstrcat(fullname, "/");
+ pstrcat(fullname, dname);
+
+ if (conn->vfs_ops.lstat(dos_to_unix
+ (fullname,
+ False),
+ &st) != 0)
+ break;
+ if (st.st_mode & S_IFDIR)
{
- pstring fullname;
- SMB_STRUCT_STAT st;
-
- if ((strcmp(dname, ".") == 0)
- || (strcmp(dname, "..") ==
- 0))
- continue;
-
- /* Construct the full name. */
- if (strlen(directory) +
- strlen(dname) + 1 >=
- sizeof(fullname))
+ if (lp_recursive_veto_delete
+ (SNUM(conn)))
{
- errno = ENOMEM;
- break;
+ if (recursive_rmdir
+ (conn,
+ fullname) != 0)
+ break;
}
- pstrcpy(fullname, directory);
- pstrcat(fullname, "/");
- pstrcat(fullname, dname);
-
- if (conn->vfs_ops.
- lstat(dos_to_unix
- (fullname, False),
- &st) != 0)
- break;
- if (st.st_mode & S_IFDIR)
- {
- if
- (lp_recursive_veto_delete
- (SNUM(conn)))
- {
- DEBUG(0,
- ("ERROR: recursive_rmdir()\n"));
- if
- (recursive_rmdir
- (conn,
- fullname)
- != 0)
- break;
- }
- if (conn->vfs_ops.
- rmdir(dos_to_unix
+ if (conn->
+ vfs_ops.rmdir(dos_to_unix
(fullname,
False)) !=
- 0)
- break;
- }
- else if (conn->vfs_ops.
- unlink(dos_to_unix
- (fullname,
- False)) != 0)
+ 0)
break;
}
- CloseDir(dirptr);
- /* Retry the rmdir */
- ok =
- (conn->vfs_ops.
- rmdir(dos_to_unix
- (directory, False)) == 0);
+ else if (conn->
+ vfs_ops.unlink(dos_to_unix
+ (fullname,
+ False)) != 0)
+ break;
}
- else
- CloseDir(dirptr);
+ CloseDir(dirptr);
+ /* Retry the rmdir */
+ ok =
+ (conn->
+ vfs_ops.rmdir(dos_to_unix
+ (directory, False)) == 0);
}
else
- errno = ENOTEMPTY;
+ CloseDir(dirptr);
}
+ else
+ errno = ENOTEMPTY;
+ }
+
+ if (!ok)
+ DEBUG(3,
+ ("rmdir_internals: couldn't remove directory %s : %s\n",
+ directory, strerror(errno)));
+
+ return ok;
+}
- if (!ok)
- DEBUG(3, ("couldn't remove directory %s : %s\n",
- directory, strerror(errno)));
+/****************************************************************************
+ Reply to a rmdir.
+****************************************************************************/
+
+int reply_rmdir(connection_struct * conn, char *inbuf, char *outbuf,
+ int dum_size, int dum_buffsize)
+{
+ pstring directory;
+ int outsize = 0;
+ BOOL ok = False;
+ BOOL bad_path = False;
+
+ pstrcpy(directory, smb_buf(inbuf) + 1);
+
+ RESOLVE_DFSPATH(directory, conn, inbuf, outbuf)
+ unix_convert(directory, conn, NULL, &bad_path, NULL);
+
+ if (check_name(directory, conn))
+ {
+ dptr_closepath(directory, SVAL(inbuf, smb_pid));
+ ok = rmdir_internals(conn, directory);
}
if (!ok)
int count = 0;
int error = ERRnoaccess;
BOOL exists = False;
+ BOOL rc = True;
+ pstring zdirectory;
*directory = *mask = 0;
- if (!unix_dfs_convert(name, conn, 0, &bad_path1, NULL))
- {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
- }
- if (!unix_dfs_convert
- (newname, conn, newname_last_component, &bad_path2, NULL))
- {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
- }
+ rc = unix_convert(name, conn, 0, &bad_path1, NULL);
+ unix_convert(newname, conn, newname_last_component, &bad_path2, NULL);
/*
* Split the old name into directory and last component
- * strings. Note that if (!unix_dfs_convert may have stripped off a
+ * strings. Note that unix_convert may have stripped off a
* leading ./ from both name and newname if the rename is
* at the root of the share. We need to make sure either both
* name and newname contain a / character or neither of them do
*p = '/'; /* Replace needed for exceptional test below. */
}
- if (is_mangled(mask))
+ /*
+ * We should only check the mangled cache
+ * here if unix_convert failed. This means
+ * that the path in 'mask' doesn't exist
+ * on the file system and so we need to look
+ * for a possible mangle. This patch from
+ * Tine Smukavec <valentin.smukavec@hermes.si>.
+ */
+
+ if (!rc && is_mangled(mask))
check_mangled_cache(mask);
has_wild = strchr(mask, '*') || strchr(mask, '?');
}
}
+ pstrcpy(zdirectory, dos_to_unix(directory, False));
if (replace_if_exists)
{
/*
* NT SMB specific flag - rename can overwrite
* file with the same name so don't check for
- * dos_file_exist().
+ * vfs_file_exist().
*/
if (resolve_wildcards(directory, newname) &&
can_rename(directory, conn) &&
- !conn->vfs_ops.
- rename(dos_to_unix(directory, False), newname))
+ !conn->vfs_ops.rename(zdirectory,
+ dos_to_unix(newname,
+ False)))
count++;
}
else
{
if (resolve_wildcards(directory, newname) &&
can_rename(directory, conn) &&
- !vfs_file_exist(conn, dos_to_unix(newname, False),
- NULL)
- && !conn->vfs_ops.
- rename(dos_to_unix(directory, False), newname))
+ !vfs_file_exist(conn, newname, NULL) &&
+ !conn->vfs_ops.rename(zdirectory,
+ dos_to_unix(newname,
+ False)))
count++;
}
newname));
if (!count)
- exists =
- vfs_file_exist(conn,
- dos_to_unix(directory, False),
- NULL);
- if (!count && exists
- && vfs_file_exist(conn, dos_to_unix(newname, False),
- NULL))
+ exists = vfs_file_exist(conn, directory, NULL);
+ if (!count && exists && vfs_file_exist(conn, newname, NULL))
{
exists = True;
error = ERRrename;
continue;
}
- if (!replace_if_exists
- && vfs_file_exist(conn,
- dos_to_unix(destname,
- False),
- NULL))
+ if (!replace_if_exists &&
+ vfs_file_exist(conn, destname, NULL))
{
DEBUG(6,
("file_exist %s\n", destname));
continue;
}
- if (!conn->vfs_ops.
- rename(dos_to_unix(fname, False),
- destname))
+ if (!conn->
+ vfs_ops.rename(dos_to_unix(fname, False),
+ dos_to_unix(destname,
+ False)))
count++;
DEBUG(3,
("rename_internals: doing rename on %s -> %s\n",
pstrcpy(name, smb_buf(inbuf) + 1);
pstrcpy(newname, smb_buf(inbuf) + 3 + strlen(name));
+ RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
+ RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
+
DEBUG(3, ("reply_mv : %s -> %s\n", name, newname));
outsize = rename_internals(conn, inbuf, outbuf, name, newname, False);
******************************************************************/
static BOOL copy_file(char *src, char *dest1, connection_struct * conn,
- int ofun, int count, BOOL target_is_directory)
+ int ofun, int count, BOOL target_is_directory,
+ int *err_ret)
{
int Access, action;
SMB_STRUCT_STAT st;
- int ret = -1;
+ SMB_OFF_T ret = -1;
files_struct *fsp1, *fsp2;
pstring dest;
+ *err_ret = 0;
+
pstrcpy(dest, dest1);
if (target_is_directory)
{
pstrcat(dest, p);
}
- if (!vfs_file_exist(conn, dos_to_unix(src, False), &st))
+ if (!vfs_file_exist(conn, src, &st))
return (False);
fsp1 = file_new();
NULL, 0, 0);
close_file(fsp1, False);
- close_file(fsp2, False);
+ /*
+ * As we are opening fsp1 read-only we only expect
+ * an error on close on fsp2 if we are out of space.
+ * Thus we don't look at the error return from the
+ * close of fsp1.
+ */
+ *err_ret = close_file(fsp2, False);
- return (ret == st.st_size);
+ return (ret == (SMB_OFF_T) st.st_size);
}
char *p;
int count = 0;
int error = ERRnoaccess;
+ int err = 0;
BOOL has_wild;
BOOL exists = False;
int tid2 = SVAL(inbuf, smb_vwv0);
BOOL target_is_directory = False;
BOOL bad_path1 = False;
BOOL bad_path2 = False;
+ BOOL rc = True;
*directory = *mask = 0;
return (ERROR(ERRSRV, ERRinvdevice));
}
- if (!unix_dfs_convert(name, conn, 0, &bad_path1, NULL))
- {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
- }
- if (!unix_dfs_convert(newname, conn, 0, &bad_path2, NULL))
- {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
- }
+ RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
+ RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
+
+ rc = unix_convert(name, conn, 0, &bad_path1, NULL);
+ unix_convert(newname, conn, 0, &bad_path2, NULL);
- target_is_directory = dos_directory_exist(newname, NULL);
+ target_is_directory = vfs_directory_exist(conn, False, NULL);
if ((flags & 1) && target_is_directory)
{
return (ERROR(ERRDOS, ERRbadpath));
}
- if ((flags & (1 << 5)) && dos_directory_exist(name, NULL))
+ if ((flags & (1 << 5)) && vfs_directory_exist(conn, name, NULL))
{
/* wants a tree copy! XXXX */
DEBUG(3, ("Rejecting tree copy\n"));
pstrcpy(mask, p + 1);
}
- if (is_mangled(mask))
+ /*
+ * We should only check the mangled cache
+ * here if unix_convert failed. This means
+ * that the path in 'mask' doesn't exist
+ * on the file system and so we need to look
+ * for a possible mangle. This patch from
+ * Tine Smukavec <valentin.smukavec@hermes.si>.
+ */
+
+ if (!rc && is_mangled(mask))
check_mangled_cache(mask);
has_wild = strchr(mask, '*') || strchr(mask, '?');
pstrcat(directory, mask);
if (resolve_wildcards(directory, newname) &&
copy_file(directory, newname, conn, ofun,
- count, target_is_directory)) count++;
+ count, target_is_directory, &err))
+ count++;
+ if (!count && err)
+ {
+ errno = err;
+ return (UNIXERROR(ERRHRD, ERRgeneral));
+ }
if (!count)
- exists =
- vfs_file_exist(conn,
- dos_to_unix(directory, False),
- NULL);
+ exists = vfs_file_exist(conn, directory, NULL);
}
else
{
pstrcpy(fname, dname);
if (!mask_match
- (fname, mask, case_sensitive,
- False)) continue;
+ (fname, mask, case_sensitive, False))
+ continue;
error = ERRnoaccess;
slprintf(fname, sizeof(fname) - 1, "%s/%s",
directory, dname);
pstrcpy(destname, newname);
if (resolve_wildcards(fname, destname) &&
- copy_file(directory, newname, conn, ofun,
- count, target_is_directory))
- count++;
+ copy_file(fname, destname, conn, ofun,
+ count, target_is_directory,
+ &err)) count++;
DEBUG(3,
("reply_copy : doing copy on %s -> %s\n",
fname, destname));
if (count == 0)
{
+ if (err)
+ {
+ /* Error on close... */
+ errno = err;
+ return (UNIXERROR(ERRHRD, ERRgeneral));
+ }
+
if (exists)
return (ERROR(ERRDOS, error));
else
}
else
{
- ok = dos_directory_exist(newdir, NULL);
+ ok = vfs_directory_exist(conn, newdir, NULL);
if (ok)
{
string_set(&conn->connectpath, newdir);
return (outsize);
}
+/****************************************************************************
+ Get a lock count, dealing with large count requests.
+****************************************************************************/
+
+SMB_OFF_T get_lock_count(char *data, int data_offset, BOOL large_file_format,
+ BOOL *err)
+{
+ SMB_OFF_T count = 0;
+
+ *err = False;
+
+ if (!large_file_format)
+ {
+ count = (SMB_OFF_T) IVAL(data, SMB_LKLEN_OFFSET(data_offset));
+ }
+ else
+ {
+
+#if defined(LARGE_SMB_OFF_T) && !defined(HAVE_BROKEN_FCNTL64_LOCKS)
+
+ count =
+ (((SMB_OFF_T)
+ IVAL(data,
+ SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) <<
+ 32) | ((SMB_OFF_T) IVAL(data,
+ SMB_LARGE_LKLEN_OFFSET_LOW
+ (data_offset)));
+
+#else /* !LARGE_SMB_OFF_T || HAVE_BROKEN_FCNTL64_LOCKS */
+
+ /*
+ * NT4.x seems to be broken in that it sends large file
+ * lockingX calls even if the CAP_LARGE_FILES was *not*
+ * negotiated. For boxes without large file locks truncate the
+ * lock count by dropping the top 32 bits.
+ */
+
+ if (IVAL(data, SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0)
+ {
+ DEBUG(3,
+ ("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n",
+ (unsigned int)IVAL(data,
+ SMB_LARGE_LKLEN_OFFSET_HIGH
+ (data_offset)),
+ (unsigned int)IVAL(data,
+ SMB_LARGE_LKLEN_OFFSET_LOW
+ (data_offset))));
+ SIVAL(data, SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset),
+ 0);
+ }
+
+ if (IVAL(data, SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0)
+ {
+ /*
+ * Before we error out, see if we can sensibly map the top bits
+ * down to the lower bits - or lose the top bits if they are all 1's.
+ * It seems that NT has this horrible bug where it will send 64 bit
+ * lock requests even if told not to. JRA.
+ */
+
+ if (IVAL
+ (data,
+ SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) ==
+ (uint32)0xFFFFFFFF)
+ count =
+ (SMB_OFF_T) IVAL(data,
+ SMB_LARGE_LKLEN_OFFSET_HIGH
+ (data_offset));
+ else
+ if (IVAL
+ (data,
+ SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))
+ == (uint32)0xFFFFFFFF)
+ count =
+ (SMB_OFF_T) IVAL(data,
+ SMB_LARGE_LKLEN_OFFSET_LOW
+ (data_offset));
+ else
+ {
+
+ DEBUG(0,
+ ("get_lock_count: Error : a large file count (%x << 32 | %x) was sent and we don't \
+support large counts.\n",
+ (unsigned int)IVAL(data,
+ SMB_LARGE_LKLEN_OFFSET_HIGH
+ (data_offset)),
+ (unsigned int)IVAL(data,
+ SMB_LARGE_LKLEN_OFFSET_LOW
+ (data_offset))));
+
+ *err = True;
+ return (SMB_OFF_T) - 1;
+ }
+ }
+ else
+ count =
+ (SMB_OFF_T) IVAL(data,
+ SMB_LARGE_LKLEN_OFFSET_LOW
+ (data_offset));
+
+#endif /* LARGE_SMB_OFF_T */
+ }
+ return count;
+}
+
+/****************************************************************************
+ Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
+****************************************************************************/
+static uint32 map_lock_offset(uint32 high, uint32 low)
+{
+ unsigned int i;
+ uint32 mask = 0;
+ uint32 highcopy = high;
+
+ /*
+ * Try and find out how many significant bits there are in high.
+ */
+
+ for (i = 0; highcopy; i++)
+ highcopy >>= 1;
+
+ /*
+ * We use 31 bits not 32 here as POSIX
+ * lock offsets may not be negative.
+ */
+
+ mask = (~0) << (31 - i);
+
+ if (low & mask)
+ return 0; /* Fail. */
+
+ high <<= (31 - i);
+
+ return (high | low);
+}
+
+/****************************************************************************
+ Get a lock offset, dealing with large offset requests.
+****************************************************************************/
+
+SMB_OFF_T get_lock_offset(char *data, int data_offset, BOOL large_file_format,
+ BOOL *err)
+{
+ SMB_OFF_T offset = 0;
+
+ *err = False;
+
+ if (!large_file_format)
+ {
+ offset =
+ (SMB_OFF_T) IVAL(data, SMB_LKOFF_OFFSET(data_offset));
+ }
+ else
+ {
+
+#if defined(LARGE_SMB_OFF_T) && !defined(HAVE_BROKEN_FCNTL64_LOCKS)
+
+ offset =
+ (((SMB_OFF_T)
+ IVAL(data,
+ SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) <<
+ 32) | ((SMB_OFF_T) IVAL(data,
+ SMB_LARGE_LKOFF_OFFSET_LOW
+ (data_offset)));
+
+#else /* !LARGE_SMB_OFF_T || HAVE_BROKEN_FCNTL64_LOCKS */
+
+ /*
+ * NT4.x seems to be broken in that it sends large file
+ * lockingX calls even if the CAP_LARGE_FILES was *not*
+ * negotiated. For boxes without large file locks mangle the
+ * lock offset by mapping the top 32 bits onto the lower 32.
+ */
+
+ if (IVAL(data, SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0)
+ {
+ uint32 low = IVAL(data,
+ SMB_LARGE_LKOFF_OFFSET_LOW
+ (data_offset));
+ uint32 high = IVAL(data,
+ SMB_LARGE_LKOFF_OFFSET_HIGH
+ (data_offset));
+ uint32 new_low = 0;
+
+ if ((new_low = map_lock_offset(high, low)) == 0)
+ {
+ *err = True;
+ return (SMB_OFF_T) - 1;
+ }
+
+ DEBUG(3,
+ ("get_lock_offset: truncating lock offset (high)0x%x (low)0x%x to offset 0x%x.\n",
+ (unsigned int)high, (unsigned int)low,
+ (unsigned int)new_low));
+ SIVAL(data, SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset),
+ 0);
+ SIVAL(data, SMB_LARGE_LKOFF_OFFSET_LOW(data_offset),
+ new_low);
+ }
+
+ if (IVAL(data, SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0)
+ {
+ /*
+ * Before we error out, see if we can sensibly map the top bits
+ * down to the lower bits - or lose the top bits if they are all 1's.
+ * It seems that NT has this horrible bug where it will send 64 bit
+ * lock requests even if told not to. JRA.
+ */
+
+ if (IVAL
+ (data,
+ SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)) ==
+ (uint32)0xFFFFFFFF)
+ offset =
+ (SMB_OFF_T) IVAL(data,
+ SMB_LARGE_LKOFF_OFFSET_HIGH
+ (data_offset));
+ else
+ if (IVAL
+ (data,
+ SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))
+ == (uint32)0xFFFFFFFF)
+ offset =
+ (SMB_OFF_T) IVAL(data,
+ SMB_LARGE_LKOFF_OFFSET_LOW
+ (data_offset));
+ else
+ {
+
+ DEBUG(0,
+ ("get_lock_count: Error : a large file offset (%x << 32 | %x) was sent and we don't \
+support large offsets.\n",
+ (unsigned int)IVAL(data,
+ SMB_LARGE_LKOFF_OFFSET_HIGH
+ (data_offset)),
+ (unsigned int)IVAL(data,
+ SMB_LARGE_LKOFF_OFFSET_LOW
+ (data_offset))));
+
+ *err = True;
+ return (SMB_OFF_T) - 1;
+ }
+ }
+ else
+ offset =
+ (SMB_OFF_T) IVAL(data,
+ SMB_LARGE_LKOFF_OFFSET_LOW
+ (data_offset));
+
+#endif /* LARGE_SMB_OFF_T */
+ }
+ return offset;
+}
+
/****************************************************************************
reply to a lockingX request
****************************************************************************/
int length, int bufsize)
{
files_struct *fsp = file_fsp(inbuf, smb_vwv2);
- uchar locktype = CVAL(inbuf, smb_vwv3);
+ unsigned char locktype = CVAL(inbuf, smb_vwv3);
#if 0
- uchar oplocklevel = CVAL(inbuf, smb_vwv3 + 1);
+ unsigned char oplocklevel = CVAL(inbuf, smb_vwv3 + 1);
#endif
uint16 num_ulocks = SVAL(inbuf, smb_vwv6);
uint16 num_locks = SVAL(inbuf, smb_vwv7);
uint32 ecode = 0, dummy2;
int eclass = 0, dummy1;
BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
+ BOOL err1, err2;
+
CHECK_FSP(fsp, conn);
CHECK_ERROR(fsp);
*/
if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE))
{
- SMB_DEV_T dev = fsp->fd_ptr->dev;
- SMB_INO_T inode = fsp->fd_ptr->inode;
-
DEBUG(5,
("reply_lockingX: oplock break reply from client for fnum = %d\n",
fsp->fnum));
/*
- * Make sure we have granted an oplock on this file.
+ * Make sure we have granted an exclusive or batch oplock on this file.
*/
- if (!fsp->granted_oplock)
+
+ if (!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
{
DEBUG(0,
("reply_lockingX: Error : oplock break from client for fnum = %d and \
-no oplock granted on this file.\n",
- fsp->fnum));
- return ERROR(ERRDOS, ERRlock);
+no oplock granted on this file (%s).\n",
+ fsp->fnum, fsp->fsp_name));
+
+ /* if this is a pure oplock break request then don't send a reply */
+ if (num_locks == 0 && num_ulocks == 0)
+ return -1;
+ else
+ return ERROR(ERRDOS, ERRlock);
}
- /* Remove the oplock flag from the sharemode. */
- lock_share_entry(fsp->conn, dev, inode);
- if (remove_share_oplock(fsp) == False)
+ if (remove_oplock(fsp) == False)
{
DEBUG(0,
- ("reply_lockingX: failed to remove share oplock for fnum %d, \
-dev = %x, inode = %.0f\n",
- fsp->fnum, (unsigned int)dev, (double)inode));
-
- unlock_share_entry(fsp->conn, dev, inode);
- }
- else
- {
- unlock_share_entry(fsp->conn, dev, inode);
-
- /* Clear the granted flag and return. */
- fsp->granted_oplock = False;
+ ("reply_lockingX: error in removing oplock on file %s\n",
+ fsp->fsp_name));
}
/* if this is a pure oplock break request then don't send a reply */
of smb_unlkrng structs */
for (i = 0; i < (int)num_ulocks; i++)
{
- if (!large_file_format)
- {
- count = IVAL(data, SMB_LKLEN_OFFSET(i));
- offset = IVAL(data, SMB_LKOFF_OFFSET(i));
- }
-#ifdef LARGE_SMB_OFF_T
- else
- {
- count =
- (((SMB_OFF_T)
- IVAL(data,
- SMB_LARGE_LKLEN_OFFSET_HIGH(i))) << 32)
- | ((SMB_OFF_T)
- IVAL(data, SMB_LARGE_LKLEN_OFFSET_LOW(i)));
- offset =
- (((SMB_OFF_T)
- IVAL(data,
- SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32)
- | ((SMB_OFF_T)
- IVAL(data, SMB_LARGE_LKOFF_OFFSET_LOW(i)));
- }
-#endif /* LARGE_SMB_OFF_T */
+ count = get_lock_count(data, i, large_file_format, &err1);
+ offset = get_lock_offset(data, i, large_file_format, &err2);
+
+ /*
+ * There is no error code marked "stupid client bug".... :-).
+ */
+ if (err1 || err2)
+ return ERROR(ERRDOS, ERRnoaccess);
DEBUG(10,
("reply_lockingX: unlock start=%.0f, len=%.0f for file %s\n",
for (i = 0; i < (int)num_locks; i++)
{
- if (!large_file_format)
- {
- count = IVAL(data, SMB_LKLEN_OFFSET(i));
- offset = IVAL(data, SMB_LKOFF_OFFSET(i));
- }
-#ifdef LARGE_SMB_OFF_T
- else
- {
- count =
- (((SMB_OFF_T)
- IVAL(data,
- SMB_LARGE_LKLEN_OFFSET_HIGH(i))) << 32)
- | ((SMB_OFF_T)
- IVAL(data, SMB_LARGE_LKLEN_OFFSET_LOW(i)));
- offset =
- (((SMB_OFF_T)
- IVAL(data,
- SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32)
- | ((SMB_OFF_T)
- IVAL(data, SMB_LARGE_LKOFF_OFFSET_LOW(i)));
- }
-#endif /* LARGE_SMB_OFF_T */
+ count = get_lock_count(data, i, large_file_format, &err1);
+ offset = get_lock_offset(data, i, large_file_format, &err2);
+
+ /*
+ * There is no error code marked "stupid client bug".... :-).
+ */
+ if (err1 || err2)
+ return ERROR(ERRDOS, ERRnoaccess);
DEBUG(10,
("reply_lockingX: lock start=%.0f, len=%.0f for file %s\n",
if (!do_lock
(fsp, conn, count, offset,
- ((locktype & 1) ? F_RDLCK : F_WRLCK), &eclass, &ecode))
+ ((locktype & 1) ? READ_LOCK : WRITE_LOCK), &eclass,
+ &ecode))
{
if ((ecode == ERRlock) && (lock_timeout != 0)
&& lp_blocking_locks(SNUM(conn)))
all of the previous locks (X/Open spec). */
if (i != num_locks && num_locks != 0)
{
- for (; i >= 0; i--)
+ /*
+ * Ensure we don't do a remove on the lock that just failed,
+ * as under POSIX rules, if we have a lock already there, we
+ * will delete it (and we shouldn't) .....
+ */
+ for (i--; i >= 0; i--)
{
- if (!large_file_format)
- {
- count = IVAL(data, SMB_LKLEN_OFFSET(i));
- offset = IVAL(data, SMB_LKOFF_OFFSET(i));
- }
-#ifdef LARGE_SMB_OFF_T
- else
- {
- count =
- (((SMB_OFF_T)
- IVAL(data,
- SMB_LARGE_LKLEN_OFFSET_HIGH
- (i))) << 32) | ((SMB_OFF_T)
- IVAL(data,
- SMB_LARGE_LKLEN_OFFSET_LOW
- (i)));
- offset =
- (((SMB_OFF_T)
- IVAL(data,
- SMB_LARGE_LKOFF_OFFSET_HIGH
- (i))) << 32) | ((SMB_OFF_T)
- IVAL(data,
- SMB_LARGE_LKOFF_OFFSET_LOW
- (i)));
- }
-#endif /* LARGE_SMB_OFF_T */
+ count =
+ get_lock_count(data, i, large_file_format,
+ &err1);
+ offset =
+ get_lock_offset(data, i, large_file_format,
+ &err2);
+
+ /*
+ * There is no error code marked "stupid client bug".... :-).
+ */
+ if (err1 || err2)
+ return ERROR(ERRDOS, ERRnoaccess);
do_unlock(fsp, conn, count, offset, &dummy1, &dummy2);
}
tcount = maxcount;
total_read = 0;
- if (is_locked(fsp, conn, maxcount, startpos, F_RDLCK))
+ if (is_locked(fsp, conn, maxcount, startpos, READ_LOCK))
return (ERROR(ERRDOS, ERRlock));
do
reply to a SMBwritebmpx (write block multiplex primary) request
****************************************************************************/
int reply_writebmpx(connection_struct * conn, char *inbuf, char *outbuf,
- int dum_size, int dum_buffsize)
+ int size, int dum_buffsize)
{
size_t numtowrite;
ssize_t nwritten = -1;
not an SMBwritebmpx - set this up now so we don't forget */
CVAL(outbuf, smb_com) = SMBwritec;
- if (is_locked(fsp, conn, tcount, startpos, F_WRLCK))
+ if (is_locked(fsp, conn, tcount, startpos, WRITE_LOCK))
return (ERROR(ERRDOS, ERRlock));
- if (seek_file(fsp, startpos) == -1)
- return (UNIXERROR(ERRDOS, ERRnoaccess));
+ nwritten = write_file(fsp, data, startpos, numtowrite);
- nwritten = write_file(fsp, data, numtowrite);
-
- if ((lp_syncalways(SNUM(conn)) || write_through) &&
- lp_strict_sync(SNUM(conn)))
- conn->vfs_ops.sync(fsp->fd_ptr->fd);
+ if (lp_syncalways(SNUM(conn)) || write_through)
+ conn->vfs_ops.fsync(fsp->fd_ptr->fd);
if (nwritten < (ssize_t) numtowrite)
return (UNIXERROR(ERRHRD, ERRdiskfull));
SSVALS(outbuf, smb_vwv0, -1); /* We don't support smb_remaining */
DEBUG(3, ("writebmpx fnum=%d num=%d wrote=%d\n",
- fsp->fnum, numtowrite, nwritten));
+ fsp->fnum, (int)numtowrite, (int)nwritten));
if (write_through && tcount == nwritten)
{
if (wbms->wr_discard)
return -1; /* Just discard the packet */
- if (seek_file(fsp, startpos) == -1)
- {
- if (write_through)
- {
- /* We are returning an error - we can delete the aux struct */
- if (wbms)
- free((char *)wbms);
- fsp->wbmpx_ptr = NULL;
- return (UNIXERROR(ERRDOS, ERRnoaccess));
- }
- return (CACHE_ERROR(wbms, ERRDOS, ERRnoaccess));
- }
-
- nwritten = write_file(fsp, data, numtowrite);
+ nwritten = write_file(fsp, data, startpos, numtowrite);
- if ((lp_syncalways(SNUM(conn)) || write_through) &&
- lp_strict_sync(SNUM(conn)))
- conn->vfs_ops.sync(fsp->fd_ptr->fd);
+ if (lp_syncalways(SNUM(conn)) || write_through)
+ conn->vfs_ops.fsync(fsp->fd_ptr->fd);
if (nwritten < (ssize_t) numtowrite)
{
reply to a SMBsetattrE
****************************************************************************/
int reply_setattrE(connection_struct * conn, char *inbuf, char *outbuf,
- int dum_size, int dum_buffsize)
+ int size, int dum_buffsize)
{
struct utimbuf unix_times;
int outsize = 0;
reply to a SMBgetattrE
****************************************************************************/
int reply_getattrE(connection_struct * conn, char *inbuf, char *outbuf,
- int dum_size, int dum_buffsize)
+ int size, int dum_buffsize)
{
SMB_STRUCT_STAT sbuf;
int outsize = 0;
}
else
{
- SIVAL(outbuf, smb_vwv6, (uint32) sbuf.st_size);
+ SIVAL(outbuf, smb_vwv6, (uint32)sbuf.st_size);
SIVAL(outbuf, smb_vwv8, SMB_ROUNDUP(sbuf.st_size, 1024));
}
SSVAL(outbuf, smb_vwv10, mode);
extern fstring global_myworkgroup;
extern fstring global_sam_name;
extern pstring global_myname;
-extern dfs_internal dfs_struct;
int am_parent = 1;
/* a useful macro to debug the last message processed */
#define LAST_MESSAGE() smb_fn_name(last_message)
-extern pstring scope;
extern int DEBUGLEVEL;
extern pstring user_socket_options;
/****************************************************************************
open the socket communication
****************************************************************************/
-static BOOL open_sockets(BOOL is_daemon,int port,int port445)
+static BOOL open_sockets(BOOL is_daemon,int port, int port445)
{
extern int Client;
extern int ClientPort;
num_interfaces = 1;
/* open an incoming socket */
- s = open_server_socket(port, interpret_addr(lp_socket_address()));
+ s = open_server_socket(port,
+ interpret_addr(lp_socket_address()));
if (s == -1)
return(False);
fd_listenset[0] = s;
memcpy((char *)&lfds, (char *)&listen_set,
sizeof(listen_set));
- num = sys_select(256,&lfds,NULL, NULL);
+ num = sys_select(FD_SETSIZE,&lfds,NULL,NULL);
if (num == -1 && errno == EINTR)
continue;
+ /* check if we need to reload services */
+ check_reload(time(NULL));
+
/* Find the sockets that are read-ready -
accept on these. */
for( ; num > 0; num--) {
ret = lp_load(servicesf,False,False,True);
+#ifdef MS_DFS
+ /* load the dfs maps of all the services having
+ a dfs_map parameter
+ we don't want to do this in lp_load because we want just the smbd
+ server to load up the dfs maps into msdfs.tdb. not nmbd, swat etc*/
+ load_dfsmaps();
+#endif
+
load_printers();
/* perhaps the config filename is now set */
}
reset_mangled_cache();
+ reset_stat_cache();
/* this forces service parameters to be flushed */
become_service(NULL,True);
/****************************************************************************
-this prevents zombie child processes
+ Catch a sighup.
****************************************************************************/
-BOOL reload_after_sighup = False;
+
+VOLATILE SIG_ATOMIC_T reload_after_sighup = False;
static void sig_hup(int sig)
{
conn_close_all();
+ respond_to_all_remaining_local_messages();
+
#ifdef WITH_DFS
if (dcelogin_atmost_once) {
dfs_unlogin();
}
locking_end();
+#ifdef MS_DFS
+ msdfs_end();
+#endif
DEBUG(3,("Server exit (%s)\n", (reason ? reason : "")));
-#ifdef MEM_MAN
- {
- extern FILE *dbf;
- smb_mem_write_verbose(dbf);
- dbgflush();
- }
-#endif
exit(0);
}
****************************************************************************/
static void init_structs(void)
{
+ /*
+ * Set the machine NETBIOS name if not already
+ * set from the config file.
+ */
+
+ if (!*global_myname) {
+ char *p;
+ fstrcpy( global_myname, myhostname() );
+ p = strchr( global_myname, '.' );
+ if (p)
+ *p = 0;
+ }
+
+ strupper( global_myname );
+
conn_init();
file_init();
init_rpc_pipe_hnd(); /* for RPC pipes */
init_dptrs();
- init_dfs_table();
}
/****************************************************************************
****************************************************************************/
static void usage(char *pname)
{
- DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
-
- printf("Usage: %s [-D] [-p port] [-d debuglevel] ", pname);
- printf("[-l log basename] [-s services file]\n" );
- printf("Version %s\n",VERSION);
- printf("\t-D become a daemon\n");
- printf("\t-p port listen on the specified port\n");
- printf("\t-d debuglevel set the debuglevel\n");
+
+ printf("Usage: %s [-DaoPh?V] [-d debuglevel] [-l log basename] [-p port]\n", pname);
+ printf(" [-O socket options] [-s services file]\n");
+ printf("\t-D Become a daemon\n");
+ printf("\t-a Append to log file (default)\n");
+ printf("\t-o Overwrite log file, don't append\n");
+ printf("\t-P Passive only\n");
+ printf("\t-h Print usage\n");
+ printf("\t-? Print usage\n");
+ printf("\t-V Print version\n");
+ printf("\t-d debuglevel Set the debuglevel\n");
printf("\t-l log basename. Basename for log/debug files\n");
+ printf("\t-p port Listen on the specified port\n");
+ printf("\t-O socket options Socket options\n");
printf("\t-s services file. Filename of services file\n");
- printf("\t-P passive only\n");
- printf("\t-a append to log file (default)\n");
- printf("\t-o overwrite log file, don't append\n");
- printf("\t-i scope NetBIOS scope to use (default none)\n");
printf("\n");
}
extern BOOL append_log;
/* shall I run as a daemon */
BOOL is_daemon = False;
+ BOOL specified_logfile = False;
int port = SMB_PORT;
int port445 = SMB_PORT2;
int opt;
set_auth_parameters(argc,argv);
#endif
-#ifdef HAVE_SETLUID
- /* needed for SecureWare on SCO */
- setluid(0);
-#endif
-
- append_log = True;
-
- TimeInit();
-
- pstrcpy(debugf,SMBLOGFILE);
-
- pstrcpy(remote_machine, "smb");
-
- setup_logging(argv[0],False);
-
- charset_initialise();
-
- /* make absolutely sure we run as root - to handle cases where people
- are crazy enough to have it setuid */
- gain_root_privilege();
- gain_root_group_privilege();
-
- fault_setup((void (*)(void *))exit_server);
- CatchSignal(SIGTERM , SIGNAL_CAST dflt_sig);
-
- /* we are never interested in SIGPIPE */
- BlockSignals(True,SIGPIPE);
-
- /* we want total control over the permissions on created files,
- so set our umask to 0 */
- umask(0);
-
- dos_GetWd(OriginalDir);
-
- init_uid();
-
/* this is for people who can't start the program correctly */
while (argc > 1 && (*argv[1] != '-')) {
argv++;
argc--;
}
- while ( EOF != (opt = getopt(argc, argv, "O:i:l:s:d:Dp:h?Paof:")) )
+ while ( EOF != (opt = getopt(argc, argv, "O:l:s:d:Dp:h?VPaof:")) )
switch (opt) {
case 'O':
pstrcpy(user_socket_options,optarg);
break;
- case 'i':
- pstrcpy(scope,optarg);
- break;
-
case 'P':
{
extern BOOL passive;
break;
case 'l':
+ specified_logfile = True;
pstrcpy(debugf,optarg);
break;
exit(0);
break;
+ case 'V':
+ printf("Version %s\n",VERSION);
+ exit(0);
+ break;
default:
+ DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
usage(argv[0]);
exit(1);
}
+#ifdef HAVE_SETLUID
+ /* needed for SecureWare on SCO */
+ setluid(0);
+#endif
+
+ /*
+ * gain_root_privilege uses an assert than will cause a core
+ * dump if euid != 0. Ensure this is the case.
+ */
+
+ if(geteuid() != (uid_t)0) {
+ fprintf(stderr, "%s: Version %s : Must have effective user id of zero to run.\n", argv[0], VERSION);
+ exit(1);
+ }
+
+ append_log = True;
+
+ TimeInit();
+
+ if(!specified_logfile)
+ pstrcpy(debugf,SMBLOGFILE);
+
+ pstrcpy(remote_machine, "smb");
+
+ setup_logging(argv[0],False);
+
+ charset_initialise();
+
+ /* we want to re-seed early to prevent time delays causing
+ client problems at a later date. (tridge) */
+ generate_random_buffer(NULL, 0, False);
+
+ /* make absolutely sure we run as root - to handle cases where people
+ are crazy enough to have it setuid */
+
+ gain_root_privilege();
+ gain_root_group_privilege();
+
+ fault_setup((void (*)(void *))exit_server);
+ CatchSignal(SIGTERM , SIGNAL_CAST dflt_sig);
+
+ /* we are never interested in SIGPIPE */
+ BlockSignals(True,SIGPIPE);
+
+#if defined(SIGFPE)
+ /* we are never interested in SIGFPE */
+ BlockSignals(True,SIGFPE);
+#endif
+
+ /* we want total control over the permissions on created files,
+ so set our umask to 0 */
+ umask(0);
+
+ dos_GetWd(OriginalDir);
+
+ init_uid();
+
reopen_logs();
DEBUG(1,( "smbd version %s started.\n", VERSION));
exit(1);
}
+ /*
+ * Do this before reload_services.
+ */
+
if (!reload_services(False))
return(-1);
}
#endif
- /*
- * Set the machine NETBIOS name if not already
- * set from the config file.
- */
- if (!*global_myname)
- {
- fstrcpy(global_myname, dns_to_netbios_name(myhostname()));
- }
- strupper(global_myname);
-
#ifdef WITH_SSL
{
extern BOOL sslEnabled;
codepage_initialise(lp_client_code_page());
- if (!pwdb_initialise(True))
- {
- exit(1);
- }
+ fstrcpy(global_myworkgroup, lp_workgroup());
CatchSignal(SIGHUP,SIGNAL_CAST sig_hup);
/* If we are using the malloc debug code we can't use
SIGUSR1 and SIGUSR2 to do debug level changes. */
-#ifndef MEM_MAN
#if defined(SIGUSR1)
CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 );
#endif /* SIGUSR1 */
#if defined(SIGUSR2)
CatchSignal( SIGUSR2, SIGNAL_CAST sig_usr2 );
#endif /* SIGUSR2 */
-#endif /* MEM_MAN */
DEBUG(3,( "loaded services\n"));
if (!open_sockets(is_daemon,port,port445))
exit(1);
+ /*
+ * Note that this call should be done after the fork() call
+ * in open_sockets(), as some versions of the locking shared
+ * memory code register openers in a flat file.
+ */
+
if (!locking_init(0))
exit(1);
+ if(!pwdb_initialise(True))
+ exit(1);
+
/* possibly reload the services file. */
reload_services(True);
Unix SMB/Netbios implementation.
Version 1.9.
service (connection) opening and closing
- Copyright (C) Andrew Tridgell 1992-1998
+ 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
extern int DEBUGLEVEL;
-extern time_t smb_last_time;
+extern struct timeval smb_last_time;
extern int case_default;
extern BOOL case_preserve;
extern BOOL short_case_preserve;
return(False);
}
- conn->lastused = smb_last_time;
+ conn->lastused = smb_last_time.tv_sec;
snum = SNUM(conn);
{
int iService;
- string_sub(service,"\\","/");
+ all_string_sub(service,"\\","/",0);
iService = lp_servicenumber(service);
char *phome_dir = get_unixhome_dir(service);
pstring home_dir;
- if(phome_dir == NULL)
+ if(!phome_dir)
{
/*
* Try mapping the servicename, it may
iService = find_service(defservice);
if (iService >= 0)
{
- string_sub(service,"_","/");
+ all_string_sub(service,"_","/",0);
iService = lp_add_service(service,iService);
}
}
{
pstring list;
StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
- string_sub(list,"%S",service);
+ pstring_sub(list,"%S",service);
if (user_in_list(user,list))
conn->read_only = True;
StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
- string_sub(list,"%S",service);
+ pstring_sub(list,"%S",service);
if (user_in_list(user,list))
conn->read_only = False;
string_set(&conn->dirpath,"");
string_set(&conn->user,user);
+ conn->vfs_conn = (struct vfs_connection_struct *)
+ malloc(sizeof(struct vfs_connection_struct));
+
+ if (conn->vfs_conn == NULL) {
+ DEBUG(0, ("No memory to create vfs_connection_struct"));
+ return NULL;
+ }
+
+ ZERO_STRUCTP(conn->vfs_conn);
+
+ /* Copy across relevant data from connection struct */
+
+ conn->vfs_conn->printer = conn->printer;
+ conn->vfs_conn->ipc = conn->ipc;
+ conn->vfs_conn->read_only = conn->read_only;
+ conn->vfs_conn->admin_user = conn->admin_user;
+
+ pstrcpy(conn->vfs_conn->dirpath, conn->dirpath);
+ pstrcpy(conn->vfs_conn->connectpath, conn->connectpath);
+ pstrcpy(conn->vfs_conn->origpath, conn->origpath);
+
+ pstrcpy(conn->vfs_conn->service, service);
+ pstrcpy(conn->vfs_conn->user, conn->user);
+
+ conn->vfs_conn->uid = conn->uid;
+ conn->vfs_conn->gid = conn->gid;
+ conn->vfs_conn->ngroups = conn->ngroups;
+ conn->vfs_conn->groups = (gid_t *)memdup(conn->groups,
+ conn->ngroups * sizeof(gid_t));
+
/* Initialise VFS function pointers */
if (*lp_vfsobj(SNUM(conn))) {
vfs_init_default(conn);
}
+ /*
+ * If force user is true, then store the
+ * given userid and also the primary groupid
+ * of the user we're forcing.
+ */
+
+ if (*lp_force_user(snum))
+ {
+ const struct passwd *pass2;
+ pstring fuser;
+ pstrcpy(fuser,lp_force_user(snum));
+
+ /* Allow %S to be used by force user. */
+ pstring_sub(fuser,"%S",service);
+
+ pass2 = Get_Pwnam(fuser,True);
+ if (pass2) {
+ conn->uid = pass2->pw_uid;
+ conn->gid = pass2->pw_gid;
+ string_set(&conn->user,fuser);
+ fstrcpy(user,fuser);
+ conn->force_user = True;
+ DEBUG(3,("Forced user %s\n",fuser));
+ } else {
+ DEBUG(1,("Couldn't find user %s\n",fuser));
+ }
+ }
+
#ifdef HAVE_GETGRNAM
+ /*
+ * If force group is true, then override
+ * any groupid stored for the connecting user.
+ */
+
if (*lp_force_group(snum)) {
struct group *gptr;
pstring gname;
+ pstring tmp_gname;
+ BOOL user_must_be_member = False;
- StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
+ StrnCpy(tmp_gname,lp_force_group(snum),sizeof(pstring)-1);
+
+ if (tmp_gname[0] == '+') {
+ user_must_be_member = True;
+ StrnCpy(gname,&tmp_gname[1],sizeof(pstring)-2);
+ } else {
+ StrnCpy(gname,tmp_gname,sizeof(pstring)-1);
+ }
/* default service may be a group name */
- string_sub(gname,"%S",service);
+ pstring_sub(gname,"%S",service);
gptr = (struct group *)getgrnam(gname);
if (gptr) {
+ /*
+ * If the user has been forced and the forced group starts
+ * with a '+', then we only set the group to be the forced
+ * group if the forced user is a member of that group.
+ * Otherwise, the meaning of the '+' would be ignored.
+ */
+ if (conn->force_user && user_must_be_member) {
+ int i;
+ for (i = 0; gptr->gr_mem[i] != NULL; i++) {
+ if (strcmp(user,gptr->gr_mem[i]) == 0) {
conn->gid = gptr->gr_gid;
- DEBUG(3,("Forced group %s\n",gname));
- } else {
- DEBUG(1,("Couldn't find group %s\n",gname));
+ DEBUG(3,("Forced group %s for member %s\n",gname,user));
+ break;
}
}
-#endif
-
- if (*lp_force_user(snum)) {
- const struct passwd *pass2;
- fstring fuser;
- fstrcpy(fuser,lp_force_user(snum));
- pass2 = (const struct passwd *)Get_Pwnam(fuser,True);
- if (pass2) {
- conn->uid = pass2->pw_uid;
- string_set(&conn->user,fuser);
- fstrcpy(user,fuser);
- conn->force_user = True;
- DEBUG(3,("Forced user %s\n",fuser));
} else {
- DEBUG(1,("Couldn't find user %s\n",fuser));
+ conn->gid = gptr->gr_gid;
+ DEBUG(3,("Forced group %s\n",gname));
+ }
+ } else {
+ DEBUG(1,("Couldn't find group %s\n",gname));
}
}
+#endif /* HAVE_GETGRNAM */
{
pstring s;
}
if (lp_status(SNUM(conn)))
- claim_connection(conn,"STATUS.",
+ claim_connection(conn,"",
MAXSTATUS,False);
} /* IS_IPC */
/* execute any "root preexec = " line */
if (*lp_rootpreexec(SNUM(conn)))
{
+ BOOL ret;
pstring cmd;
user_struct *vuser = get_valid_user_struct(&key);
pstrcpy(cmd,lp_rootpreexec(SNUM(conn)));
standard_sub(conn,vuser, cmd);
vuid_free_user_struct(vuser);
DEBUG(5,("cmd=%s\n",cmd));
- smbrun(cmd,NULL,False);
+ ret = smbrun(cmd,NULL,False);
+ if (ret != 0 && lp_rootpreexec_close(SNUM(conn))) {
+ DEBUG(1,("preexec gave %d - failing connection\n", ret));
+ conn_free(conn);
+ *ecode = ERRsrverror;
+ return NULL;
+ }
}
if (!become_user(conn, conn->vuid)) {
lp_servicename(SNUM(conn)),
lp_max_connections(SNUM(conn)));
if (lp_status(SNUM(conn))) {
- yield_connection(conn,"STATUS.",MAXSTATUS);
+ yield_connection(conn,"",MAXSTATUS);
}
}
conn_free(conn);
lp_servicename(SNUM(conn)),
lp_max_connections(SNUM(conn)));
if (lp_status(SNUM(conn)))
- yield_connection(conn,"STATUS.",MAXSTATUS);
+ yield_connection(conn,"",MAXSTATUS);
}
conn_free(conn);
*ecode = ERRinvnetname;
/* execute any "preexec = " line */
if (*lp_preexec(SNUM(conn)))
{
+ BOOL ret;
pstring cmd;
user_struct *vuser = get_valid_user_struct(&key);
pstrcpy(cmd,lp_preexec(SNUM(conn)));
standard_sub(conn,vuser, cmd);
vuid_free_user_struct(vuser);
- smbrun(cmd,NULL,False);
+ ret = smbrun(cmd,NULL,False);
+ if (ret != 0 && lp_preexec_close(SNUM(conn))) {
+ DEBUG(1,("preexec gave %d - failing connection\n", ret));
+ conn_free(conn);
+ *ecode = ERRsrverror;
+ return NULL;
+ }
+ }
+
+ /*
+ * Print out the 'connected as' stuff here as we need
+ * to know the effective uid and gid we will be using.
+ */
+
+ if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
+ dbgtext( "%s (%s) ", remote_machine, conn->client_address );
+ dbgtext( "connect to service %s ", lp_servicename(SNUM(conn)) );
+ dbgtext( "as user %s ", user );
+ dbgtext( "(uid=%d, gid=%d) ", (int)geteuid(), (int)getegid() );
+ dbgtext( "(pid %d)\n", (int)getpid() );
}
/* we've finished with the sensitive stuff */
set_namearray( &conn->veto_oplock_list, lp_veto_oplocks(SNUM(conn)));
}
- if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
-
- dbgtext( "%s (%s) ", remote_machine, client_connection_addr() );
- dbgtext( "connect to service %s ", lp_servicename(SNUM(conn)));
- dbgtext( "as user %s ", user );
- dbgtext( "(uid=%d, gid=%d) ", (int)conn->uid, (int)conn->gid );
- dbgtext( "(pid %d)\n", (int)key.pid );
- }
-
- /* Invoke make connection hook */
+ /* Invoke VFS make connection hook */
if (conn->vfs_ops.connect) {
- struct vfs_connection_struct *vconn;
-
- vconn = (struct vfs_connection_struct *)
- malloc(sizeof(struct vfs_connection_struct));
-
- if (vconn == NULL) {
- DEBUG(0, ("No memory to create vfs_connection_struct"));
- return NULL;
- }
-
- ZERO_STRUCTP(vconn);
-
- /* Copy across relevant data from connection struct */
-
- vconn->printer = conn->printer;
- vconn->ipc = conn->ipc;
- vconn->read_only = conn->read_only;
- vconn->admin_user = conn->admin_user;
-
- pstrcpy(vconn->dirpath, conn->dirpath);
- pstrcpy(vconn->connectpath, conn->connectpath);
- pstrcpy(vconn->origpath, conn->origpath);
-
- pstrcpy(vconn->service, service);
- pstrcpy(vconn->user, conn->user);
-
- vconn->uid = conn->uid;
- vconn->gid = conn->gid;
- vconn->ngroups = conn->ngroups;
- vconn->groups = (gid_t *)memdup(conn->groups,
- conn->ngroups * sizeof(gid_t));
-
- /* Call connect hook */
-
- if (conn->vfs_ops.connect(vconn, service, user) < 0) {
+ if (conn->vfs_ops.connect(conn->vfs_conn, service, user) < 0) {
return NULL;
}
}
if (conn->vfs_ops.disconnect != NULL) {
- /* Call disconnect hook */
+ /* Call VFS disconnect hook */
conn->vfs_ops.disconnect();
+ }
+
+ /* Close dlopen() handle */
+
+ if (conn->vfs_conn->dl_handle != NULL) {
+ dlclose(conn->vfs_conn->dl_handle); /* should we check return val? */
+ }
+
/* Free vfs_connection_struct */
if (conn->vfs_conn != NULL) {
}
free(conn->vfs_conn);
}
- }
yield_connection(conn,
lp_servicename(SNUM(conn)),
lp_max_connections(SNUM(conn)));
if (lp_status(SNUM(conn)))
- yield_connection(conn,"STATUS.",MAXSTATUS);
+ yield_connection(conn,"",MAXSTATUS);
file_close_conn(conn);
dptr_closecnum(conn);
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "includes.h"
-
-/*
- * Hmmm, only check on WITH_SSL after we have included includes.h
- * which pulls in config.h which is where WITH_SSL is defined, if
- * at all :-)
+/*
+ * since includes.h pulls in config.h which is were WITH_SSL will be
+ * defined, we want to include includes.h before testing for WITH_SSL
+ * RJS 26-Jan-1999
*/
+#include "includes.h"
+
#ifdef WITH_SSL /* should always be defined if this module is compiled */
#include <ssl.h>
*/
#include "includes.h"
-#include "nterr.h"
#include "trans2.h"
extern int DEBUGLEVEL;
extern int smb_read_error;
extern fstring local_machine;
extern int global_oplock_break;
-extern dfs_internal dfs_struct;
+extern uint32 global_client_caps;
/****************************************************************************
Send the required number of replies back.
total_sent_thistime = params_to_send + data_to_send +
alignment_offset + data_alignment_offset;
/* We can never send more than useable_space */
- total_sent_thistime = MIN(total_sent_thistime, useable_space);
+ /*
+ * Note that 'useable_space' does not include the alignment offsets,
+ * but we must include the alignment offsets in the calculation of
+ * the length of the data we send over the wire, as the alignment offsets
+ * are sent here. Fix from Marc_Jacobsen@hp.com.
+ */
+ total_sent_thistime = MIN(total_sent_thistime, useable_space+
+ alignment_offset + data_alignment_offset);
set_message(outbuf, 10, total_sent_thistime, True);
data_sent_thistime = MIN(data_sent_thistime,data_to_send);
SSVAL(outbuf,smb_prcnt, params_sent_thistime);
+
+ /* smb_proff is the offset from the start of the SMB header to the
+ parameter bytes, however the first 4 bytes of outbuf are
+ the Netbios over TCP header. Thus use smb_base() to subtract
+ them from the calculation */
+
+ SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
+
if(params_sent_thistime == 0)
- {
- /*SSVAL(outbuf,smb_proff,0);*/
- SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
SSVAL(outbuf,smb_prdisp,0);
- }
else
- {
- /* smb_proff is the offset from the start of the SMB header to the
- parameter bytes, however the first 4 bytes of outbuf are
- the Netbios over TCP header. Thus use smb_base() to subtract
- them from the calculation */
- SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
/* Absolute displacement of param bytes sent in this packet */
SSVAL(outbuf,smb_prdisp,pp - params);
- }
SSVAL(outbuf,smb_drcnt, data_sent_thistime);
if(data_sent_thistime == 0)
/* XXXX we need to handle passed times, sattr and flags */
- if (!unix_dfs_convert(fname,conn,0,&bad_path,NULL))
- {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
- }
+ unix_convert(fname,conn,0,&bad_path,NULL);
fsp = file_new();
if (!fsp)
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- unixmode = unix_mode(conn,open_attr | aARCH);
+ unixmode = unix_mode(conn,open_attr | aARCH, fname);
open_file_shared(fsp,conn,fname,open_mode,open_ofun,unixmode,
oplock_request, &rmode,&smb_action);
if(params == NULL)
return(ERROR(ERRDOS,ERRnomem));
- memset(params, 0, 28);
+ memset((char *)params,'\0',28);
SSVAL(params,0,fsp->fnum);
SSVAL(params,2,fmode);
put_dos_date2(params,4, mtime);
/****************************************************************************
get a level dependent lanman2 dir entry.
****************************************************************************/
-static int get_lanman2_dir_entry(connection_struct *conn,
+static BOOL get_lanman2_dir_entry(connection_struct *conn,
char *path_mask,int dirtype,int info_level,
int requires_resume_key,
BOOL dont_descend,char **ppdata,
char *base_data, int space_remaining,
- BOOL *out_of_space,
+ BOOL *out_of_space, BOOL *got_exact_match,
int *last_name_off)
{
char *dname;
*fname = 0;
*out_of_space = False;
+ *got_exact_match = False;
if (!conn->dirptr)
return(False);
while (!found)
{
+ BOOL got_match;
+
/* Needed if we run out of space */
prev_dirpos = TellDir(conn->dirptr);
dname = ReadDirName(conn->dirptr);
pstrcpy(fname,dname);
- if(mask_match(fname, mask, case_sensitive, True))
+ if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive)))
+ got_match = mask_match(fname, mask, case_sensitive, True);
+
+ if(!got_match && !is_8_3(fname, False)) {
+
+ /*
+ * It turns out that NT matches wildcards against
+ * both long *and* short names. This may explain some
+ * of the wildcard wierdness from old DOS clients
+ * that some people have been seeing.... JRA.
+ */
+
+ pstring newname;
+ pstrcpy( newname, fname);
+ name_map_mangle( newname, True, False, SNUM(conn));
+ if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
+ got_match = mask_match(newname, mask, case_sensitive, True);
+ }
+
+ if(got_match)
{
BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
if (dont_descend && !isdots)
}
}
- name_map_mangle(fname,False,SNUM(conn));
+ name_map_mangle(fname,False,True,SNUM(conn));
p = pdata;
nameptr = p;
SIVAL(p,0,0); p += 4;
if (!was_8_3) {
pstrcpy(p+2,fname);
- if (!name_map_mangle(p+2,True,SNUM(conn)))
+ if (!name_map_mangle(p+2,True,True,SNUM(conn)))
(p+2)[12] = 0;
} else
*(p+2) = 0;
*last_name_off = PTR_DIFF(nameptr,base_data);
/* Advance the data pointer to the next slot */
*ppdata = p;
+
return(found);
}
}
/****************************************************************************
- reply to a TRANS2_FINDFIRST
+ Reply to a TRANS2_FINDFIRST.
****************************************************************************/
+
static int call_trans2findfirst(connection_struct *conn,
char *inbuf, char *outbuf, int bufsize,
char **pparams, char **ppdata)
pstrcpy(directory, params + 12); /* Complete directory path with
wildcard mask appended */
+ RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
+
DEBUG(5,("path=%s\n",directory));
- if (!unix_dfs_convert(directory,conn,0,&bad_path,NULL))
- {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
- }
+ unix_convert(directory,conn,0,&bad_path,NULL);
if(!check_name(directory,conn)) {
if((errno == ENOENT) && bad_path)
{
pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
if(!*ppdata)
return(ERROR(ERRDOS,ERRnomem));
- memset(pdata, 0, max_data_bytes);
+ memset((char *)pdata,'\0',max_data_bytes + 1024);
/* Realloc the params space */
params = *pparams = Realloc(*pparams, 10);
if(params == NULL)
return(ERROR(ERRDOS,ERRnomem));
- dptr_num = dptr_create(conn,directory, True ,SVAL(inbuf,smb_pid));
+ dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
if (dptr_num < 0)
return(UNIXERROR(ERRDOS,ERRbadfile));
/* Convert the formatted mask. */
mask_convert(mask);
-#if 0 /* JRA */
- /*
- * Now we have a working mask_match in util.c, I believe
- * we no longer need these hacks (in fact they break
- * things). JRA.
- */
-
- /* a special case for 16 bit apps */
- if (strequal(mask,"????????.???")) pstrcpy(mask,"*");
-
- /* handle broken clients that send us old 8.3 format */
- string_sub(mask,"????????","*");
- string_sub(mask,".???",".*");
-#endif /* JRA */
-
/* Save the wildcard match and attribs we are using on this directory -
needed as lanman2 assumes these are being saved between calls */
if(!(wcard = strdup(mask))) {
- dptr_close(dptr_num);
+ dptr_close(&dptr_num);
return(ERROR(ERRDOS,ERRnomem));
}
out_of_space = False;
for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
+ {
+ BOOL got_exact_match;
+
+ /* this is a heuristic to avoid seeking the dirptr except when
+ absolutely necessary. It allows for a filename of about 40 chars */
+ if (space_remaining < DIRLEN_GUESS && numentries > 0)
{
+ out_of_space = True;
+ finished = False;
+ }
+ else
+ {
+ finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
+ requires_resume_key,dont_descend,
+ &p,pdata,space_remaining, &out_of_space, &got_exact_match,
+ &last_name_off);
+ }
- /* this is a heuristic to avoid seeking the dirptr except when
- absolutely necessary. It allows for a filename of about 40 chars */
- if (space_remaining < DIRLEN_GUESS && numentries > 0)
- {
- out_of_space = True;
- finished = False;
- }
- else
- {
- finished =
- !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
- requires_resume_key,dont_descend,
- &p,pdata,space_remaining, &out_of_space,
- &last_name_off);
- }
+ if (finished && out_of_space)
+ finished = False;
- if (finished && out_of_space)
- finished = False;
+ if (!finished && !out_of_space)
+ numentries++;
- if (!finished && !out_of_space)
- numentries++;
- space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
- }
+ /*
+ * As an optimisation if we know we aren't looking
+ * for a wildcard name (ie. the name matches the wildcard exactly)
+ * then we can finish on any (first) match.
+ * This speeds up large directory searches. JRA.
+ */
+
+ if(got_exact_match)
+ finished = True;
+
+ space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
+ }
/* Check if we can close the dirptr */
if(close_after_first || (finished && close_if_end))
- {
- dptr_close(dptr_num);
- DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
- dptr_num = -1;
- }
+ {
+ DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
+ dptr_close(&dptr_num);
+ }
/*
* If there are no matching entries we must return ERRDOS/ERRbadfile -
*/
if(numentries == 0)
+ {
+ dptr_close(&dptr_num);
return(ERROR(ERRDOS,ERRbadfile));
+ }
/* At this point pdata points to numentries directory entries. */
smb_fn_name(CVAL(inbuf,smb_com)),
mask, directory, dirtype, numentries ) );
+ /*
+ * Force a name mangle here to ensure that the
+ * mask as an 8.3 name is top of the mangled cache.
+ * The reasons for this are subtle. Don't remove
+ * this code unless you know what you are doing
+ * (see PR#13758). JRA.
+ */
+
+ if(!is_8_3( mask, False))
+ name_map_mangle(mask, True, True, SNUM(conn));
+
return(-1);
}
int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
char *params = *pparams;
char *pdata = *ppdata;
- int16 dptr_num = SVAL(params,0);
+ int dptr_num = SVAL(params,0);
int maxentries = SVAL(params,2);
uint16 info_level = SVAL(params,4);
uint32 resume_key = IVAL(params,6);
pdata = *ppdata = Realloc( *ppdata, max_data_bytes + 1024);
if(!*ppdata)
return(ERROR(ERRDOS,ERRnomem));
- memset(pdata, 0, max_data_bytes);
+ memset((char *)pdata,'\0',max_data_bytes + 1024);
/* Realloc the params space */
params = *pparams = Realloc(*pparams, 6*SIZEOFWORD);
*/
if(dname != NULL)
- name_map_mangle( dname, False, SNUM(conn));
+ name_map_mangle( dname, False, True, SNUM(conn));
if(dname && strcsequal( resume_name, dname))
{
*/
if(dname != NULL)
- name_map_mangle( dname, False, SNUM(conn));
+ name_map_mangle( dname, False, True, SNUM(conn));
if(dname && strcsequal( resume_name, dname))
{
} /* end if requires_resume_key && !continue_bit */
for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
+ {
+ BOOL got_exact_match;
+
+ /* this is a heuristic to avoid seeking the dirptr except when
+ absolutely necessary. It allows for a filename of about 40 chars */
+ if (space_remaining < DIRLEN_GUESS && numentries > 0)
{
- /* this is a heuristic to avoid seeking the dirptr except when
- absolutely necessary. It allows for a filename of about 40 chars */
- if (space_remaining < DIRLEN_GUESS && numentries > 0)
- {
- out_of_space = True;
- finished = False;
- }
- else
- {
- finished =
- !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
- requires_resume_key,dont_descend,
- &p,pdata,space_remaining, &out_of_space,
- &last_name_off);
- }
+ out_of_space = True;
+ finished = False;
+ }
+ else
+ {
+ finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
+ requires_resume_key,dont_descend,
+ &p,pdata,space_remaining, &out_of_space, &got_exact_match,
+ &last_name_off);
+ }
- if (finished && out_of_space)
- finished = False;
+ if (finished && out_of_space)
+ finished = False;
- if (!finished && !out_of_space)
- numentries++;
- space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
- }
+ if (!finished && !out_of_space)
+ numentries++;
+
+ /*
+ * As an optimisation if we know we aren't looking
+ * for a wildcard name (ie. the name matches the wildcard exactly)
+ * then we can finish on any (first) match.
+ * This speeds up large directory searches. JRA.
+ */
+
+ if(got_exact_match)
+ finished = True;
+
+ space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
+ }
/* Check if we can close the dirptr */
if(close_after_request || (finished && close_if_end))
- {
- dptr_close(dptr_num); /* This frees up the saved mask */
- DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
- dptr_num = -1;
- }
+ {
+ DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
+ dptr_close(&dptr_num); /* This frees up the saved mask */
+ }
/* Set up the return parameter block */
int length, int bufsize,
char **pparams, char **ppdata)
{
+ int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
char *pdata = *ppdata;
char *params = *pparams;
uint16 info_level = SVAL(params,0);
char *vname = volume_label(SNUM(conn));
int snum = SNUM(conn);
char *fstype = lp_fstype(SNUM(conn));
- extern uint32 global_client_caps;
DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
return (ERROR(ERRSRV,ERRinvdevice));
}
- pdata = *ppdata = Realloc(*ppdata, 1024); memset(pdata, 0, 1024);
+ pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
+ memset((char *)pdata,'\0',max_data_bytes + 1024);
switch (info_level)
{
{
SMB_BIG_UINT dfree,dsize,bsize;
data_len = 18;
- conn->vfs_ops.disk_free(".",&bsize,&dfree,&dsize);
+ conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize);
SIVAL(pdata,l1_idFileSystem,st.st_dev);
SIVAL(pdata,l1_cSectorUnit,bsize/512);
SIVAL(pdata,l1_cUnit,dsize);
break;
}
case SMB_QUERY_FS_ATTRIBUTE_INFO:
- data_len = 12 + 2*strlen(fstype);
- SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH); /* FS ATTRIBUTES */
+ {
+ int fstype_len;
+ SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
+ FILE_DEVICE_IS_MOUNTED|
+ (lp_nt_acl_support() ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
#if 0 /* Old code. JRA. */
SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
#endif /* Old code. */
+
SIVAL(pdata,4,128); /* Max filename component length */
- SIVAL(pdata,8,2*strlen(fstype));
- ascii_to_unibuf(pdata+12, fstype, 1024-2-12);
+ fstype_len = dos_PutUniCode(pdata+12,unix_to_dos(fstype,False),sizeof(pstring), False);
+ SIVAL(pdata,8,fstype_len);
+ data_len = 12 + fstype_len;
SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
break;
+ }
case SMB_QUERY_FS_LABEL_INFO:
data_len = 4 + strlen(vname);
SIVAL(pdata,0,strlen(vname));
/* NT4 always serves this up as unicode but expects it to be
* delivered as ascii! (tridge && JRA)
*/
- if (global_client_caps & CAP_NT_SMBS) {
+ if ((get_remote_arch() != RA_WIN2K) && (global_client_caps & CAP_NT_SMBS)) {
data_len = 18 + strlen(vname);
SIVAL(pdata,12,strlen(vname));
pstrcpy(pdata+18,vname);
} else {
data_len = 18 + 2*strlen(vname);
SIVAL(pdata,12,strlen(vname)*2);
- ascii_to_unibuf(pdata+18, vname, 1024-2-18);
+ dos_PutUniCode(pdata+18,unix_to_dos(vname,False),sizeof(pstring), False);
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
}
DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n",
- strlen(vname),vname));
+ (int)strlen(vname),vname));
break;
case SMB_QUERY_FS_SIZE_INFO:
{
SMB_BIG_UINT dfree,dsize,bsize;
data_len = 24;
- conn->vfs_ops.disk_free(".",&bsize,&dfree,&dsize);
- SIVAL(pdata,0,dsize);
- SIVAL(pdata,8,dfree);
+ conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize);
+ SBIG_UINT(pdata,0,dsize);
+ SBIG_UINT(pdata,8,dfree);
SIVAL(pdata,16,bsize/512);
SIVAL(pdata,20,512);
break;
char **pparams,char **ppdata,
int total_data)
{
+ int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
char *params = *pparams;
char *pdata = *ppdata;
uint16 tran_call = SVAL(inbuf, smb_setup0);
files_struct *fsp = file_fsp(params,0);
info_level = SVAL(params,2);
- if(fsp && fsp->open && fsp->is_directory) {
+ DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
+
+ if(fsp && fsp->open && (fsp->is_directory || fsp->stat_open)) {
/*
* This is actually a QFILEINFO on a directory
* handle (returned from an NT SMB). NT5.0 seems
* to do this call. JRA.
*/
fname = fsp->fsp_name;
- if (!unix_dfs_convert(fname,conn,0,&bad_path,&sbuf))
- {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
- }
- if (!check_name(fname,conn) || (!VALID_STAT(sbuf) &&
- conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
+ unix_convert(fname,conn,0,&bad_path,&sbuf);
+ if (!check_name(fname,conn) ||
+ (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
if((errno == ENOENT) && bad_path)
{
}
return(UNIXERROR(ERRDOS,ERRbadpath));
}
+
+ delete_pending = fsp->directory_delete_on_close;
+
} else {
/*
* Original code - this is an open file.
} else {
/* qpathinfo */
info_level = SVAL(params,0);
+
+ DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
+
fname = &fname1[0];
pstrcpy(fname,¶ms[6]);
- if (!unix_dfs_convert(fname,conn,0,&bad_path,&sbuf))
- {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
- }
+
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
+ unix_convert(fname,conn,0,&bad_path,&sbuf);
if (!check_name(fname,conn) ||
- (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),
- &sbuf))) {
+ (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
if((errno == ENOENT) && bad_path)
{
/* from now on we only want the part after the / */
fname = p;
- params = *pparams = Realloc(*pparams,2); memset(params, 0, 2);
- data_size = 1024;
+ params = *pparams = Realloc(*pparams,2);
+ memset((char *)params,'\0',2);
+ data_size = max_data_bytes + 1024;
pdata = *ppdata = Realloc(*ppdata, data_size);
if (total_data > 0 && IVAL(pdata,0) == total_data) {
return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
}
- memset(pdata, 0, data_size);
+ memset((char *)pdata,'\0',data_size);
switch (info_level)
{
case SMB_QUERY_FILE_ALT_NAME_INFO:
{
pstring short_name;
- char *data_end;
-
pstrcpy(short_name,p);
/* Mangle if not already 8.3 */
if(!is_8_3(short_name, True))
{
- if(!name_map_mangle(short_name,True,SNUM(conn)))
+ if(!name_map_mangle(short_name,True,True,SNUM(conn)))
*short_name = '\0';
}
strupper(short_name);
- data_end = ascii_to_unibuf(pdata + 4, short_name, 1024-2-4);
- data_size = data_end - pdata;
- SIVAL(pdata,0,2*(data_size-4));
+ l = strlen(short_name);
+ dos_PutUniCode(pdata + 4, unix_to_dos(short_name,False),sizeof(pstring), False);
+ data_size = 4 + (2*l);
+ SIVAL(pdata,0,2*l);
}
break;
case SMB_QUERY_FILE_NAME_INFO:
+ /*
+ * The first part of this code is essential
+ * to get security descriptors to work on mapped
+ * drives. Don't ask how I discovered this unless
+ * you like hearing about me suffering.... :-). JRA.
+ */
+ if(strequal(".", fname) && (global_client_caps & CAP_UNICODE)) {
+ l = l*2;
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
+ dos_PutUniCode(pdata + 4, unix_to_dos("\\",False),sizeof(pstring), False);
+ } else {
+ pstrcpy(pdata+4,fname);
+ }
data_size = 4 + l;
SIVAL(pdata,0,l);
- pstrcpy(pdata+4,fname);
break;
case SMB_QUERY_FILE_ALLOCATION_INFO:
fsp = file_fsp(params,0);
info_level = SVAL(params,2);
- if(fsp && fsp->open && fsp->is_directory) {
+ if(fsp && fsp->open && (fsp->is_directory || fsp->stat_open)) {
/*
* This is actually a SETFILEINFO on a directory
* handle (returned from an NT SMB). NT5.0 seems
* to do this call. JRA.
*/
fname = fsp->fsp_name;
- if (!unix_dfs_convert(fname,conn,0,&bad_path,&st))
- {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
- }
- if (!check_name(fname,conn) || (!VALID_STAT(st) &&
- conn->vfs_ops.stat(dos_to_unix(fname,False),&st))) {
+ unix_convert(fname,conn,0,&bad_path,&st);
+ if (!check_name(fname,conn) ||
+ (!VALID_STAT(st) && conn->vfs_ops.stat(dos_to_unix(fname,False),&st))) {
DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
if((errno == ENOENT) && bad_path)
{
info_level = SVAL(params,0);
fname = fname1;
pstrcpy(fname,¶ms[6]);
- if (!unix_dfs_convert(fname,conn,0,&bad_path,&st))
- {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
- }
+ unix_convert(fname,conn,0,&bad_path,&st);
if(!check_name(fname, conn))
{
if((errno == ENOENT) && bad_path)
tran_call,fname,info_level,total_data));
/* Realloc the parameter and data sizes */
- params = *pparams = Realloc(*pparams,2); SSVAL(params,0,0);
+ params = *pparams = Realloc(*pparams,2);
if(params == NULL)
return(ERROR(ERRDOS,ERRnomem));
+ SSVAL(params,0,0);
+
size = st.st_size;
tvs.modtime = st.st_mtime;
tvs.actime = st.st_atime;
case SMB_SET_FILE_BASIC_INFO:
{
+ /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
+ time_t write_time;
+ time_t changed_time;
+
/* Ignore create time at offset pdata. */
/* access time */
tvs.actime = interpret_long_date(pdata+8);
- /* write time + changed time, combined. */
- tvs.modtime=MAX(interpret_long_date(pdata+16),
- interpret_long_date(pdata+24));
+ write_time = interpret_long_date(pdata+16);
+ changed_time = interpret_long_date(pdata+24);
+
+ tvs.modtime = MIN(write_time, changed_time);
+
+ /* Prefer a defined time to an undefined one. */
+ if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
+ tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
+ ? changed_time
+ : write_time);
#if 0 /* Needs more testing... */
/* Test from Luke to prevent Win95 from
break;
}
+ /*
+ * NT seems to use this call with a size of zero
+ * to mean truncate the file. JRA.
+ */
+
+ case SMB_SET_FILE_ALLOCATION_INFO:
+ {
+ SMB_OFF_T newsize = IVAL(pdata,0);
+#ifdef LARGE_SMB_OFF_T
+ newsize |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
+#else /* LARGE_SMB_OFF_T */
+ if (IVAL(pdata,4) != 0) /* more than 32 bits? */
+ return(ERROR(ERRDOS,ERRunknownlevel));
+#endif /* LARGE_SMB_OFF_T */
+ DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n", fname, (double)newsize ));
+ if(newsize == 0)
+ size = 0;
+ break;
+ }
+
case SMB_SET_FILE_END_OF_FILE_INFO:
{
size = IVAL(pdata,0);
if (IVAL(pdata,4) != 0) /* more than 32 bits? */
return(ERROR(ERRDOS,ERRunknownlevel));
#endif /* LARGE_SMB_OFF_T */
+ DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
break;
}
- case SMB_SET_FILE_ALLOCATION_INFO:
- break; /* We don't need to do anything for this call. */
-
case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
{
if ((tran_call == TRANSACT2_SETFILEINFO) && (fsp != NULL))
BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
if(fsp->is_directory)
- return(ERROR(ERRDOS,ERRnoaccess));
-
- /*
- * We can only set the delete on close flag if
- * the share mode contained ALLOW_SHARE_DELETE
- */
+ {
+ fsp->directory_delete_on_close = delete_on_close;
+ DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, directory %s\n",
+ delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
- if(lp_share_modes(SNUM(conn)))
+ }
+ else if(fsp->stat_open)
+ {
+ DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, stat open %s\n",
+ delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
+ }
+ else
{
- if(!GET_ALLOW_SHARE_DELETE(fsp->share_mode))
- return(ERROR(ERRDOS,ERRnoaccess));
/*
- * If the flag has been set then
- * modify the share mode entry for all files we have open
- * on this device and inode to tell other smbds we have
- * changed the delete on close flag.
+ * We can only set the delete on close flag if
+ * the share mode contained ALLOW_SHARE_DELETE
*/
- if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode))
+ if(lp_share_modes(SNUM(conn)))
{
- int i;
- files_struct *iterate_fsp;
- SMB_DEV_T dev = fsp->fd_ptr->dev;
- SMB_INO_T inode = fsp->fd_ptr->inode;
- int num_share_modes;
- share_mode_entry *current_shares = NULL;
-
- if(lock_share_entry(fsp->conn, dev, inode) == False)
+ if(!GET_ALLOW_SHARE_DELETE(fsp->share_mode))
return(ERROR(ERRDOS,ERRnoaccess));
/*
- * Before we allow this we need to ensure that all current opens
- * on the file have the GET_ALLOW_SHARE_DELETE flag set. If they
- * do not then we deny this (as we are essentially deleting the
- * file at this point.
+ * If the flag has been set then
+ * modify the share mode entry for all files we have open
+ * on this device and inode to tell other smbds we have
+ * changed the delete on close flag.
*/
- num_share_modes = get_share_modes(conn, dev, inode, ¤t_shares);
- for(i = 0; i < num_share_modes; i++)
+ if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode))
{
- if(!GET_ALLOW_SHARE_DELETE(current_shares[i].share_mode))
+ int i;
+ files_struct *iterate_fsp;
+ SMB_DEV_T dev = fsp->fd_ptr->dev;
+ SMB_INO_T inode = fsp->fd_ptr->inode;
+ int num_share_modes;
+ share_mode_entry *current_shares = NULL;
+
+ if(lock_share_entry(fsp->conn, dev, inode) == False)
+ return(ERROR(ERRDOS,ERRnoaccess));
+
+ /*
+ * Before we allow this we need to ensure that all current opens
+ * on the file have the GET_ALLOW_SHARE_DELETE flag set. If they
+ * do not then we deny this (as we are essentially deleting the
+ * file at this point.
+ */
+
+ num_share_modes = get_share_modes(conn, dev, inode, ¤t_shares);
+ for(i = 0; i < num_share_modes; i++)
{
- DEBUG(5,("call_trans2setfilepathinfo: refusing to set delete on close flag for fnum = %d, \
+ if(!GET_ALLOW_SHARE_DELETE(current_shares[i].share_mode))
+ {
+ DEBUG(5,("call_trans2setfilepathinfo: refusing to set delete on close flag for fnum = %d, \
file %s as a share exists that was not opened with FILE_DELETE access.\n",
- fsp->fnum, fsp->fsp_name ));
- /*
- * Release the lock.
- */
+ fsp->fnum, fsp->fsp_name ));
+ /*
+ * Release the lock.
+ */
- unlock_share_entry(fsp->conn, dev, inode);
+ unlock_share_entry(fsp->conn, dev, inode);
- /*
- * current_shares was malloced by get_share_modes - free it here.
- */
+ /*
+ * current_shares was malloced by get_share_modes - free it here.
+ */
- free((char *)current_shares);
+ free((char *)current_shares);
- /*
- * Even though share violation would be more appropriate here,
- * return ERRnoaccess as that's what NT does.
- */
+ /*
+ * Even though share violation would be more appropriate here,
+ * return ERRnoaccess as that's what NT does.
+ */
- return(ERROR(ERRDOS,ERRnoaccess));
+ return(ERROR(ERRDOS,ERRnoaccess));
+ }
}
- }
- /*
- * current_shares was malloced by get_share_modes - free it here.
- */
+ /*
+ * current_shares was malloced by get_share_modes - free it here.
+ */
- free((char *)current_shares);
+ free((char *)current_shares);
- DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
- delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
+ DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
+ delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
- /*
- * Go through all files we have open on the same device and
- * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
- * Other smbd's that have this file open will have to fend for themselves. We
- * take care of this (rare) case in close_file(). See the comment there.
- */
+ /*
+ * Go through all files we have open on the same device and
+ * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
+ * Other smbd's that have this file open will have to fend for themselves. We
+ * take care of this (rare) case in close_file(). See the comment there.
+ */
- for(iterate_fsp = file_find_di_first(dev, inode); iterate_fsp;
- iterate_fsp = file_find_di_next(iterate_fsp))
- {
- int new_share_mode = (delete_on_close ?
- (iterate_fsp->share_mode | DELETE_ON_CLOSE_FLAG) :
- (iterate_fsp->share_mode & ~DELETE_ON_CLOSE_FLAG) );
+ for(iterate_fsp = file_find_di_first(dev, inode); iterate_fsp;
+ iterate_fsp = file_find_di_next(iterate_fsp))
+ {
+ int new_share_mode = (delete_on_close ?
+ (iterate_fsp->share_mode | DELETE_ON_CLOSE_FLAG) :
+ (iterate_fsp->share_mode & ~DELETE_ON_CLOSE_FLAG) );
- DEBUG(10,("call_trans2setfilepathinfo: Changing share mode for fnum %d, file %s \
+ DEBUG(10,("call_trans2setfilepathinfo: Changing share mode for fnum %d, file %s \
dev = %x, inode = %.0f from %x to %x\n",
- iterate_fsp->fnum, iterate_fsp->fsp_name, (unsigned int)dev,
- (double)inode, iterate_fsp->share_mode, new_share_mode ));
+ iterate_fsp->fnum, iterate_fsp->fsp_name, (unsigned int)dev,
+ (double)inode, iterate_fsp->share_mode, new_share_mode ));
- if(modify_share_mode(iterate_fsp, new_share_mode,
- iterate_fsp->granted_oplock ? LEVEL_II_OPLOCK : NO_OPLOCK)==False)
- DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close for fnum %d, \
+ if(modify_share_mode(iterate_fsp, new_share_mode, iterate_fsp->oplock_type)==False)
+ DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close for fnum %d, \
dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode));
- }
+ }
- /*
- * Set the delete on close flag in the reference
- * counted struct. Delete when the last reference
- * goes away.
- */
- fsp->fd_ptr->delete_on_close = delete_on_close;
- unlock_share_entry(fsp->conn, dev, inode);
+ /*
+ * Set the delete on close flag in the reference
+ * counted struct. Delete when the last reference
+ * goes away.
+ */
+ fsp->fd_ptr->delete_on_close = delete_on_close;
- DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
- delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
+ unlock_share_entry(fsp->conn, dev, inode);
- } /* end if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode)) */
- } /* end if lp_share_modes() */
+ DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
+ delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
+ } /* end if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode)) */
+ } /* end if lp_share_modes() */
+ } /* end if is_directory. */
} else
return(ERROR(ERRDOS,ERRunknownlevel));
break;
}
}
+ /* get some defaults (no modifications) if any info is zero or -1. */
+ if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
+ tvs.actime = st.st_atime;
+
+ if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
+ tvs.modtime = st.st_mtime;
+
DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
DEBUG(6,("size: %.0f ", (double)size));
DEBUG(6,("mode: %x\n" , mode));
- /* get some defaults (no modifications) if any info is zero. */
- if (!tvs.actime) tvs.actime = st.st_atime;
- if (!tvs.modtime) tvs.modtime = st.st_mtime;
- if (!size) size = st.st_size;
+ if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
+ (info_level == SMB_SET_FILE_ALLOCATION_INFO))) {
+ /*
+ * Only do this test if we are not explicitly
+ * changing the size of a file.
+ */
+ if (!size)
+ size = st.st_size;
+ }
/* Try and set the times, size and mode of this file -
if they are different from the current values
*/
- if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime)
- {
- if(fsp != NULL)
- {
+ if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime) {
+ if(fsp != NULL) {
/*
* This was a setfileinfo on an open file.
* NT does this a lot. It's actually pointless
* on the next write, so we save the request
* away and will set it on file code. JRA.
*/
- fsp->pending_modtime = tvs.modtime;
- }
- else if(file_utime(conn, fname, &tvs)!=0)
- {
- return(UNIXERROR(ERRDOS,ERRnoaccess));
+
+ if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
+ DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
+ ctime(&tvs.modtime) ));
+ fsp->pending_modtime = tvs.modtime;
+ }
+
+ } else {
+
+ DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
+
+ if(file_utime(conn, fname, &tvs)!=0)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
}
}
/* check the mode isn't different, before changing it */
- if (mode != dos_mode(conn, fname, &st) && file_chmod(conn, fname, mode, NULL))
- {
- DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
- return(UNIXERROR(ERRDOS,ERRnoaccess));
+ if ((mode != 0) && (mode != dos_mode(conn, fname, &st))) {
+
+ DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
+ fname, mode ));
+
+ if(file_chmod(conn, fname, mode, NULL)) {
+ DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
}
- if(size != st.st_size)
- {
- if (fd == -1)
- {
-DEBUG(0, ("@@@ 23 @@@\n"));
- fd = dos_open(fname,O_RDWR,0);
+ if(size != st.st_size) {
+
+ DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
+ fname, (double)size ));
+
+ if (fd == -1) {
+ fd = conn->vfs_ops.open(dos_to_unix(fname,False),O_RDWR,0);
if (fd == -1)
- {
return(UNIXERROR(ERRDOS,ERRbadpath));
- }
- set_filelen(fd, size);
- close(fd);
- }
- else
- {
- set_filelen(fd, size);
+ set_filelen(fd, size); /* tpot vfs */
+ conn->vfs_ops.close(fd);
+ } else {
+ set_filelen(fd, size); /* tpot vfs */
}
+
+ if(fsp)
+ set_filelen_write_cache(fsp, size);
}
SSVAL(params,0,0);
DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
- if (!unix_dfs_convert(directory,conn,0,&bad_path,NULL))
- {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
- }
+ unix_convert(directory,conn,0,&bad_path,NULL);
if (check_name(directory,conn))
ret = conn->vfs_ops.mkdir(dos_to_unix(directory,False),
- unix_mode(conn,aDIR));
+ unix_mode(conn,aDIR,directory));
if(ret < 0)
{
return(-1);
}
+/****************************************************************************
+ reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>
+****************************************************************************/
+static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
+ char* outbuf, int length, int bufsize,
+ char** pparams, char** ppdata)
+{
+ char *params = *pparams;
+ enum remote_arch_types ra_type = get_remote_arch();
+ BOOL NT_arch = ((ra_type == RA_WINNT) || (ra_type == RA_WIN2K));
+ pstring pathname;
+ int reply_size = 0;
+ int max_referral_level = SVAL(params,0);
+
+
+ DEBUG(10,("call_trans2getdfsreferral\n"));
+
+ if(!lp_host_msdfs())
+ return(ERROR(ERRDOS,ERRbadfunc));
+
+ /* if pathname is in UNICODE, convert to DOS */
+ /* NT always sends in UNICODE, may not set UNICODE flag */
+ if(NT_arch || (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS))
+ {
+ unistr_to_dos(pathname, ¶ms[2]);
+ DEBUG(10,("UNICODE referral for %s\n",pathname));
+ }
+ else
+ pstrcpy(pathname,¶ms[2]);
+
+ if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
+ return(ERROR(ERRDOS,ERRbadfile));
+
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_UNICODE_STRINGS |
+ FLAGS2_DFS_PATHNAMES);
+ send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
+
+ return(-1);
+}
+
+
/****************************************************************************
reply to a SMBfindclose (stop trans2 directory search)
****************************************************************************/
char *inbuf,char *outbuf,int length,int bufsize)
{
int outsize = 0;
- int16 dptr_num=SVALS(inbuf,smb_vwv0);
+ int dptr_num=SVALS(inbuf,smb_vwv0);
DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
- dptr_close(dptr_num);
+ dptr_close(&dptr_num);
outsize = set_message(outbuf,0,0,True);
return(outsize);
}
-#define UNICODE_DFS
-
-/****************************************************************************
- reply to a TRANS2_GET_DFS_REFERRAL
- ****************************************************************************/
-static int call_trans2getdfsreferral(connection_struct *conn,
- char *inbuf, char *outbuf, int length,
- int bufsize,
- char **pparams, char **ppdata,
- int total_data)
-{
- char *params = *pparams;
- char *pdata;
- char *pheader;
- char *localstring_offset;
- char *mangledstring_offset;
- char *sharename_offset;
- char *referal_offset;
-
- int i;
- int j;
- unsigned int total_params = SVAL(inbuf, smb_tpscnt);
- int query_file_len=0;
- int bytesreq=0;
- int filename_len;
-
- BOOL first_one=True;
-
- referal_trans_param rtp;
- dfs_internal_table *list=dfs_struct.table;
- dfs_response reply;
-
- DEBUG(0,("call_trans2getdfsreferral:1\n"));
-
- ZERO_STRUCT(rtp);
- ZERO_STRUCT(reply);
-
- /* decode the param member of query */
- rtp.level=SVAL(params, 0);
- DEBUGADD(0,("rtp.level:[%d]\n",rtp.level));
-
- DEBUGADD(0,("total_params:[%d]\n",total_params));
- for (i=0; i<(total_params-2)/2; i++)
- {
- rtp.directory[i]=SVAL(params, 2+2*i);
- }
-/*
- strupper(rtp.directory);
-*/
- query_file_len=strlen(rtp.directory);
- DEBUGADD(0,("rtp.directory:[%s]\n",rtp.directory));
- DEBUGADD(0,("query_file_len:[%d]\n",query_file_len));
-
- /*
- lookup in the internal DFS table all the entries
- and calculate the required data buffer size
- */
- bytesreq=8; /* the header */
- reply.number_of_referal=0;
- DEBUGADD(0,("call_trans2getdfsreferral:2\n"));
-
- for(i=0; i<dfs_struct.size; i++)
- {
- filename_len=list[i].localpath_length;
- DEBUGADD(0,("checking against [%s][%d]\n", list[i].localpath, filename_len));
-
- if( (filename_len==query_file_len) &&
- (!StrnCaseCmp(rtp.directory, list[i].localpath, query_file_len)) )
- {
-
- bytesreq+=22; /* the referal size */
- bytesreq+=2*(list[i].sharename_length+1); /* the string length */
- reply.number_of_referal++;
- DEBUGADD(0,("found\n"));
-
- if (first_one) {
- DEBUGADD(0,("first one\n"));
- bytesreq+=2*(list[i].localpath_length+1);
- bytesreq+=2*(list[i].mangledpath_length+1);
-
- reply.path_consumed=list[i].localpath_length;
-
- strncpy(reply.filename, list[i].localpath, list[i].localpath_length+1);
- strncpy(reply.mangledname, list[i].mangledpath, list[i].mangledpath_length+1);
- rtp.type=list[i].type;
- first_one=False;
- }
- }
- }
- DEBUGADD(0,("call_trans2getdfsreferral:3\n"));
-
- /* allocate memory for the reply data */
- pdata = *ppdata = Realloc(*ppdata, bytesreq + 1024);
- memset(*ppdata, 0, bytesreq+22);
-
- pdata = *ppdata;
- pheader = pdata;
-
- localstring_offset = pdata + 8 + reply.number_of_referal*22;
-
-#ifdef UNICODE_DFS
- mangledstring_offset = localstring_offset + 2*(1+strlen(reply.filename));
- sharename_offset = mangledstring_offset + 2*(1+strlen(reply.mangledname));
-
-#else
- mangledstring_offset = localstring_offset + (1+strlen(reply.filename));
- sharename_offset = mangledstring_offset + (1+strlen(reply.mangledname));
-#endif
- referal_offset = pdata + 8;
-
- /* right now respond storage server */
-/*
- reply.server_function=rtp.type;
-*/
- reply.server_function=0x3;
-
- /* write the header */
-#ifdef UNICODE_DFS
- SSVAL(pheader, 0, reply.path_consumed*2);
-#else
- SSVAL(pheader, 0, reply.path_consumed);
-#endif
- SSVAL(pheader, 2, reply.number_of_referal);
- SIVAL(pheader, 4, reply.server_function);
-
- /* write the local path string */
-#ifdef UNICODE_DFS
- for(i=0; i<strlen(reply.filename); i++)
- {
- SSVAL(localstring_offset, 2*i, (uint16) reply.filename[i]);
- }
- SSVAL(localstring_offset, 2*strlen(reply.filename), 0);
-#else
-
- for(i=0; i<strlen(reply.filename); i++)
- {
- localstring_offset[i]=reply.filename[i];
- }
- localstring_offset[strlen(reply.filename)]=0;
-#endif
- DEBUG(0,("reply.filename is [%s]:[%d], i is [%d]\n", reply.filename, strlen(reply.filename), i));
-
- /* write the mangled local path string */
-#ifdef UNICODE_DFS
- for(i=0; i<strlen(reply.mangledname); i++)
- {
- SSVAL(mangledstring_offset, 2*i, (uint16) reply.mangledname[i]);
- }
- SSVAL(mangledstring_offset, 2*i, 0);
-#else
- for(i=0; i<strlen(reply.mangledname); i++)
- {
- mangledstring_offset[i]=reply.mangledname[i];
- }
- mangledstring_offset[i]=0;
-#endif
- DEBUGADD(0,("call_trans2getdfsreferral:4\n"));
-
- /* the order of the referals defines the load balancing */
-
- /* write each referal */
- for(i=0; i<dfs_struct.size; i++)
- {
- filename_len=list[i].localpath_length;
-
- if(filename_len==query_file_len &&
- !strncasecmp(rtp.directory, list[i].localpath, query_file_len))
- {
-
- SSVAL(referal_offset, 0, 2); /* version */
- SSVAL(referal_offset, 2, 22); /* size */
-
- if (rtp.type==3)
- SSVAL(referal_offset, 4, 1); /* type SMB server*/
- else
- SSVAL(referal_offset, 4, 0); /* type unknown */
- SSVAL(referal_offset, 6, 1); /* flags */
- SIVAL(referal_offset, 8, list[i].proximity); /* proximity */
- SIVAL(referal_offset, 12, 300); /* ttl */
- SSVAL(referal_offset, 16, localstring_offset-referal_offset);
- SSVAL(referal_offset, 18, mangledstring_offset-referal_offset);
- SSVAL(referal_offset, 20, sharename_offset-referal_offset);
-
-#ifdef UNICODE_DFS
- for(j=0; j<list[i].sharename_length; j++)
- {
- SSVAL(sharename_offset, 2*j, (uint16) list[i].sharename[j]);
- }
- SSVAL(sharename_offset, 2*j, 0);
-
- sharename_offset=sharename_offset + 2*(1+list[i].sharename_length);
-#else
- for(j=0; j<list[i].sharename_length; j++)
- {
- sharename_offset[j]=list[i].sharename[j];
- }
- sharename_offset[j]=0;
-
- sharename_offset=sharename_offset + (1+list[i].sharename_length);
-#endif
-
- referal_offset=referal_offset+22;
- }
- }
-
- DEBUGADD(0,("call_trans2getdfsreferral:5\n"));
-
- send_trans2_replies(outbuf, bufsize, params, 0, *ppdata, bytesreq+22);
-
-/* send_trans2_replies(outbuf, bufsize, *ppdata, bytesreq, params, 0);*/
- DEBUGADD(0,("call_trans2getdfsreferral:6\n"));
-
- return(-1);
-}
-
-
-/****************************************************************************
-reply to a TRANS2_REPORT_DFS_INCONSISTANCY
-****************************************************************************/
-static int call_trans2reportdfsinconsistancy(connection_struct *conn,
- char *inbuf, char *outbuf, int length,
- int bufsize,
- char **pparams, char **ppdata)
-{
- char *params = *pparams;
-
- DEBUG(4,("call_trans2reportdfsinconsistancy\n"));
- send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
- return(-1);
-}
-
/****************************************************************************
reply to a SMBtranss2 - just ignore it!
}
/* Now we must call the relevant TRANS2 function */
- switch(tran_call)
- {
- case TRANSACT2_OPEN:
- {
- outsize = call_trans2open(conn,
+ switch(tran_call) {
+ case TRANSACT2_OPEN:
+ outsize = call_trans2open(conn,
inbuf, outbuf, bufsize,
¶ms, &data);
- break;
- }
- case TRANSACT2_FINDFIRST:
- {
- outsize = call_trans2findfirst(conn, inbuf, outbuf,
- bufsize, ¶ms, &data);
- break;
- }
- case TRANSACT2_FINDNEXT:
- {
- outsize = call_trans2findnext(conn, inbuf, outbuf,
- length, bufsize,
- ¶ms, &data);
- break;
- }
- case TRANSACT2_QFSINFO:
- {
- outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
- length, bufsize, ¶ms,
- &data);
- break;
- }
- case TRANSACT2_SETFSINFO:
- {
- outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
- length, bufsize,
- ¶ms, &data);
- break;
- }
- case TRANSACT2_QPATHINFO:
- case TRANSACT2_QFILEINFO:
- {
- outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
- length, bufsize,
- ¶ms, &data, total_data);
- break;
- }
- case TRANSACT2_SETPATHINFO:
- case TRANSACT2_SETFILEINFO:
- {
- outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
- length, bufsize,
- ¶ms, &data,
- total_data);
- break;
- }
- case TRANSACT2_FINDNOTIFYFIRST:
- {
- outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
- length, bufsize,
- ¶ms, &data);
- break;
- }
- case TRANSACT2_FINDNOTIFYNEXT:
- {
- outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
- length, bufsize,
- ¶ms, &data);
- break;
- }
- case TRANSACT2_MKDIR:
- {
- outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
- bufsize, ¶ms, &data);
- break;
- }
- case TRANSACT2_GET_DFS_REFERRAL:
- {
- outsize = call_trans2getdfsreferral(conn, inbuf, outbuf,
- length, bufsize, ¶ms,
- &data, total_data);
- break;
- }
- case TRANSACT2_REPORT_DFS_INCONSISTANCY:
- {
- outsize = call_trans2reportdfsinconsistancy(conn, inbuf, outbuf,
- length, bufsize,
- ¶ms, &data);
- break;
- }
- default:
- {
- /* Error in request */
- DEBUG(2,("Unknown request %d in trans2 call\n",
- tran_call));
- if(params)
- free(params);
- if(data)
- free(data);
- return (ERROR(ERRSRV,ERRerror));
- }
+ break;
+
+ case TRANSACT2_FINDFIRST:
+ outsize = call_trans2findfirst(conn, inbuf, outbuf,
+ bufsize, ¶ms, &data);
+ break;
+
+ case TRANSACT2_FINDNEXT:
+ outsize = call_trans2findnext(conn, inbuf, outbuf,
+ length, bufsize,
+ ¶ms, &data);
+ break;
+
+ case TRANSACT2_QFSINFO:
+ outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
+ length, bufsize, ¶ms,
+ &data);
+ break;
+
+ case TRANSACT2_SETFSINFO:
+ outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
+ length, bufsize,
+ ¶ms, &data);
+ break;
+
+ case TRANSACT2_QPATHINFO:
+ case TRANSACT2_QFILEINFO:
+ outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
+ length, bufsize,
+ ¶ms, &data, total_data);
+ break;
+ case TRANSACT2_SETPATHINFO:
+ case TRANSACT2_SETFILEINFO:
+ outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
+ length, bufsize,
+ ¶ms, &data,
+ total_data);
+ break;
+
+ case TRANSACT2_FINDNOTIFYFIRST:
+ outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
+ length, bufsize,
+ ¶ms, &data);
+ break;
+
+ case TRANSACT2_FINDNOTIFYNEXT:
+ outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
+ length, bufsize,
+ ¶ms, &data);
+ break;
+ case TRANSACT2_MKDIR:
+ outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
+ bufsize, ¶ms, &data);
+ break;
+
+ case TRANSACT2_GET_DFS_REFERRAL:
+ outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
+ bufsize, ¶ms, &data);
+ break;
+ default:
+ /* Error in request */
+ DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
+ if(params)
+ free(params);
+ if(data)
+ free(data);
+ return (ERROR(ERRSRV,ERRerror));
}
/* As we do not know how many data packets will need to be
call_trans2xxx calls have already sent
it. If outsize != -1 then it is returning */
}
-
/*
Unix SMB/Netbios implementation.
Version 1.9.
- Wrap disk only vfs functions to sidestep dodgy compilers.
+s Wrap disk only vfs functions to sidestep dodgy compilers.
Copyright (C) Tim Potter 1998
This program is free software; you can redistribute it and/or modify
/* Disk operations */
-SMB_BIG_UINT vfswrap_disk_free(char *path, SMB_BIG_UINT *bsize,
+SMB_BIG_UINT vfswrap_disk_free(char *path, BOOL small_query, SMB_BIG_UINT *bsize,
SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
SMB_BIG_UINT result;
}
#endif
- result = sys_disk_free(path, bsize, dfree, dsize);
+ result = sys_disk_free(path, small_query, bsize, dfree, dsize);
return result;
}
return result;
}
-void vfswrap_sync_file(int fd)
+void vfswrap_fsync(int fd)
{
- sys_sync_file(fd);
+ fsync(fd);
}
int vfswrap_stat(char *fname, SMB_STRUCT_STAT *sbuf)
return result;
}
-BOOL vfswrap_fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count,
- int type)
-{
- BOOL result;
-
- result = fcntl_lock(fd, op, offset, count, type);
- return result;
-}
-
int vfswrap_unlink(char *path)
{
int result;
*/
#include "includes.h"
-#ifdef HAVE_LIBDL
-#include <dlfcn.h>
-#endif
extern int DEBUGLEVEL;
vfswrap_write,
vfswrap_lseek,
vfswrap_rename,
- vfswrap_sync_file,
+ vfswrap_fsync,
vfswrap_stat,
vfswrap_fstat,
vfswrap_lstat,
- vfswrap_fcntl_lock,
vfswrap_unlink,
vfswrap_chmod,
vfswrap_utime
/* Open object file */
- handle = dlopen(lp_vfsobj(SNUM(conn)), RTLD_NOW);
+ handle = dlopen(lp_vfsobj(SNUM(conn)), RTLD_NOW | RTLD_GLOBAL);
+ conn->vfs_conn->dl_handle = handle;
+
if (!handle) {
DEBUG(0, ("Error opening %s: %s\n", lp_vfsobj(SNUM(conn)),
dlerror()));
/* Get handle on vfs_init() symbol */
fptr = dlsym(handle, "vfs_init");
+
if (fptr == NULL) {
DEBUG(0, ("No vfs_init() symbol found in %s\n",
lp_vfsobj(SNUM(conn))));
return False;
}
- dlclose(handle);
-
/* Initialise vfs_ops structure */
- if ((ops = fptr(lp_vfsoptions(SNUM(conn)))) == NULL) {
+ if ((ops = fptr(NULL)) == NULL) {
+ DEBUG(0, ("vfs_init function from %s failed\n", lp_vfsobj(SNUM(conn))));
return False;
}
conn->vfs_ops.rename = default_vfs_ops.rename;
}
- if (conn->vfs_ops.sync == NULL) {
- conn->vfs_ops.sync = default_vfs_ops.sync;
+ if (conn->vfs_ops.fsync == NULL) {
+ conn->vfs_ops.fsync = default_vfs_ops.fsync;
}
if (conn->vfs_ops.stat == NULL) {
conn->vfs_ops.lstat = default_vfs_ops.lstat;
}
- if (conn->vfs_ops.lock == NULL) {
- conn->vfs_ops.lock = default_vfs_ops.lock;
- }
-
if (conn->vfs_ops.unlink == NULL) {
conn->vfs_ops.unlink = default_vfs_ops.unlink;
}
}
#endif
+BOOL vfs_directory_exist(connection_struct *conn, char *dname,
+ SMB_STRUCT_STAT *st)
+{
+ SMB_STRUCT_STAT st2;
+ BOOL ret;
+
+ if (!st) st = &st2;
+
+ if (conn->vfs_ops.stat(dos_to_unix(dname,False),st) != 0)
+ return(False);
+
+ ret = S_ISDIR(st->st_mode);
+ if(!ret)
+ errno = ENOTDIR;
+
+ return ret;
+}
+
/*******************************************************************
check if a vfs file exists
********************************************************************/
unix_to_dos(dname, True);
return(dname);
}
+
+/* VFS options not quite working yet */
+
+#if 0
+
+/***************************************************************************
+ handle the interpretation of the vfs option parameter
+ *************************************************************************/
+static BOOL handle_vfs_option(char *pszParmValue, char **ptr)
+{
+ struct vfs_options *new_option, **options = (struct vfs_options **)ptr;
+ int i;
+
+ /* Create new vfs option */
+
+ new_option = (struct vfs_options *)malloc(sizeof(*new_option));
+ if (new_option == NULL) {
+ return False;
+ }
+
+ ZERO_STRUCTP(new_option);
+
+ /* Get name and value */
+
+ new_option->name = strtok(pszParmValue, "=");
+
+ if (new_option->name == NULL) {
+ return False;
+ }
+
+ while(isspace(*new_option->name)) {
+ new_option->name++;
+ }
+
+ for (i = strlen(new_option->name); i > 0; i--) {
+ if (!isspace(new_option->name[i - 1])) break;
+ }
+
+ new_option->name[i] = '\0';
+ new_option->name = strdup(new_option->name);
+
+ new_option->value = strtok(NULL, "=");
+
+ if (new_option->value != NULL) {
+
+ while(isspace(*new_option->value)) {
+ new_option->value++;
+ }
+
+ for (i = strlen(new_option->value); i > 0; i--) {
+ if (!isspace(new_option->value[i - 1])) break;
+ }
+
+ new_option->value[i] = '\0';
+ new_option->value = strdup(new_option->value);
+ }
+
+ /* Add to list */
+
+ DLIST_ADD(*options, new_option);
+
+ return True;
+}
+
+#endif
+
+.libs
*.po
*.po32
kernel_stat.h
return NULL;
}
- make_nmb_name(&calling, global_myname, 0x0
+ make_nmb_name(&calling, global_myname, 0x0);
make_nmb_name(&called , server, 0x20);
DEBUG(4,("server_n=[%s] server=[%s]\n", server_n, server));
if (!cli_session_request(&c, &calling, &called)) {
cli_shutdown(&c);
if (strcmp(called.name, "*SMBSERVER")) {
- make_nmb_name(&called , "*SMBSERVER", 0x20, "");
+ make_nmb_name(&called , "*SMBSERVER", 0x20);
goto again;
}
errno = ENOENT;
if (strstr(syscmd,"%s"))
{
pstrcpy(filename,filename1);
- string_sub(syscmd, "%s", filename);
+ pstring_sub(syscmd, "%s", filename);
}
- string_sub(syscmd, "%f", filename1);
+ pstring_sub(syscmd, "%f", filename1);
/* Does the service have a printername? If not, make a fake and empty
* printer name. That way a %p is treated sanely if no printer
tstr = SERVICE(snum);
}
- string_sub(syscmd, "%p", tstr);
+ pstring_sub(syscmd, "%p", tstr);
/* If the lpr command support the 'Job' option replace here */
- string_sub(syscmd, "%j", job_name);
+ pstring_sub(syscmd, "%j", job_name);
if ( *syscmd != '\0')
{
switch (info_level)
{
+ case 1:
+ {
+ ctr->info.id1 = g_new(SHARE_INFO_1, 1);
+ if (ctr->info.id1 == NULL)
+ {
+ return NT_STATUS_NO_MEMORY;
+ }
+ make_srv_share_1_info(&ctr->info.id1->info1_hdr,
+ &ctr->info.id1->info1_str,
+ snum);
+ return NT_STATUS_NOPROBLEMO;
+ }
case 2:
{
ctr->info.id2 = g_new(SHARE_INFO_2, 1);
+.libs
*.lo
tdbtool
tdbtest
*/
#define _PROTO_H_
#define _NAMESERV_H_
+#define _DEBUG_H_
+#define _HASH_H_
/* The main Samba system-adaptive header file.
*/
-/* ************************************************************************** **
+/* ========================================================================== **
* debug2html.c
*
* Copyright (C) 1998 by Christopher R. Hertel
* does a decent job of converting Samba logs into HTML.
* -------------------------------------------------------------------------- **
*
- * $Revision: 1.9.2.1 $
+ * Revision 1.4 1998/11/13 03:37:01 tridge
+ * fixes for OSF1 compilation
*
- * ************************************************************************** **
- */
-
-#include "includes.h"
-
-/* -------------------------------------------------------------------------- **
- * Global values.
+ * Revision 1.3 1998/10/28 20:33:35 crh
+ * I've moved the debugparse module files into the ubiqx directory because I
+ * know that 'make proto' will ignore them there. The debugparse.h header
+ * file is included in includes.h, and includes.h is included in debugparse.c,
+ * so all of the pieces "see" each other. I've compiled and tested this,
+ * and it does seem to work. It's the same compromise model I used when
+ * adding the ubiqx modules into the system, which is why I put it all into
+ * the same directory.
+ *
+ * Chris -)-----
+ *
+ * Revision 1.1 1998/10/26 23:21:37 crh
+ * Here is the simple debug parser and the debug2html converter. Still to do:
+ *
+ * * Debug message filtering.
+ * * I need to add all this to Makefile.in
+ * (If it looks at all strange I'll ask for help.)
+ *
+ * If you want to compile debug2html, you'll need to do it by hand until I
+ * make the changes to Makefile.in. Sorry.
+ *
+ * Chris -)-----
+ *
+ * ========================================================================== **
*/
-FILE *infile;
-FILE *outfile;
+#include "debugparse.h"
/* -------------------------------------------------------------------------- **
* The size of the read buffer.
if( dbg_message != mode )
{
/* Switching to message mode. */
- (void)fprintf( outfile, "<PRE>\n" );
+ (void)printf( "<PRE>\n" );
return( dbg_message );
}
break;
if( dbg_message == mode )
{
/* Switching out of message mode. */
- (void)fprintf( outfile, "</PRE>\n\n" );
+ (void)printf( "</PRE>\n\n" );
return( dbg_null );
}
}
switch( old )
{
case dbg_timestamp:
- (void)fprintf( outfile, ",</B>" );
+ (void)printf( ",</B>" );
break;
case dbg_level:
- (void)fprintf( outfile, "</FONT>]</B>\n " );
+ (void)printf( "</FONT>]</B>\n " );
break;
case dbg_sourcefile:
- (void)fprintf( outfile, ":" );
+ (void)printf( ":" );
break;
case dbg_lineno:
- (void)fprintf( outfile, ")" );
+ (void)printf( ")" );
break;
default:
break;
switch( new )
{
case dbg_timestamp:
- (void)fprintf( outfile, "<B>[" );
+ (void)printf( "<B>[" );
break;
case dbg_level:
- (void)fprintf( outfile, " <B><FONT COLOR=MAROON>" );
+ (void)printf( " <B><FONT COLOR=MAROON>" );
break;
case dbg_lineno:
- (void)fprintf( outfile, "(" );
+ (void)printf( "(" );
break;
default:
break;
break;
case dbg_null:
case dbg_eof:
- (void)putc( '\n', outfile );
+ (void)putchar( '\n' );
break;
default:
switch( c )
{
case '<':
- (void)fprintf( outfile, "<" );
+ (void)printf( "<" );
break;
case '>':
- (void)fprintf( outfile, ">" );
+ (void)printf( ">" );
break;
case '&':
- (void)fprintf( outfile, "&" );
+ (void)printf( "&" );
break;
case '\"':
- (void)fprintf( outfile, """ );
+ (void)printf( """ );
break;
default:
- (void)putc( c, outfile );
+ (void)putchar( c );
break;
}
}
} /* charprint */
-static void convert( void )
+int main( int argc, char *argv[] )
/* ------------------------------------------------------------------------ **
- * Read the input logfile, converting the entries to HTML.
+ * This simple program scans and parses Samba debug logs, and produces HTML
+ * output.
+ *
+ * Input: argc - Currently ignored.
+ * argv - Currently ignored.
*
- * Input: none.
- * output: none.
- * Notes: Reads from the global infile, writes to the global outfile.
- * These default to stdin and stdout, respectively.
+ * Output: Always zero.
+ *
+ * Notes: The HTML output is sent to stdout.
*
* ------------------------------------------------------------------------ **
*/
state = dbg_null,
mode = dbg_null;
- while( (!feof( infile ))
- && ((len = fread( bufr, 1, DBG_BSIZE, infile )) > 0) )
+ (void)printf( "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n" );
+ (void)printf( "<HTML>\n<HEAD>\n" );
+ (void)printf( " <TITLE>Samba Debug Output</TITLE>\n</HEAD>\n\n<BODY>\n" );
+
+ while( (!feof( stdin ))
+ && ((len = fread( bufr, 1, DBG_BSIZE, stdin )) > 0) )
{
for( i = 0; i < len; i++ )
{
}
(void)modechange( dbg_eof, mode );
- } /* convert */
-
-static void usage( void )
- /* ------------------------------------------------------------------------ **
- * Prints a usage message on stderr, then gently exits.
- *
- * Input: none.
- * Output: none. Exits with return code of 0.
- *
- * ------------------------------------------------------------------------ **
- */
- {
- fprintf( stderr, "This utility converts Samba log files " );
- fprintf( stderr, "into HTML documents.\n" );
- fprintf( stderr, "Usage:\n" );
- fprintf( stderr, " debug2html <infile> <outfile>\n" );
- exit( 0 );
- } /* usage */
-
-static FILE *carefull_fopen( const char *path, const char *type )
- /* ------------------------------------------------------------------------ **
- * Checks for leading '-' characters, which are generically regarded as
- * flags. Also exits the program gracefully should the file fail to open.
- *
- * Input: path - pathname of the file to open.
- * type - open mode. See fopen(3S).
- *
- * Output: Pointer to open file.
- *
- * ------------------------------------------------------------------------ **
- */
- {
- FILE *tmp;
-
- if( '-' == path[0] || '\0' == path[0] )
- usage();
-
- tmp = sys_fopen( path, type );
- if( NULL == tmp )
- {
- fprintf( stderr, "Error opening file %s: %s\n", path, strerror(errno) );
- exit( 1 );
- }
- return( tmp );
- } /* carefull_fopen */
-
-int main( int argc, char *argv[] )
- /* ------------------------------------------------------------------------ **
- * This simple program scans and parses Samba debug logs, and produces HTML
- * output.
- *
- * Input: argc - Argument count.
- * argv[1] - Input file name.
- * argv[2] - Output file name.
- * A '-' character by itself means use defaults (i.e.,
- * <stdin> or <stdout> depending upon the argument.
- * A string beginning with '-' and containing more than
- * that one character will generate a usage message.
- *
- * Output: An exit value of 1 is returned if an error was encountered
- * while opening a file, else 0.
- *
- * Notes: The HTML output is sent to stdout.
- *
- * ------------------------------------------------------------------------ **
- */
- {
- if( argc > 3 )
- usage();
-
- infile = stdin;
- outfile = stdout;
-
- if( argc > 1 && 0 != strcmp( argv[1], "-" ) )
- infile = carefull_fopen( argv[1], "r" );
-
- if( argc > 2 && 0 != strcmp( argv[2], "-" ) )
- infile = carefull_fopen( argv[2], "w" );
-
- (void)fprintf( outfile,
- "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n" );
- (void)fprintf( outfile, "<HTML>\n<HEAD>\n" );
- (void)fprintf( outfile,
- " <TITLE>Samba Log</TITLE>\n</HEAD>\n\n<BODY>\n" );
-
- convert();
-
- (void)fprintf( outfile, "</BODY>\n</HTML>\n" );
-
+ (void)printf( "</BODY>\n</HTML>\n" );
return( 0 );
} /* main */
*/
char *files_to_copy;
-char *driverfile, *datafile, *helpfile, *languagemonitor, *datatype;
+char *driverfile, *datafile, *helpfile, *languagemonitor, *datatype, *vendorsetup;
char buffer[50][sizeof(pstring)];
char sbuffer[50][sizeof(pstring)];
char sub_dir[50][2][sizeof(pstring)];
i++;
}
(*entry)[i]='\0';
- pstrcpy(value,temp+i+1);
+ if (temp[i]!='\0') {
+ i++;
+ }
+ while( temp[i]==' ' && temp[i]!='\0') {
+ i++;
+ }
+ pstrcpy(value,temp+i);
return (value);
}
static void build_subdir(void)
{
int i=0;
+ int j=0;
char *entry;
char *data;
#ifdef DEBUGIT
fprintf(stderr,"\tentry=data %s:%s\n",entry,data);
#endif
+ j = strlen(entry);
+ while (j) {
+ if (entry[j-1] != ' ') break;
+ j--;
+ }
+ entry[j] = '\0';
- if (strcmp(data,"11")==0) {
+ if (strncmp(data,"11",2)==0) {
pstrcpy(sub_dir[i][0],entry);
pstrcpy(sub_dir[i][1],"");
}
- if (strcmp(data,"23")==0) {
+ if (strncmp(data,"23",2)==0) {
pstrcpy(sub_dir[i][0],entry);
pstrcpy(sub_dir[i][1],"color\\");
}
pointeur++;
}
}
+
+ /* CCMRCF Mod, seg fault or worse if not found */
+ if (pointeur == 0) {
+ fprintf(stderr,"Printer not found\tNo [Strings] block in inf file\n");
+ exit(2);
+ }
+
#ifdef DEBUGIT
fprintf(stderr,"\t\tFound %d entries\n",pointeur-1);
#endif
fprintf(stderr,"\tsubdir %s:%s\n",sub_dir[i][0],sub_dir[i][1]);
#endif
if (strcmp(sub_dir[i][0],part)==0)
- pstrcpy(direc,sub_dir[i][1]);
- i++;
+ pstrcpy(direc,sub_dir[i][1]);
+ i++;
}
i=0;
while (*buffer[i]!='\0') {
*
* pscript.hlp = pscript.hl_
* hpdcmon.dll,hpdcmon.dl_
+ * MSVCRT.DLL,MSVCRT.DL_,,32
* ctl3dv2.dll,ctl3dv2.dl_,ctl3dv2.tmp
*
* In the first 2 cases you want the first file name - in the last case
* you only want the last file name (at least that is what a Win95
- * machine sent). This may still be wrong but at least I get the same list
+ * machine sent). In the third case you also want the first file name
+ * (detect by the last component being just a number ?).
+ * This may still be wrong but at least I get the same list
* of files as seen on a printer test page.
*/
part = strchr(buffer[i],'=');
if (part) {
+ /*
+ * Case (1) eg. pscript.hlp = pscript.hl_ - chop after the first name.
+ */
+
*part = '\0';
- while (--part > buffer[i])
- if ((*part == ' ') || (*part =='\t')) *part = '\0';
- else break;
- } else {
- part = strchr(buffer[i],',');
- if (part) {
- if ((mpart = strrchr(part+1,','))!=NULL) {
- pstrcpy(buffer[i],mpart+1);
- } else
- *part = '\0';
+
+ /*
+ * Now move back to the start and print that.
+ */
+
+ while (--part > buffer[i]) {
+ if ((*part == ' ') || (*part =='\t'))
+ *part = '\0';
+ else
+ break;
+ }
+ } else {
+ part = strchr(buffer[i],',');
+ if (part) {
+ /*
+ * Cases (2-4)
+ */
+
+ if ((mpart = strrchr(part+1,','))!=NULL) {
+ /*
+ * Second ',' - case 3 or 4.
+ * Check if the last part is just a number,
+ * if so we need the first part.
+ */
+
+ char *endptr = NULL;
+ BOOL isnumber = False;
+
+ mpart++;
+ (void)strtol(mpart, &endptr, 10);
+
+ isnumber = ((endptr > mpart) && isdigit(*mpart));
+ if(!isnumber)
+ pstrcpy(buffer[i],mpart+1);
+ else
+ *part = '\0';
+ } else {
+ *part = '\0';
+ }
while (--part > buffer[i])
if ((*part == ' ') || (*part =='\t')) *part = '\0';
else break;
- }
- }
- if (strlen(files_to_copy) != 0)
- pstrcat(files_to_copy,",");
- pstrcat(files_to_copy,direc);
- pstrcat(files_to_copy,buffer[i]);
- fprintf(stderr,"%s%s\n",direc,buffer[i]);
- i++;
- }
+ }
+ }
+ if (*buffer[i] != ';') {
+ if (strlen(files_to_copy) != 0)
+ pstrcat(files_to_copy,",");
+ pstrcat(files_to_copy,direc);
+ pstrcat(files_to_copy,buffer[i]);
+ fprintf(stderr,"%s%s\n",direc,buffer[i]);
+ }
+ i++;
+ } /* end while */
}
part=strtok(NULL,",");
- }
- while (part!=NULL);
+ if (part) {
+ while( *part ==' ' && *part != '\0') {
+ part++;
+ }
+ }
+ } while (part!=NULL);
fprintf(stderr,"\n");
}
helpfile=0;
languagemonitor=0;
+ vendorsetup=0;
datatype="RAW";
if((temp=(char *)malloc(sizeof(pstring))) == NULL) {
fprintf(stderr, "scan_short_desc: malloc fail !\n");
languagemonitor=scan(buffer[i],&temp);
else if (strncasecmp(buffer[i],"DefaultDataType",15)==0)
datatype=scan(buffer[i],&temp);
+ else if (strncasecmp(buffer[i],"VendorSetup",11)==0)
+ vendorsetup=scan(buffer[i],&temp);
i++;
}
languagemonitor=scan(buffer[i],&temp);
else if (strncasecmp(buffer[i],"DefaultDataType",15)==0)
datatype=scan(buffer[i],&temp);
+ else if (strncasecmp(buffer[i],"VendorSetup",11)==0)
+ vendorsetup=scan(buffer[i],&temp);
i++;
}
}
helpfile?helpfile:"(null)");
fprintf(stderr,"LanguageMonitor: %s\n",
languagemonitor?languagemonitor:"(null)");
+ fprintf(stderr,"VendorSetup: %s\n",
+ vendorsetup?vendorsetup:"(null)");
if (copyfiles) scan_copyfiles(fichier,copyfiles);
}
Version 1.9.
Create codepage files from codepage_def.XXX files.
- Copyright (C) Jeremy Allison 1997-1998.
+ Copyright (C) Jeremy Allison 1997-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
* Returns the number of lines copied.
*/
-static int clean_data( char **buf, uint32 *size)
+static int clean_data( char **buf, size_t *size)
{
pstring linebuf;
char *p = *buf;
static int do_compile(int codepage, char *input_file, char *output_file)
{
FILE *fp = NULL;
- uint32 size = 0;
+ size_t size = 0;
char *buf = NULL;
char output_buf[CODEPAGE_HEADER_SIZE + 4 * MAXCODEPAGELINES];
int num_lines = 0;
static int do_decompile( int codepage, char *input_file, char *output_file)
{
- uint32 size = 0;
+ size_t size = 0;
SMB_STRUCT_STAT st;
char header_buf[CODEPAGE_HEADER_SIZE];
char *buf = NULL;
exit(1);
}
- size = (uint32)st.st_size;
+ size = (size_t)st.st_size;
if( size < CODEPAGE_HEADER_SIZE || size > (CODEPAGE_HEADER_SIZE + 256))
{
if (s != -1) FD_SET(s, &fds);
if (c != -1) FD_SET(c, &fds);
- num = sys_select(MAX(s+1, c+1),&fds,NULL, NULL);
+ num = sys_select(MAX(s+1, c+1),&fds,NULL);
if (num <= 0) continue;
if (c != -1 && FD_ISSET(c, &fds)) {
FD_ZERO(&fds);
FD_SET(s, &fds);
- num = sys_select(s+1,&fds,NULL, NULL);
+ num = sys_select(s+1,&fds,NULL);
if (num > 0) {
c = accept(s, &addr, &in_addrlen);
if (c != -1) {
#include "includes.h"
+/*
+ * stubs, to minimise linking, but unfortunately these are called
+ * in util_sec.c
+ */
+
+int DEBUGLEVEL;
+
+BOOL dbghdr( int level, char *file, char *func, int line )
+{
+ return( True );
+}
+
+#ifdef HAVE_STDARG_H
+ BOOL dbgtext( char *format_str, ... )
+ {
+ return( True );
+ } /* dbgtext */
+
+#else
+ BOOL dbgtext( va_alist )
+ va_dcl
+ {
+ return( True );
+ } /* dbgtext */
+
+#endif
+
+void smb_panic(char *reason)
+{
+ exit(1);
+}
/*******************************************************************
close the low 3 fd's and open dev/null in their place
static int shares_only = 0; /* Added by RJS */
static int locks_only = 0; /* Added by RJS */
static BOOL processes_only=False;
+static int show_brl;
/* added by OH */
if (Ucrit_checkPid(e->pid)) {
printf("%-5d ",(int)e->pid);
- switch ((e->share_mode>>4)&0xF) {
+ switch (GET_DENY_MODE(e->share_mode)) {
case DENY_NONE: printf("DENY_NONE "); break;
case DENY_ALL: printf("DENY_ALL "); break;
case DENY_DOS: printf("DENY_DOS "); break;
case DENY_READ: printf("DENY_READ "); break;
case DENY_WRITE:printf("DENY_WRITE "); break;
+ case DENY_FCB: printf("DENY_FCB "); break;
}
switch (e->share_mode&0xF) {
case 0: printf("RDONLY "); break;
}
}
+static void print_brl(SMB_DEV_T dev, SMB_INO_T ino, int pid,
+ enum brl_type lock_type,
+ br_off start, br_off size)
+{
+ static int count;
+ if (count==0) {
+ printf("Byte range locks:\n");
+ printf(" Pid dev:inode R/W start size\n");
+ printf("------------------------------------------------\n");
+ }
+ count++;
+
+ printf("%6d %05x:%05x %s %9.0f %9.0f\n",
+ (int)pid, (int)dev, (int)ino,
+ lock_type==READ_LOCK?"R":"W",
+ (double)start, (double)size);
+}
+
/*******************************************************************
dump the elements of the profile structure
}
-static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* state)
+static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
{
static pid_t last_pid;
struct session_record *ptr;
return(1);
}
- while ((c = getopt(argc, argv, "pdLSs:u:bP")) != EOF) {
+ while ((c = getopt(argc, argv, "pdLSs:u:bPB")) != EOF) {
switch (c) {
case 'b':
brief = 1;
break;
+ case 'B':
+ show_brl = 1;
+ break;
case 'd':
verbose = 1;
break;
}
printf("\n");
+
+ if (show_brl) {
+ brl_forall(print_brl);
+ }
locking_end();
}
Here we do a set of 'hard coded' checks for bad
configuration settings.
************************************************/
-static void do_global_checks(void)
+
+static int do_global_checks(void)
{
+ int ret = 0;
SMB_STRUCT_STAT st;
+
if (lp_security() > SEC_SHARE && lp_revalidate(-1)) {
printf("WARNING: the 'revalidate' parameter is ignored in all but \
'security=share' mode.\n");
}
- if (lp_security() == SEC_DOMAIN && !lp_encrypted_passwords()) {
+ if (lp_security() == SEC_DOMAIN && !lp_encrypted_passwords()) {
printf("ERROR: in 'security=domain' mode the 'encrypt passwords' parameter must also be set to 'true'.\n");
+ ret = 1;
}
if (lp_wins_support() && *lp_wins_server()) {
printf("ERROR: both 'wins support = true' and 'wins server = <server>' \
cannot be set in the smb.conf file. nmbd will abort with this setting.\n");
+ ret = 1;
}
if (!directory_exist(lp_lockdir(), &st)) {
printf("ERROR: lock directory %s does not exist\n",
lp_lockdir());
+ ret = 1;
} else if ((st.st_mode & 0777) != 0755) {
printf("WARNING: lock directory %s should have permissions 0755 for browsing to work\n",
lp_lockdir());
+ ret = 1;
+ }
+
+ /*
+ * Password server sanity checks.
+ */
+
+ if((lp_security() == SEC_SERVER || lp_security() == SEC_DOMAIN) && !lp_passwordserver()) {
+ pstring sec_setting;
+ if(lp_security() == SEC_SERVER)
+ pstrcpy(sec_setting, "server");
+ else if(lp_security() == SEC_DOMAIN)
+ pstrcpy(sec_setting, "domain");
+
+ printf("ERROR: The setting 'security=%s' requires the 'password server' parameter be set \
+to a valid password server.\n", sec_setting );
+ ret = 1;
}
+
+ /*
+ * Password chat sanity checks.
+ */
+
+ if(lp_security() == SEC_USER && lp_unix_password_sync()) {
+
+ /*
+ * Check that we have a valid lp_passwd_program().
+ */
+
+ if(lp_passwd_program() == NULL) {
+ printf("ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd program' \
+parameter.\n" );
+ ret = 1;
+ } else {
+ pstring passwd_prog;
+ pstring truncated_prog;
+ char *p;
+
+ pstrcpy( passwd_prog, lp_passwd_program());
+ p = passwd_prog;
+ *truncated_prog = '\0';
+ next_token(&p, truncated_prog, NULL, sizeof(pstring));
+
+ if(access(truncated_prog, F_OK) == -1) {
+ printf("ERROR: the 'unix password sync' parameter is set and the 'passwd program' (%s) \
+cannot be executed (error was %s).\n", truncated_prog, strerror(errno) );
+ ret = 1;
+ }
+ }
+
+ if(lp_passwd_chat() == NULL) {
+ printf("ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd chat' \
+parameter.\n");
+ ret = 1;
+ }
+
+ /*
+ * Check that we have a valid script and that it hasn't
+ * been written to expect the old password.
+ */
+
+ if(lp_encrypted_passwords()) {
+ if(strstr( lp_passwd_chat(), "%o")!=NULL) {
+ printf("ERROR: the 'passwd chat' script [%s] expects to use the old plaintext password \
+via the %%o substitution. With encrypted passwords this is not possible.\n", lp_passwd_chat() );
+ ret = 1;
+ }
+ }
+ }
+
+ /*
+ * WINS server line sanity checks.
+ */
+
+ if(*lp_wins_server()) {
+ fstring server;
+ int count = 0;
+ char *p = lp_wins_server();
+
+ while(next_token(&p,server,LIST_SEP,sizeof(server)))
+ count++;
+ if(count > 1) {
+ printf("ERROR: the 'wins server' parameter must only contain one WINS server.\n");
+ ret = -1;
+ }
+ }
+
+ return ret;
}
- int main(int argc, char *argv[])
+static void usage(char *pname)
+{
+ printf("Usage: %s [-sh] [-L servername] [configfilename] [hostname hostIP]\n", pname);
+ printf("\t-s Suppress prompt for enter\n");
+ printf("\t-h Print usage\n");
+ printf("\t-L servername Set %%L macro to servername\n");
+ printf("\tconfigfilename Configuration file to test\n");
+ printf("\thostname hostIP. Hostname and Host IP address to test\n");
+ printf("\t against \"host allow\" and \"host deny\"\n");
+ printf("\n");
+}
+
+
+int main(int argc, char *argv[])
{
extern char *optarg;
extern int optind;
+ extern fstring local_machine;
pstring configfile;
int opt;
int s;
BOOL silent_mode = False;
+ int ret = 0;
TimeInit();
charset_initialise();
- while ((opt = getopt(argc, argv,"s")) != EOF) {
+ while ((opt = getopt(argc, argv,"shL:")) != EOF) {
switch (opt) {
case 's':
silent_mode = True;
break;
+ case 'L':
+ fstrcpy(local_machine,optarg);
+ break;
+ case 'h':
+ usage(argv[0]);
+ exit(0);
+ break;
+ default:
+ printf("Incorrect program usage\n");
+ usage(argv[0]);
+ exit(1);
+ break;
}
}
printf("Load smb config files from %s\n",configfile);
- if (!lp_load(configfile,False,True,False))
- {
+ if (!lp_load(configfile,False,True,False)) {
printf("Error loading services.\n");
return(1);
- }
-
+ }
printf("Loaded services file OK.\n");
- do_global_checks();
+ ret = do_global_checks();
- for (s=0;s<1000;s++)
+ for (s=0;s<1000;s++) {
if (VALID_SNUM(s))
if (strlen(lp_servicename(s)) > 8) {
- printf("WARNING: You have some share names that are longer than 8 chars\n");
- printf("These may give errors while browsing or may not be accessible\nto some older clients\n");
- break;
+ printf("WARNING: You have some share names that are longer than 8 chars\n");
+ printf("These may give errors while browsing or may not be accessible\nto some older clients\n");
+ break;
+ }
+ }
+
+ for (s=0;s<1000;s++) {
+ if (VALID_SNUM(s)) {
+ char *deny_list = lp_hostsdeny(s);
+ char *allow_list = lp_hostsallow(s);
+ if(deny_list) {
+ char *hasstar = strchr(deny_list, '*');
+ char *hasquery = strchr(deny_list, '?');
+ if(hasstar || hasquery) {
+ printf("Invalid character %c in hosts deny list %s for service %s.\n",
+ hasstar ? *hasstar : *hasquery, deny_list, lp_servicename(s) );
+ }
}
- if (argc < 3)
- {
- if (!silent_mode) {
- printf("Press enter to see a dump of your service definitions\n");
- fflush(stdout);
- getc(stdin);
+ if(allow_list) {
+ char *hasstar = strchr(allow_list, '*');
+ char *hasquery = strchr(allow_list, '?');
+ if(hasstar || hasquery) {
+ printf("Invalid character %c in hosts allow list %s for service %s.\n",
+ hasstar ? *hasstar : *hasquery, allow_list, lp_servicename(s) );
+ }
}
- lp_dump(stdout,True);
+
+ if(lp_level2_oplocks(s) && !lp_oplocks(s)) {
+ printf("Invalid combination of parameters for service %s. \
+Level II oplocks can only be set if oplocks are also set.\n",
+ lp_servicename(s) );
+ }
+ }
+ }
+
+ if (argc < 3) {
+ if (!silent_mode) {
+ printf("Press enter to see a dump of your service definitions\n");
+ fflush(stdout);
+ getc(stdin);
}
+ lp_dump(stdout,True, lp_numservices());
+ }
- if (argc >= 3)
- {
- char *cname;
- char *caddr;
+ if (argc >= 3) {
+ char *cname;
+ char *caddr;
- if (argc == 3) {
- cname = argv[optind];
- caddr = argv[optind+1];
- } else {
- cname = argv[optind+1];
- caddr = argv[optind+2];
- }
+ if (argc == 3) {
+ cname = argv[optind];
+ caddr = argv[optind+1];
+ } else {
+ cname = argv[optind+1];
+ caddr = argv[optind+2];
+ }
- /* this is totally ugly, a real `quick' hack */
- for (s=0;s<1000;s++)
- if (VALID_SNUM(s))
- {
- if (allow_access(lp_hostsdeny(s),lp_hostsallow(s),cname,caddr))
- {
- printf("Allow connection from %s (%s) to %s\n",
- cname,caddr,lp_servicename(s));
- }
- else
- {
- printf("Deny connection from %s (%s) to %s\n",
- cname,caddr,lp_servicename(s));
- }
- }
+ /* this is totally ugly, a real `quick' hack */
+ for (s=0;s<1000;s++) {
+ if (VALID_SNUM(s)) {
+ if (allow_access(lp_hostsdeny(s),lp_hostsallow(s),cname,caddr)) {
+ printf("Allow connection from %s (%s) to %s\n",
+ cname,caddr,lp_servicename(s));
+ } else {
+ printf("Deny connection from %s (%s) to %s\n",
+ cname,caddr,lp_servicename(s));
+ }
+ }
}
- return(0);
+ }
+ return(ret);
}
-
-
*p = 0;
}
- string_sub(url, "/swat/", "");
+ string_sub(url, "/swat/", "", 0);
if (url[0] != '/' && strstr(url,"..")==0 && file_exist(url, NULL)) {
cgi_download(url);
TDB_CONTEXT *tdb;
if (cgi_variable("smbd_restart")) {
- if (smbd_running())
- stop_smbd();
+ stop_smbd();
start_smbd();
}
}
if (cgi_variable("nmbd_restart")) {
- if (nmbd_running())
- stop_nmbd();
+ stop_nmbd();
start_nmbd();
}
if (cgi_variable("nmbd_start")) {
static pstring servicesf = CONFIGFILE;
static BOOL demo_mode = False;
static BOOL have_write_access = False;
+static BOOL have_read_access = False;
+static int iNumNonAutoPrintServices = 0;
/*
* Password Management Globals
#define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
#define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
#define ADD_USER_FLAG "add_user_flag"
+#define DELETE_USER_FLAG "delete_user_flag"
#define DISABLE_USER_FLAG "disable_user_flag"
#define ENABLE_USER_FLAG "enable_user_flag"
#define RHOST "remote_host"
break;
case P_OCTAL:
- printf("<input type=text size=8 name=\"parm_%s\" value=0%o>", make_parm_name(parm->label), *(int *)ptr);
- printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'0%o\'\">",
- make_parm_name(parm->label),(int)(parm->def.ivalue));
+ printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm->label), octal_string(*(int *)ptr));
+ printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
+ make_parm_name(parm->label),
+ octal_string((int)(parm->def.ivalue)));
break;
case P_ENUM:
printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
break;
-
- default:
+ case P_SEP:
break;
}
printf("</td></tr>\n");
continue;
}
if (parm->flags & FLAG_HIDE) continue;
+ if (snum >= 0) {
+ if (printers & !(parm->flags & FLAG_PRINT)) continue;
+ if (!printers & !(parm->flags & FLAG_SHARE)) continue;
+ }
if (!advanced) {
- if (!printers && !(parm->flags & FLAG_BASIC)) {
+ if (!(parm->flags & FLAG_BASIC)) {
void *ptr = parm->ptr;
+ if (parm->class == P_LOCAL && snum >= 0) {
+ ptr = lp_local_ptr(snum, ptr);
+ }
+
switch (parm->type) {
case P_CHAR:
if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
case P_ENUM:
if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
break;
-
- default:
+ case P_SEP:
continue;
}
}
}
}
+/****************************************************************************
+ load the smb.conf file into loadparm.
+****************************************************************************/
+static BOOL load_config(BOOL save_def)
+{
+ lp_resetnumservices();
+ return lp_load(servicesf,False,save_def,False);
+}
+
/****************************************************************************
write a config file
****************************************************************************/
fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
fprintf(f, "# Date: %s\n\n", timestring(False));
- lp_dump(f, show_defaults);
+ lp_dump(f, show_defaults, iNumNonAutoPrintServices);
}
/****************************************************************************
save and reoad the smb.conf config file
****************************************************************************/
-static int save_reload(void)
+static int save_reload(int snum)
{
FILE *f;
}
write_config(f, False);
+ if (snum)
+ lp_dump_one(f, False, snum);
fclose(f);
lp_killunused(NULL);
- if (!lp_load(servicesf,False,False,False)) {
+ if (!load_config(False)) {
printf("Can't reload %s\n", servicesf);
return 0;
}
+ iNumNonAutoPrintServices = lp_numservices();
+ load_printers();
return 1;
}
}
}
-/****************************************************************************
- load the smb.conf file into loadparm.
-****************************************************************************/
-static BOOL load_config(void)
-{
- return lp_load(servicesf,False,True,False);
-}
-
/****************************************************************************
spit out the html for a link with an image
****************************************************************************/
****************************************************************************/
static void show_main_buttons(void)
{
- image_link("Home", "", "images/home.gif");
+ char *p;
+ if ((p = cgi_user_name()) && strcmp(p, "root")) {
+ printf("Logged in as <b>%s</b><p>\n", p);
+ }
+
+ image_link("Home", "", "images/home.gif");
+ if (have_write_access) {
image_link("Globals", "globals", "images/globals.gif");
image_link("Shares", "shares", "images/shares.gif");
image_link("Printers", "printers", "images/printers.gif");
+ }
+ if (have_read_access) {
image_link("Status", "status", "images/status.gif");
image_link("View Config", "viewconfig","images/viewconfig.gif");
+ }
image_link("Password Management", "passwd", "images/passwd.gif");
printf("<HR>\n");
if (cgi_variable("Commit")) {
commit_parameters(GLOBALS_SNUM);
- save_reload();
+ save_reload(0);
}
printf("<FORM name=\"swatform\" method=post>\n");
if (cgi_variable("Commit") && snum >= 0) {
commit_parameters(snum);
- save_reload();
+ save_reload(0);
}
if (cgi_variable("Delete") && snum >= 0) {
lp_remove_service(snum);
- save_reload();
+ save_reload(0);
share = NULL;
snum = -1;
}
if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
+ load_config(False);
lp_copy_service(GLOBALS_SNUM, share);
- save_reload();
+ iNumNonAutoPrintServices = lp_numservices();
+ save_reload(0);
snum = lp_servicenumber(share);
}
printf("<FORM name=\"swatform\" method=post>\n");
printf("<table>\n");
- printf("<tr><td><input type=submit name=selectshare value=\"Choose Share\"></td>\n");
+ printf("<tr>\n");
+ printf("<td><input type=submit name=selectshare value=\"Choose Share\"></td>\n");
printf("<td><select name=share>\n");
if (snum < 0)
printf("<option value=\" \"> \n");
s, s);
}
}
- printf("</select></td></tr><p>");
-
- printf("<tr><td><input type=submit name=createshare value=\"Create Share\"></td>\n");
+ printf("</select></td>\n");
+ if (have_write_access) {
+ printf("<td><input type=submit name=\"Delete\" value=\"Delete Share\"></td>\n");
+ }
+ printf("</tr>\n");
+ printf("</table>");
+ printf("<table>");
+ if (have_write_access) {
+ printf("<tr>\n");
+ printf("<td><input type=submit name=createshare value=\"Create Share\"></td>\n");
printf("<td><input type=text size=30 name=newshare></td></tr>\n");
+ }
printf("</table>");
printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
}
- printf("<input type=submit name=\"Delete\" value=\"Delete Share\">\n");
+ printf("<input type=reset name=\"Reset Values\" value=\"Reset Values\">\n");
if (advanced == 0) {
printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
} else {
*************************************************************/
static BOOL change_password(const char *remote_machine, char *user_name,
char *old_passwd, char *new_passwd,
- BOOL add_user, BOOL enable_user, BOOL disable_user)
+ int local_flags)
{
BOOL ret = False;
- uint16 acb_info = 0;
- uint16 acb_mask = 0;
pstring err_str;
pstring msg_str;
return False;
}
- if (enable_user)
- {
- acb_mask |= ACB_DISABLED;
- acb_info &= ~ACB_DISABLED;
- }
-
- if (disable_user)
- {
- acb_mask |= ACB_DISABLED;
- acb_info |= ACB_DISABLED;
- }
-
- ret = local_password_change(user_name, add_user,
- acb_info, acb_mask,
- new_passwd, err_str, sizeof(err_str),
+#if 0
+ ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str),
msg_str, sizeof(msg_str));
-
+#else
+ ret = False;
+ slprintf(err_str, sizeof(err_str)-1, "TODO: local_password_change disabled\n");
+#endif
if(*msg_str)
printf("%s\n<p>", msg_str);
if(*err_str)
{
char *host;
BOOL rslt;
+ int local_flags = 0;
/* Make sure users name has been specified */
if (strlen(cgi_variable(SWAT_USER)) == 0) {
}
/*
- * smbpasswd doesn't require anything but the users name to disable or enable the user,
+ * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
* so if that's what we're doing, skip the rest of the checks
*/
- if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG)) {
+ if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
/*
* If current user is not root, make sure old password has been specified
} else {
host = "127.0.0.1";
}
+
+ /*
+ * Set up the local flags.
+ */
+
+ local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
+ local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
+ local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
+ local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
+
rslt = change_password(host,
cgi_variable(SWAT_USER),
cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
- cgi_variable(ADD_USER_FLAG)? True : False,
- cgi_variable(ENABLE_USER_FLAG)? True : False,
- cgi_variable(DISABLE_USER_FLAG)? True : False);
-
+ local_flags);
+ if(local_flags == 0) {
if (rslt == True) {
printf("<p> The passwd for '%s' has been changed. \n", cgi_variable(SWAT_USER));
} else {
printf("<p> The passwd for '%s' has NOT been changed. \n",cgi_variable(SWAT_USER));
}
+ }
return;
}
if (demo_mode || am_root()) {
printf("<input type=submit name=%s value=\"Add New User\">\n",
ADD_USER_FLAG);
+ printf("<input type=submit name=%s value=\"Delete User\">\n",
+ DELETE_USER_FLAG);
printf("<input type=submit name=%s value=\"Disable User\">\n",
DISABLE_USER_FLAG);
printf("<input type=submit name=%s value=\"Enable User\">\n",
* Do some work if change, add, disable or enable was
* requested. It could be this is the first time through this
* code, so there isn't anything to do. */
- if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) ||
+ if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
(cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
chg_passwd();
}
printf("<tr><td> Re-type New Password : </td>\n");
printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
printf("<tr><td> Remote Machine : </td>\n");
- printf("<td><input type=password size=30 name=%s></td></tr>\n",RHOST);
+ printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
printf("</table>");
printf("<H2>Printer Parameters</H2>\n");
+ printf("<H3>Important Note:</H3>\n");
+ printf("Printer names marked with [*] in the Choose Printer drop-down box ");
+ printf("are autoloaded printers from ");
+ printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">Printcap Name</A>.\n");
+ printf("Attempting to delete these printers from SWAT will have no effect.\n");
+
if (cgi_variable("Advanced") && !cgi_variable("Basic"))
advanced = 1;
if (cgi_variable("Commit") && snum >= 0) {
commit_parameters(snum);
- save_reload();
+ if (snum >= iNumNonAutoPrintServices)
+ save_reload(snum);
+ else
+ save_reload(0);
}
if (cgi_variable("Delete") && snum >= 0) {
lp_remove_service(snum);
- save_reload();
+ save_reload(0);
share = NULL;
snum = -1;
}
if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
+ load_config(False);
lp_copy_service(GLOBALS_SNUM, share);
+ iNumNonAutoPrintServices = lp_numservices();
snum = lp_servicenumber(share);
lp_do_parameter(snum, "print ok", "Yes");
- save_reload();
+ save_reload(0);
snum = lp_servicenumber(share);
}
for (i=0;i<lp_numservices();i++) {
s = lp_servicename(i);
if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
+ if (i >= iNumNonAutoPrintServices)
+ printf("<option %s value=\"%s\">[*]%s\n",
+ (share && strcmp(share,s)==0)?"SELECTED":"",
+ s, s);
+ else
printf("<option %s value=\"%s\">%s\n",
(share && strcmp(share,s)==0)?"SELECTED":"",
s, s);
}
}
- printf("</select></td></tr><p>");
+ printf("</select></td>");
+ if (have_write_access) {
+ printf("<td><input type=submit name=\"Delete\" value=\"Delete Printer\"></td>\n");
+ }
+ printf("</tr>");
+ printf("</table>\n");
+ if (have_write_access) {
+ printf("<table>\n");
printf("<tr><td><input type=submit name=createshare value=\"Create Printer\"></td>\n");
printf("<td><input type=text size=30 name=newshare></td></tr>\n");
printf("</table>");
+ }
if (snum >= 0) {
if (have_write_access) {
printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
}
- printf("<input type=submit name=\"Delete\" value=\"Delete Printer\">\n");
+ printf("<input type=reset name=\"Reset Values\" value=\"Reset Values\">\n");
if (advanced == 0) {
printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
} else {
int opt;
char *page;
+ fault_setup(NULL);
+
+#if defined(HAVE_SET_AUTH_PARAMETERS)
+ set_auth_parameters(argc, argv);
+#endif /* HAVE_SET_AUTH_PARAMETERS */
+
/* just in case it goes wild ... */
alarm(300);
if (!dbf) dbf = stderr;
+ /* we don't want stderr screwing us up */
+ close(2);
+ open("/dev/null", O_WRONLY);
+
while ((opt = getopt(argc, argv,"s:a")) != EOF) {
switch (opt) {
case 's':
}
charset_initialise();
- load_config();
+ load_config(True);
+ iNumNonAutoPrintServices = lp_numservices();
+ load_printers();
cgi_setup(SWATDIR, !demo_mode);
cgi_load_variables(NULL);
- show_main_buttons();
-
- page = cgi_pathinfo();
-
+ if (!file_exist(servicesf, NULL)) {
+ have_read_access = True;
+ have_write_access = True;
+ } else {
/* check if the authenticated user has write access - if not then
don't show write options */
have_write_access = (access(servicesf,W_OK) == 0);
+ /* if the user doesn't have read access to smb.conf then
+ don't let them view it */
+ have_read_access = (access(servicesf,R_OK) == 0);
+ }
+
+
+ show_main_buttons();
+
+ page = cgi_pathinfo();
+
/* Root gets full functionality */
- if (strcmp(page, "globals")==0) {
+ if (have_read_access && strcmp(page, "globals")==0) {
globals_page();
- } else if (strcmp(page,"shares")==0) {
+ } else if (have_read_access && strcmp(page,"shares")==0) {
shares_page();
- } else if (strcmp(page,"printers")==0) {
+ } else if (have_read_access && strcmp(page,"printers")==0) {
printers_page();
- } else if (strcmp(page,"status")==0) {
+ } else if (have_read_access && strcmp(page,"status")==0) {
status_page();
- } else if (strcmp(page,"viewconfig")==0) {
+ } else if (have_read_access && strcmp(page,"viewconfig")==0) {
viewconfig_page();
} else if (strcmp(page,"passwd")==0) {
passwd_page();