diff options
author | Simo Sorce <idra@samba.org> | 2003-08-02 20:06:57 +0000 |
---|---|---|
committer | Simo Sorce <idra@samba.org> | 2003-08-02 20:06:57 +0000 |
commit | 04bf12b176d5abe06b7f1401810369bcafe0b611 (patch) | |
tree | 8bb6627c3ffa4cab902787b874206f8012a33e3a | |
parent | 7efce478976e2ac71bcaf4e4d1049bb263634711 (diff) | |
download | samba-04bf12b176d5abe06b7f1401810369bcafe0b611.tar.gz samba-04bf12b176d5abe06b7f1401810369bcafe0b611.tar.bz2 samba-04bf12b176d5abe06b7f1401810369bcafe0b611.zip |
port latest changes from SAMBA_3_0 tree
(This used to be commit 3101c236b8241dc0183995ffceed551876427de4)
172 files changed, 6162 insertions, 4095 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index 73ff436c6f..4674fd07ae 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -3,7 +3,7 @@ # Copyright Andrew Tridgell 1992-1998 # Copyright (C) 2001 by Martin Pool <mbp@samba.org> # Copyright Andrew Bartlett 2002 -# Copyright (C) 2003 Anthony Liguori <aliguor@us.ibm.com> +# Copyright (C) 2003 Jim McDonough <aliguor@us.ibm.com> # Copyright (C) 2002-2003 Jelmer Vernooij <jelmer@samba.org> ########################################################################### @@ -32,7 +32,6 @@ AUTHLIBS=@AUTHLIBS@ ACLLIBS=@ACLLIBS@ PASSDBLIBS=@PASSDBLIBS@ IDMAP_LIBS=@IDMAP_LIBS@ -ADSLIBS=@ADSLIBS@ KRB5LIBS=@KRB5_LIBS@ LDAPLIBS=@LDAP_LIBS@ @@ -165,7 +164,7 @@ SMBLDAP_OBJ = @SMBLDAP@ LIB_OBJ = lib/charcnv.o lib/debug.o lib/fault.o \ lib/getsmbpass.o lib/interface.o lib/md4.o \ - lib/interfaces.o lib/pidfile.o lib/replace.o \ + lib/interfaces.o lib/pidfile.o lib/replace.o lib/replace1.o \ lib/signal.o lib/system.o lib/sendfile.o lib/time.o \ lib/ufc.o lib/genrand.o lib/username.o \ lib/util_getent.o lib/util_pw.o lib/access.o lib/smbrun.o \ @@ -176,7 +175,7 @@ LIB_OBJ = lib/charcnv.o lib/debug.o lib/fault.o \ lib/util.o lib/util_sock.o lib/sock_exec.o lib/util_sec.o \ lib/talloc.o lib/hash.o lib/substitute.o lib/fsusage.o \ lib/ms_fnmatch.o lib/select.o lib/messages.o \ - lib/tallocmsg.o lib/dmallocmsg.o \ + lib/tallocmsg.o lib/dmallocmsg.o libsmb/smb_signing.o \ lib/md5.o lib/hmacmd5.o lib/iconv.o lib/smbpasswd.o \ nsswitch/wb_client.o nsswitch/wb_common.o \ lib/pam_errors.o intl/lang_tdb.o lib/account_pol.o \ @@ -216,7 +215,7 @@ LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \ libsmb/clirap.o libsmb/clierror.o libsmb/climessage.o \ libsmb/clireadwrite.o libsmb/clilist.o libsmb/cliprint.o \ libsmb/clitrans.o libsmb/clisecdesc.o libsmb/clidgram.o \ - libsmb/clistr.o libsmb/smb_signing.o \ + libsmb/clistr.o \ libsmb/cliquota.o libsmb/clifsinfo.o \ libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o \ libsmb/clioplock.o libsmb/errormap.o libsmb/clirap2.o \ @@ -300,6 +299,7 @@ VFS_EXTD_AUDIT_OBJ = modules/vfs_extd_audit.o VFS_FAKE_PERMS_OBJ = modules/vfs_fake_perms.o VFS_RECYCLE_OBJ = modules/vfs_recycle.o VFS_NETATALK_OBJ = modules/vfs_netatalk.o +VFS_DEFAULT_QUOTA_OBJ = modules/vfs_default_quota.o PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o @@ -389,17 +389,18 @@ SWAT_OBJ1 = web/cgi.o web/diagnose.o web/startstop.o web/statuspage.o \ SWAT_OBJ = $(SWAT_OBJ1) $(PARAM_OBJ) $(PRINTING_OBJ) $(LIBSMB_OBJ) \ $(LOCKING_OBJ) $(PASSDB_OBJ) $(SECRETS_OBJ) $(KRBCLIENT_OBJ) \ $(UBIQX_OBJ) $(LIB_OBJ) $(GROUPDB_OBJ) $(PLAINTEXT_AUTH_OBJ) \ - $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) + $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) lib/dummyroot.o SMBSH_OBJ = smbwrapper/smbsh.o smbwrapper/shared.o \ $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) STATUS_OBJ = utils/status.o $(LOCKING_OBJ) $(PARAM_OBJ) \ - $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) $(POPT_LIB_OBJ) + $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) $(POPT_LIB_OBJ) \ + lib/dummyroot.o libsmb/errormap.o SMBCONTROL_OBJ = utils/smbcontrol.o $(LOCKING_OBJ) $(PARAM_OBJ) \ $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) $(POPT_LIB_OBJ) \ - printing/notify.o printing/printing_db.o + printing/notify.o printing/printing_db.o lib/dummyroot.o libsmb/errormap.o SMBTREE_OBJ = utils/smbtree.o $(LOCKING_OBJ) $(PARAM_OBJ) \ $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) $(LIBSMB_OBJ) \ @@ -414,11 +415,11 @@ TESTPRNS_OBJ = utils/testprns.o $(PARAM_OBJ) $(PRINTING_OBJ) $(UBIQX_OBJ) \ SMBPASSWD_OBJ = utils/smbpasswd.o $(PARAM_OBJ) $(SECRETS_OBJ) \ $(LIBSMB_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ)\ $(UBIQX_OBJ) $(LIB_OBJ) $(KRBCLIENT_OBJ) \ - $(SMBLDAP_OBJ) + $(SMBLDAP_OBJ) lib/dummyroot.o PDBEDIT_OBJ = utils/pdbedit.o $(PARAM_OBJ) $(PASSDB_OBJ) $(LIBSAMBA_OBJ) \ $(UBIQX_OBJ) $(LIB_OBJ) $(GROUPDB_OBJ) $(SECRETS_OBJ) \ - $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) + $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) lib/dummyroot.o RPCCLIENT_OBJ1 = rpcclient/rpcclient.o rpcclient/cmd_lsarpc.o \ rpcclient/cmd_samr.o rpcclient/cmd_spoolss.o \ @@ -432,9 +433,9 @@ RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \ $(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(LIBMSRPC_OBJ) \ $(READLINE_OBJ) $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) \ $(LIBADS_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) \ - $(SMBLDAP_OBJ) $(DCUTIL_OBJ) + $(SMBLDAP_OBJ) $(DCUTIL_OBJ) lib/dummyroot.o -PAM_WINBIND_OBJ = nsswitch/pam_winbind.po nsswitch/wb_common.po lib/snprintf.po +PAM_WINBIND_OBJ = nsswitch/pam_winbind.po nsswitch/wb_common.po lib/replace1.po lib/snprintf.po SMBW_OBJ1 = smbwrapper/smbw.o \ smbwrapper/smbw_dir.o smbwrapper/smbw_stat.o \ @@ -460,7 +461,7 @@ LIBBIGBALLOFMUD_MAJOR = 0 LIBBIGBALLOFMUD_OBJ = $(PARAM_OBJ) $(LIB_OBJ) $(UBIQX_OBJ) $(SECRETS_OBJ) \ $(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) \ - $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ) + $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ) lib/dummyroot.o LIBBIGBALLOFMUD_PICOBJS = $(LIBBIGBALLOFMUD_OBJ:.o=.po) @@ -480,7 +481,7 @@ NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \ $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \ $(LIBMSRPC_OBJ) $(IDMAP_OBJ) \ $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) $(POPT_LIB_OBJ) \ - $(SMBLDAP_OBJ) $(DCUTIL_OBJ) + $(SMBLDAP_OBJ) $(DCUTIL_OBJ) lib/dummyroot.o lib/server_mutex.o CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \ $(LIB_OBJ) $(KRBCLIENT_OBJ) @@ -559,7 +560,7 @@ PROTO_OBJ = $(SMBD_OBJ_MAIN) \ $(LIB_SMBD_OBJ) $(SAM_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \ $(RPC_LSA_OBJ) $(RPC_NETLOG_OBJ) $(RPC_SAMR_OBJ) $(RPC_REG_OBJ) \ $(RPC_SVC_OBJ) $(RPC_WKS_OBJ) $(RPC_DFS_OBJ) $(RPC_SPOOLSS_OBJ) \ - $(RPC_ECHO_OBJ) $(SMBLDAP_OBJ) $(IDMAP_OBJ) + $(RPC_ECHO_OBJ) $(SMBLDAP_OBJ) $(IDMAP_OBJ) libsmb/spnego.o WINBIND_WINS_NSS_OBJ = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) \ $(LIBSMB_OBJ) $(LIB_OBJ) $(NSSWINS_OBJ) @@ -601,21 +602,22 @@ WINBINDD_OBJ = \ $(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) \ $(PROFILE_OBJ) $(SLCACHE_OBJ) $(SMBLDAP_OBJ) \ $(SECRETS_OBJ) $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) \ - $(DCUTIL_OBJ) $(IDMAP_OBJ) + $(DCUTIL_OBJ) $(IDMAP_OBJ) lib/dummyroot.o WBINFO_OBJ = nsswitch/wbinfo.o $(LIBSAMBA_OBJ) $(PARAM_OBJ) $(LIB_OBJ) \ $(UBIQX_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) -WINBIND_NSS_OBJ = nsswitch/wb_common.o @WINBIND_NSS_EXTRA_OBJS@ +WINBIND_NSS_OBJ = nsswitch/wb_common.o lib/replace1.o @WINBIND_NSS_EXTRA_OBJS@ -WINBIND_NSS_PICOBJS = $(WINBIND_NSS_OBJ:.o=.po) +WINBIND_NSS_PICOBJS = $(WINBIND_NSS_OBJ:.o=.po) lib/snprintf.po POPT_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \ popt/popthelp.o popt/poptparse.o TDBBACKUP_OBJ = tdb/tdbbackup.o tdb/tdbback.o $(TDBBASE_OBJ) -NTLM_AUTH_OBJ = utils/ntlm_auth.o $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ) +NTLM_AUTH_OBJ = utils/ntlm_auth.o $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ) \ + libsmb/asn1.o libsmb/spnego.o ###################################################################### # now the rules... @@ -727,12 +729,12 @@ bin/.dummy: bin/smbd@EXEEXT@: $(SMBD_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SMBD_OBJ) $(ADSLIBS) $(LDFLAGS) $(DYNEXP) $(PRINTLIBS) \ + @$(CC) $(FLAGS) -o $@ $(SMBD_OBJ) $(KRB5LIBS) $(LDAPLIBS) $(LDFLAGS) $(DYNEXP) $(PRINTLIBS) \ $(AUTHLIBS) $(ACLLIBS) $(PASSDBLIBS) $(LIBS) @POPTLIBS@ bin/nmbd@EXEEXT@: $(NMBD_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(NMBD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(ADSLIBS) + @$(CC) $(FLAGS) -o $@ $(NMBD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAPLIBS) bin/wrepld@EXEEXT@: $(WREPL_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ @@ -741,19 +743,19 @@ bin/wrepld@EXEEXT@: $(WREPL_OBJ) @BUILD_POPT@ bin/.dummy bin/swat@EXEEXT@: $(SWAT_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(SWAT_OBJ) $(LDFLAGS) $(DYNEXP) $(PRINTLIBS) \ - $(AUTHLIBS) $(LIBS) $(PASSDBLIBS) @POPTLIBS@ $(KRB5LIBS) + $(AUTHLIBS) $(LIBS) $(PASSDBLIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAPLIBS) bin/rpcclient@EXEEXT@: $(RPCCLIENT_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(PASSDBLIBS) $(RPCCLIENT_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ $(ADSLIBS) + @$(CC) $(FLAGS) -o $@ $(PASSDBLIBS) $(RPCCLIENT_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAPLIBS) bin/smbclient@EXEEXT@: $(CLIENT_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(CLIENT_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ $(ADSLIBS) + @$(CC) $(FLAGS) -o $@ $(CLIENT_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAPLIBS) bin/net@EXEEXT@: $(NET_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(NET_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(ADSLIBS) $(PASSDBLIBS) + @$(CC) $(FLAGS) -o $@ $(NET_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAPLIBS) $(PASSDBLIBS) bin/profiles@EXEEXT@: $(PROFILES_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ @@ -801,7 +803,7 @@ bin/smbtree@EXEEXT@: $(SMBTREE_OBJ) @BUILD_POPT@ bin/.dummy bin/smbpasswd@EXEEXT@: $(SMBPASSWD_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SMBPASSWD_OBJ) $(PASSDBLIBS) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) + @$(CC) $(FLAGS) -o $@ $(SMBPASSWD_OBJ) $(PASSDBLIBS) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAPLIBS) bin/pdbedit@EXEEXT@: $(PDBEDIT_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ @@ -873,7 +875,7 @@ bin/smbfilter@EXEEXT@: $(SMBFILTER_OBJ) bin/.dummy bin/smbw_sample@EXEEXT@: $(SMBW_OBJ) utils/smbw_sample.o bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SMBW_OBJ) utils/smbw_sample.o $(LDFLAGS) $(LIBS) $(KRB5LIBS) + @$(CC) $(FLAGS) -o $@ $(SMBW_OBJ) utils/smbw_sample.o $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAPLIBS) bin/smbsh@EXEEXT@: $(SMBSH_OBJ) bin/.dummy @echo Linking $@ @@ -882,12 +884,14 @@ bin/smbsh@EXEEXT@: $(SMBSH_OBJ) bin/.dummy bin/smbwrapper.@SHLIBEXT@: $(PICOBJS) bin/.dummy @echo Linking shared library $@ @$(SHLD) $(LDSHFLAGS) -o $@ $(PICOBJS) $(LIBS) \ - @SONAMEFLAG@`basename $@` $(KRB5LIBS) + $(KRB5LIBS) $(LDAPLIBS) \ + @SONAMEFLAG@`basename $@` bin/libsmbclient.@SHLIBEXT@: $(LIBSMBCLIENT_PICOBJS) @echo Linking libsmbclient shared library $@ @$(SHLD) $(LDSHFLAGS) -o $@ $(LIBSMBCLIENT_PICOBJS) $(LDFLAGS) $(LIBS) \ - $(KRB5LIBS) @SONAMEFLAG@`basename $@`.$(LIBSMBCLIENT_MAJOR) + $(KRB5LIBS) $(LDAPLIBS) \ + @SONAMEFLAG@`basename $@`.$(LIBSMBCLIENT_MAJOR) bin/libsmbclient.a: $(LIBSMBCLIENT_PICOBJS) @echo Linking libsmbclient non-shared library $@ @@ -897,7 +901,8 @@ bin/libsmbclient.a: $(LIBSMBCLIENT_PICOBJS) bin/libbigballofmud.@SHLIBEXT@: $(LIBBIGBALLOFMUD_PICOBJS) @echo Linking bigballofmud shared library $@ @$(SHLD) $(LDSHFLAGS) -o $@ $(LIBBIGBALLOFMUD_PICOBJS) $(LIBS) \ - @SONAMEFLAG@`basename $@`.$(LIBBIGBALLOFMUD_MAJOR) $(PASSDBLIBS) $(IDMAP_LIBS) $(ADSLIBS) + $(PASSDBLIBS) $(IDMAP_LIBS) $(KRB5LIBS) $(LDAPLIBS) \ + @SONAMEFLAG@`basename $@`.$(LIBBIGBALLOFMUD_MAJOR) ln -snf libbigballofmud.so bin/libbigballofmud.so.0 # It would be nice to build a static bigballofmud too, but when I try @@ -963,7 +968,8 @@ bin/winbindd@EXEEXT@: $(WINBINDD_OBJ) @BUILD_POPT@ bin/.dummy @WINBIND_WINS_NSS@: $(WINBIND_WINS_NSS_PICOBJS) @echo "Linking $@" - @$(SHLD) $(LDSHFLAGS) -o $@ $(WINBIND_WINS_NSS_PICOBJS) -lc \ + @$(SHLD) $(LDSHFLAGS) -o $@ $(WINBIND_WINS_NSS_PICOBJS) \ + $(KRBCLIENT_OBJ) $(LDAPLIBS) $(KRB5LIBS) -lc \ @SONAMEFLAG@`basename $@` nsswitch/pam_winbind.@SHLIBEXT@: $(PAM_WINBIND_OBJ) bin/.dummy @@ -1054,6 +1060,11 @@ bin/fake_perms.@SHLIBEXT@: $(VFS_FAKE_PERMS_OBJ:.o=.po) @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_FAKE_PERMS_OBJ:.o=.po) \ @SONAMEFLAG@`basename $@` +bin/default_quota.@SHLIBEXT@: $(VFS_DEFAULT_QUOTA_OBJ:.o=.po) + @echo "Building plugin $@" + @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_DEFAULT_QUOTA_OBJ:.o=.po) \ + @SONAMEFLAG@`basename $@` + bin/wbinfo@EXEEXT@: $(WBINFO_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ @$(LINK) -o $@ $(WBINFO_OBJ) $(LIBS) @POPTLIBS@ @@ -1138,7 +1149,7 @@ installclientlib: installdirs libsmbclient PYTHON_OBJS = $(PARAM_OBJ) $(LIB_OBJ) $(LIBSMB_OBJ) $(RPC_PARSE_OBJ) \ $(UBIQX_OBJ) $(LIBMSRPC_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \ - $(SECRETS_OBJ) $(KRBCLIENT_OBJ) + $(SECRETS_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ) lib/dummyroot.o PYTHON_PICOBJS = $(PYTHON_OBJS:.o=.po) @@ -1149,7 +1160,7 @@ python_ext: $(PYTHON_PICOBJS) fi PYTHON_OBJS="$(PYTHON_PICOBJS)" \ PYTHON_CFLAGS="$(CFLAGS) $(CPPFLAGS) $(FLAGS)" \ - LIBS="$(LIBS) $(PASSDBLIBS) $(IDMAP_LIBS) $(KRB5LIBS)" \ + LIBS="$(LIBS) $(PASSDBLIBS) $(IDMAP_LIBS) $(KRB5LIBS) $(LDAPLIBS)" \ $(PYTHON) python/setup.py build python_install: $(PYTHON_PICOBJS) @@ -1185,7 +1196,7 @@ showlayout: @echo " mandir: $(MANDIR)" -uninstall: uninstallman uninstallbin uninstallscripts +uninstall: uninstallman uninstallbin uninstallscripts uninstallmodules uninstallman: @$(SHELL) $(srcdir)/script/uninstallman.sh $(DESTDIR)$(MANDIR) $(srcdir) $(man_langs) diff --git a/source3/aclocal.m4 b/source3/aclocal.m4 index 21358e2a71..3a49f7e249 100644 --- a/source3/aclocal.m4 +++ b/source3/aclocal.m4 @@ -111,6 +111,113 @@ AC_DEFUN(AC_LIBTESTFUNC, esac ]) +# AC_CHECK_LIB_EXT(LIBRARY, [EXT_LIBS], [FUNCTION], +# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], +# [ADD-ACTION-IF-FOUND],[OTHER-LIBRARIES]) +# ------------------------------------------------------ +# +# Use a cache variable name containing both the library and function name, +# because the test really is for library $1 defining function $3, not +# just for library $1. Separate tests with the same $1 and different $3s +# may have different results. +# +# Note that using directly AS_VAR_PUSHDEF([ac_Lib], [ac_cv_lib_$1_$3]) +# is asking for troubles, since AC_CHECK_LIB($lib, fun) would give +# ac_cv_lib_$lib_fun, which is definitely not what was meant. Hence +# the AS_LITERAL_IF indirection. +# +# FIXME: This macro is extremely suspicious. It DEFINEs unconditionnally, +# whatever the FUNCTION, in addition to not being a *S macro. Note +# that the cache does depend upon the function we are looking for. +# +# It is on purpose we used `ac_check_lib_ext_save_LIBS' and not just +# `ac_save_LIBS': there are many macros which don't want to see `LIBS' +# changed but still want to use AC_CHECK_LIB_EXT, so they save `LIBS'. +# And ``ac_save_LIBS' is too tempting a name, so let's leave them some +# freedom. +AC_DEFUN([AC_CHECK_LIB_EXT], +[ +AH_CHECK_LIB_EXT([$1]) +ac_check_lib_ext_save_LIBS=$LIBS +LIBS="-l$1 $$2 $7 $LIBS" +AS_LITERAL_IF([$1], + [AS_VAR_PUSHDEF([ac_Lib_ext], [ac_cv_lib_ext_$1])], + [AS_VAR_PUSHDEF([ac_Lib_ext], [ac_cv_lib_ext_$1''])])dnl + +m4_ifval([$3], + [ + AH_CHECK_FUNC_EXT([$3]) + AS_LITERAL_IF([$1], + [AS_VAR_PUSHDEF([ac_Lib_func], [ac_cv_lib_ext_$1_$3])], + [AS_VAR_PUSHDEF([ac_Lib_func], [ac_cv_lib_ext_$1''_$3])])dnl + AC_CACHE_CHECK([for $3 in -l$1], ac_Lib_func, + [AC_TRY_LINK_FUNC($3, + [AS_VAR_SET(ac_Lib_func, yes); + AS_VAR_SET(ac_Lib_ext, yes)], + [AS_VAR_SET(ac_Lib_func, no); + AS_VAR_SET(ac_Lib_ext, no)]) + ]) + AS_IF([test AS_VAR_GET(ac_Lib_func) = yes], + [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_$3))])dnl + AS_VAR_POPDEF([ac_Lib_func])dnl + ],[ + AC_CACHE_CHECK([for -l$1], ac_Lib_ext, + [AC_TRY_LINK_FUNC([main], + [AS_VAR_SET(ac_Lib_ext, yes)], + [AS_VAR_SET(ac_Lib_ext, no)]) + ]) + ]) +LIBS=$ac_check_lib_ext_save_LIBS + +AS_IF([test AS_VAR_GET(ac_Lib_ext) = yes], + [m4_default([$4], + [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_LIB$1)) + case "$$2" in + *-l$1*) + ;; + *) + $2="$$2 -l$1" + ;; + esac]) + [$6] + ], + [$5])dnl +AS_VAR_POPDEF([ac_Lib_ext])dnl +])# AC_CHECK_LIB_EXT + +# AH_CHECK_LIB_EXT(LIBNAME) +# --------------------- +m4_define([AH_CHECK_LIB_EXT], +[AH_TEMPLATE(AS_TR_CPP(HAVE_LIB$1), + [Define to 1 if you have the `]$1[' library (-l]$1[).])]) + +# AC_CHECK_FUNCS_EXT(FUNCTION, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# ----------------------------------------------------------------- +dnl check for a function in a $LIBS and $OTHER_LIBS libraries variable. +dnl AC_CHECK_FUNC_EXT(func,OTHER_LIBS,IF-TRUE,IF-FALSE) +AC_DEFUN([AC_CHECK_FUNC_EXT], +[ + AH_CHECK_FUNC_EXT($1) + ac_check_func_ext_save_LIBS=$LIBS + LIBS="$2 $LIBS" + AS_VAR_PUSHDEF([ac_var], [ac_cv_func_ext_$1])dnl + AC_CACHE_CHECK([for $1], ac_var, + [AC_LINK_IFELSE([AC_LANG_FUNC_LINK_TRY([$1])], + [AS_VAR_SET(ac_var, yes)], + [AS_VAR_SET(ac_var, no)])]) + LIBS=$ac_check_func_ext_save_LIBS + AS_IF([test AS_VAR_GET(ac_var) = yes], + [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_$1])) $3], + [$4])dnl +AS_VAR_POPDEF([ac_var])dnl +])# AC_CHECK_FUNC + +# AH_CHECK_FUNC_EXT(FUNCNAME) +# --------------------- +m4_define([AH_CHECK_FUNC_EXT], +[AH_TEMPLATE(AS_TR_CPP(HAVE_$1), + [Define to 1 if you have the `]$1[' function.])]) + dnl Define an AC_DEFINE with ifndef guard. dnl AC_N_DEFINE(VARIABLE [, VALUE]) define(AC_N_DEFINE, diff --git a/source3/auth/auth.c b/source3/auth/auth.c index a2486acbd1..8316c4b617 100644 --- a/source3/auth/auth.c +++ b/source3/auth/auth.c @@ -512,7 +512,7 @@ NTSTATUS make_auth_context_fixed(struct auth_context **auth_context, uchar chal[ return nt_status; } - (*auth_context)->challenge = data_blob(chal, 8); + (*auth_context)->challenge = data_blob_talloc((*auth_context)->mem_ctx, chal, 8); (*auth_context)->challenge_set_by = "fixed"; return nt_status; } diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index 56bd6b9aca..aacea261fe 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -69,7 +69,7 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli, /* Attempt connection */ *retry = True; result = cli_full_connection(cli, global_myname(), dc_name, &dc_ip, 0, - "IPC$", "IPC", "", "", "", 0, retry); + "IPC$", "IPC", "", "", "", 0, Undefined, retry); if (!NT_STATUS_IS_OK(result)) { /* map to something more useful */ @@ -104,7 +104,7 @@ machine %s. Error was : %s.\n", dc_name, cli_errstr(*cli))); return NT_STATUS_NO_LOGON_SERVERS; } - snprintf((*cli)->mach_acct, sizeof((*cli)->mach_acct) - 1, "%s$", setup_creds_as); + fstr_sprintf((*cli)->mach_acct, "%s$", setup_creds_as); if (!(*cli)->mach_acct) { release_server_mutex(); diff --git a/source3/auth/auth_ntlmssp.c b/source3/auth/auth_ntlmssp.c index a381219d74..3af0cbaada 100644 --- a/source3/auth/auth_ntlmssp.c +++ b/source3/auth/auth_ntlmssp.c @@ -135,4 +135,3 @@ NTSTATUS auth_ntlmssp_update(AUTH_NTLMSSP_STATE *auth_ntlmssp_state, { return ntlmssp_server_update(auth_ntlmssp_state->ntlmssp_state, request, reply); } - diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c index 012696f46a..fb66d53cd4 100644 --- a/source3/auth/auth_sam.c +++ b/source3/auth/auth_sam.c @@ -44,12 +44,12 @@ static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response, } if (sec_blob->length != 8) { - DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect challenge size (%d)\n", sec_blob->length)); + DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect challenge size (%lu)\n", (unsigned long)sec_blob->length)); return False; } if (nt_response->length != 24) { - DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%d)\n", nt_response->length)); + DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%lu)\n", (unsigned long)nt_response->length)); return False; } @@ -103,8 +103,8 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response, /* We MUST have more than 16 bytes, or the stuff below will go crazy. No known implementation sends less than the 24 bytes for LMv2, let alone NTLMv2. */ - DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%d)\n", - ntv2_response->length)); + DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%lu)\n", + (unsigned long)ntv2_response->length)); return False; } @@ -233,8 +233,8 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context, if (auth_flags & AUTH_FLAG_LM_RESP) { if (user_info->lm_resp.length != 24) { - DEBUG(2,("sam_password_ok: invalid LanMan password length (%d) for user %s\n", - user_info->nt_resp.length, pdb_get_username(sampass))); + DEBUG(2,("sam_password_ok: invalid LanMan password length (%lu) for user %s\n", + (unsigned long)user_info->nt_resp.length, pdb_get_username(sampass))); } if (!lp_lanman_auth()) { diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 8e1b420b47..5403ee8c39 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -68,7 +68,7 @@ void auth_add_user_script(const char *domain, const char *username) * user on the fly, do so. */ - if ( lp_adduser_script() ) + if ( *lp_adduser_script() ) smb_create_user(domain, username, NULL); else { DEBUG(10,("auth_add_user_script: no 'add user script'. Asking winbindd\n")); @@ -133,7 +133,7 @@ static NTSTATUS make_user_info(auth_usersupplied_info **user_info, *user_info = malloc(sizeof(**user_info)); if (!user_info) { - DEBUG(0,("malloc failed for user_info (size %d)\n", sizeof(*user_info))); + DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info))); return NT_STATUS_NO_MEMORY; } @@ -489,9 +489,9 @@ void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token) DEBUGC(dbg_class, dbg_lev, ("NT user token of user %s\n", sid_to_string(sid_str, &token->user_sids[0]) )); - DEBUGADDC(dbg_class, dbg_lev, ("contains %i SIDs\n", token->num_sids)); + DEBUGADDC(dbg_class, dbg_lev, ("contains %lu SIDs\n", (unsigned long)token->num_sids)); for (i = 0; i < token->num_sids; i++) - DEBUGADDC(dbg_class, dbg_lev, ("SID[%3i]: %s\n", i, + DEBUGADDC(dbg_class, dbg_lev, ("SID[%3lu]: %s\n", (unsigned long)i, sid_to_string(sid_str, &token->user_sids[i]))); } diff --git a/source3/client/client.c b/source3/client/client.c index d9c3a7aa1b..ec29f44e6e 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -438,7 +438,8 @@ static void add_to_do_list_queue(const char* entry) } if (do_list_queue) { - pstrcpy(do_list_queue + do_list_queue_end, entry); + safe_strcpy_base(do_list_queue + do_list_queue_end, + entry, do_list_queue, do_list_queue_size); do_list_queue_end = new_end; DEBUG(4,("added %s to do_list_queue (start=%d, end=%d)\n", entry, (int)do_list_queue_start, (int)do_list_queue_end)); @@ -481,6 +482,11 @@ static void do_list_helper(file_info *f, const char *mask, void *state) pstring mask2; char *p; + if (!f->name[0]) { + d_printf("Empty dir name returned. Possible server misconfiguration.\n"); + return; + } + pstrcpy(mask2, mask); p = strrchr_m(mask2,'\\'); if (!p) return; @@ -2285,9 +2291,9 @@ static char **remote_completion(const char *text, int len) if (i > 0) { strncpy(info.dirmask, text, i+1); info.dirmask[i+1] = 0; - snprintf(dirmask, sizeof(dirmask), "%s%*s*", cur_dir, i-1, text); + pstr_sprintf(dirmask, "%s%*s*", cur_dir, i-1, text); } else - snprintf(dirmask, sizeof(dirmask), "%s*", cur_dir); + pstr_sprintf(dirmask, "%s*", cur_dir); if (cli_list(cli, dirmask, aDIR | aSYSTEM | aHIDDEN, completion_remote_filter, &info) < 0) goto cleanup; @@ -2523,6 +2529,8 @@ static struct cli_state *do_connect(const char *server, const char *share) c->protocol = max_protocol; c->use_kerberos = use_kerberos; + cli_setup_signing_state(c, cmdline_auth_info.signing_state); + if (!cli_session_request(c, &calling, &called)) { char *p; @@ -2816,9 +2824,25 @@ static void remember_query_host(const char *arg, max_protocol = interpret_protocol(poptGetOptArg(pc), max_protocol); break; case 'T': - if (!tar_parseargs(argc, argv, poptGetOptArg(pc), optind)) { - poptPrintUsage(pc, stderr, 0); - exit(1); + /* We must use old option processing for this. Find the + * position of the -T option in the raw argv[]. */ + { + int i, optnum; + for (i = 1; i < argc; i++) { + if (strncmp("-T", argv[i],2)==0) + break; + } + i++; + if (!(optnum = tar_parseargs(argc, argv, poptGetOptArg(pc), i))) { + poptPrintUsage(pc, stderr, 0); + exit(1); + } + /* Now we must eat (optnum - i) options - they have + * been processed by tar_parseargs(). + */ + optnum -= i; + for (i = 0; i < optnum; i++) + poptGetOptArg(pc); } break; case 'D': @@ -2843,7 +2867,7 @@ static void remember_query_host(const char *arg, } } - if (poptPeekArg(pc)) { + if (poptPeekArg(pc) && !cmdline_auth_info.got_pass) { cmdline_auth_info.got_pass = True; pstrcpy(cmdline_auth_info.password,poptGetArg(pc)); } diff --git a/source3/client/clitar.c b/source3/client/clitar.c index 765bc2a659..5295de8010 100644 --- a/source3/client/clitar.c +++ b/source3/client/clitar.c @@ -43,27 +43,23 @@ static int clipfind(char **aret, int ret, char *tok); typedef struct file_info_struct file_info2; -struct file_info_struct -{ - SMB_BIG_UINT size; - uint16 mode; - uid_t uid; - gid_t gid; - /* These times are normally kept in GMT */ - time_t mtime; - time_t atime; - time_t ctime; - char *name; /* This is dynamically allocate */ - - file_info2 *next, *prev; /* Used in the stack ... */ - +struct file_info_struct { + SMB_BIG_UINT size; + uint16 mode; + uid_t uid; + gid_t gid; + /* These times are normally kept in GMT */ + time_t mtime; + time_t atime; + time_t ctime; + char *name; /* This is dynamically allocate */ + + file_info2 *next, *prev; /* Used in the stack ... */ }; -typedef struct -{ - file_info2 *top; - int items; - +typedef struct { + file_info2 *top; + int items; } stack; #define SEPARATORS " \t\n\r" @@ -145,285 +141,284 @@ static void unfixtarname(char *tptr, char *fp, int l, BOOL first); /******************************************************************* Create a string of size size+1 (for the null) *******************************************************************/ + static char *string_create_s(int size) { - char *tmp; + char *tmp; - tmp = (char *)malloc(size+1); + tmp = (char *)malloc(size+1); - if (tmp == NULL) { - - DEBUG(0, ("Out of memory in string_create_s\n")); - - } - - return(tmp); + if (tmp == NULL) { + DEBUG(0, ("Out of memory in string_create_s\n")); + } + return(tmp); } /**************************************************************************** Write a tar header to buffer ****************************************************************************/ + static void writetarheader(int f, const char *aname, SMB_BIG_UINT size, time_t mtime, const char *amode, unsigned char ftype) { - union hblock hb; - int i, chk, l; - char *jp; + union hblock hb; + int i, chk, l; + char *jp; - DEBUG(5, ("WriteTarHdr, Type = %c, Size= %.0f, Name = %s\n", ftype, (double)size, aname)); + DEBUG(5, ("WriteTarHdr, Type = %c, Size= %.0f, Name = %s\n", ftype, (double)size, aname)); - memset(hb.dummy, 0, sizeof(hb.dummy)); + memset(hb.dummy, 0, sizeof(hb.dummy)); - l=strlen(aname); - if (l >= NAMSIZ - 1) { - /* write a GNU tar style long header */ - char *b; - b = (char *)malloc(l+TBLOCK+100); - if (!b) { - DEBUG(0,("out of memory\n")); - exit(1); - } - writetarheader(f, "/./@LongLink", l+2, 0, " 0 \0", 'L'); - memset(b, 0, l+TBLOCK+100); - fixtarname(b, aname, l); - i = strlen(b)+1; - DEBUG(5, ("File name in tar file: %s, size=%d, \n", b, (int)strlen(b))); - dotarbuf(f, b, TBLOCK*(((i-1)/TBLOCK)+1)); - SAFE_FREE(b); - } - - /* use l + 1 to do the null too */ - fixtarname(hb.dbuf.name, aname, (l >= NAMSIZ) ? NAMSIZ : l + 1); - - if (lowercase) - strlower_m(hb.dbuf.name); - - /* write out a "standard" tar format header */ - - hb.dbuf.name[NAMSIZ-1]='\0'; - safe_strcpy(hb.dbuf.mode, amode, sizeof(hb.dbuf.mode)-1); - oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.uid); - oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.gid); - oct_it((SMB_BIG_UINT) size, 13, hb.dbuf.size); - if (size > (SMB_BIG_UINT)077777777777LL) { - - /* This is a non-POSIX compatible extention to store files - greater than 8GB. */ - - memset(hb.dbuf.size, 0, 4); - hb.dbuf.size[0]=128; - for (i = 8, jp=(char*)&size; i; i--) - hb.dbuf.size[i+3] = *(jp++); - } - oct_it((SMB_BIG_UINT) mtime, 13, hb.dbuf.mtime); - memcpy(hb.dbuf.chksum, " ", sizeof(hb.dbuf.chksum)); - memset(hb.dbuf.linkname, 0, NAMSIZ); - hb.dbuf.linkflag=ftype; + l=strlen(aname); + if (l >= NAMSIZ - 1) { + /* write a GNU tar style long header */ + char *b; + b = (char *)malloc(l+TBLOCK+100); + if (!b) { + DEBUG(0,("out of memory\n")); + exit(1); + } + writetarheader(f, "/./@LongLink", l+2, 0, " 0 \0", 'L'); + memset(b, 0, l+TBLOCK+100); + fixtarname(b, aname, l); + i = strlen(b)+1; + DEBUG(5, ("File name in tar file: %s, size=%d, \n", b, (int)strlen(b))); + dotarbuf(f, b, TBLOCK*(((i-1)/TBLOCK)+1)); + SAFE_FREE(b); + } + + /* use l + 1 to do the null too */ + fixtarname(hb.dbuf.name, aname, (l >= NAMSIZ) ? NAMSIZ : l + 1); + + if (lowercase) + strlower_m(hb.dbuf.name); + + /* write out a "standard" tar format header */ + + hb.dbuf.name[NAMSIZ-1]='\0'; + safe_strcpy(hb.dbuf.mode, amode, sizeof(hb.dbuf.mode)-1); + oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.uid); + oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.gid); + oct_it((SMB_BIG_UINT) size, 13, hb.dbuf.size); + if (size > (SMB_BIG_UINT)077777777777LL) { + + /* This is a non-POSIX compatible extention to store files + greater than 8GB. */ + + memset(hb.dbuf.size, 0, 4); + hb.dbuf.size[0]=128; + for (i = 8, jp=(char*)&size; i; i--) + hb.dbuf.size[i+3] = *(jp++); + } + oct_it((SMB_BIG_UINT) mtime, 13, hb.dbuf.mtime); + memcpy(hb.dbuf.chksum, " ", sizeof(hb.dbuf.chksum)); + memset(hb.dbuf.linkname, 0, NAMSIZ); + hb.dbuf.linkflag=ftype; - for (chk=0, i=sizeof(hb.dummy), jp=hb.dummy; --i>=0;) chk+=(0xFF & *jp++); + for (chk=0, i=sizeof(hb.dummy), jp=hb.dummy; --i>=0;) + chk+=(0xFF & *jp++); - oct_it((SMB_BIG_UINT) chk, 8, hb.dbuf.chksum); - hb.dbuf.chksum[6] = '\0'; + oct_it((SMB_BIG_UINT) chk, 8, hb.dbuf.chksum); + hb.dbuf.chksum[6] = '\0'; - (void) dotarbuf(f, hb.dummy, sizeof(hb.dummy)); + (void) dotarbuf(f, hb.dummy, sizeof(hb.dummy)); } /**************************************************************************** Read a tar header into a hblock structure, and validate ***************************************************************************/ + static long readtarheader(union hblock *hb, file_info2 *finfo, char *prefix) { - long chk, fchk; - int i; - char *jp; - - /* - * read in a "standard" tar format header - we're not that interested - * in that many fields, though - */ - - /* check the checksum */ - for (chk=0, i=sizeof(hb->dummy), jp=hb->dummy; --i>=0;) chk+=(0xFF & *jp++); + long chk, fchk; + int i; + char *jp; - if (chk == 0) - return chk; - - /* compensate for blanks in chksum header */ - for (i=sizeof(hb->dbuf.chksum), jp=hb->dbuf.chksum; --i>=0;) - chk-=(0xFF & *jp++); + /* + * read in a "standard" tar format header - we're not that interested + * in that many fields, though + */ - chk += ' ' * sizeof(hb->dbuf.chksum); + /* check the checksum */ + for (chk=0, i=sizeof(hb->dummy), jp=hb->dummy; --i>=0;) + chk+=(0xFF & *jp++); - fchk=unoct(hb->dbuf.chksum, sizeof(hb->dbuf.chksum)); + if (chk == 0) + return chk; - DEBUG(5, ("checksum totals chk=%ld fchk=%ld chksum=%s\n", - chk, fchk, hb->dbuf.chksum)); + /* compensate for blanks in chksum header */ + for (i=sizeof(hb->dbuf.chksum), jp=hb->dbuf.chksum; --i>=0;) + chk-=(0xFF & *jp++); - if (fchk != chk) - { - DEBUG(0, ("checksums don't match %ld %ld\n", fchk, chk)); - dump_data(5, (char *)hb - TBLOCK, TBLOCK *3); - return -1; - } + chk += ' ' * sizeof(hb->dbuf.chksum); - if ((finfo->name = string_create_s(strlen(prefix) + strlen(hb -> dbuf.name) + 3)) == NULL) { + fchk=unoct(hb->dbuf.chksum, sizeof(hb->dbuf.chksum)); - DEBUG(0, ("Out of space creating file_info2 for %s\n", hb -> dbuf.name)); - return(-1); + DEBUG(5, ("checksum totals chk=%ld fchk=%ld chksum=%s\n", + chk, fchk, hb->dbuf.chksum)); - } + if (fchk != chk) { + DEBUG(0, ("checksums don't match %ld %ld\n", fchk, chk)); + dump_data(5, (char *)hb - TBLOCK, TBLOCK *3); + return -1; + } - safe_strcpy(finfo->name, prefix, strlen(prefix) + strlen(hb -> dbuf.name) + 3); + if ((finfo->name = string_create_s(strlen(prefix) + strlen(hb -> dbuf.name) + 3)) == NULL) { + DEBUG(0, ("Out of space creating file_info2 for %s\n", hb -> dbuf.name)); + return(-1); + } - /* use l + 1 to do the null too; do prefix - prefcnt to zap leading slash */ - unfixtarname(finfo->name + strlen(prefix), hb->dbuf.name, - strlen(hb->dbuf.name) + 1, True); + safe_strcpy(finfo->name, prefix, strlen(prefix) + strlen(hb -> dbuf.name) + 3); + + /* use l + 1 to do the null too; do prefix - prefcnt to zap leading slash */ + unfixtarname(finfo->name + strlen(prefix), hb->dbuf.name, + strlen(hb->dbuf.name) + 1, True); + + /* can't handle some links at present */ + if ((hb->dbuf.linkflag != '0') && (hb -> dbuf.linkflag != '5')) { + if (hb->dbuf.linkflag == 0) { + DEBUG(6, ("Warning: NULL link flag (gnu tar archive ?) %s\n", + finfo->name)); + } else { + if (hb -> dbuf.linkflag == 'L') { /* We have a longlink */ + /* Do nothing here at the moment. do_tarput will handle this + as long as the longlink gets back to it, as it has to advance + the buffer pointer, etc */ + } else { + DEBUG(0, ("this tar file appears to contain some kind \ +of link other than a GNUtar Longlink - ignoring\n")); + return -2; + } + } + } + + if ((unoct(hb->dbuf.mode, sizeof(hb->dbuf.mode)) & S_IFDIR) || + (*(finfo->name+strlen(finfo->name)-1) == '\\')) { + finfo->mode=aDIR; + } else { + finfo->mode=0; /* we don't care about mode at the moment, we'll + * just make it a regular file */ + } - /* can't handle some links at present */ - if ((hb->dbuf.linkflag != '0') && (hb -> dbuf.linkflag != '5')) { - if (hb->dbuf.linkflag == 0) { - DEBUG(6, ("Warning: NULL link flag (gnu tar archive ?) %s\n", - finfo->name)); - } else { - if (hb -> dbuf.linkflag == 'L') { /* We have a longlink */ - /* Do nothing here at the moment. do_tarput will handle this - as long as the longlink gets back to it, as it has to advance - the buffer pointer, etc */ + /* + * Bug fix by richard@sj.co.uk + * + * REC: restore times correctly (as does tar) + * We only get the modification time of the file; set the creation time + * from the mod. time, and the access time to current time + */ + finfo->mtime = finfo->ctime = strtol(hb->dbuf.mtime, NULL, 8); + finfo->atime = time(NULL); + finfo->size = unoct(hb->dbuf.size, sizeof(hb->dbuf.size)); - } else { - DEBUG(0, ("this tar file appears to contain some kind of link other than a GNUtar Longlink - ignoring\n")); - return -2; - } - } - } - - if ((unoct(hb->dbuf.mode, sizeof(hb->dbuf.mode)) & S_IFDIR) - || (*(finfo->name+strlen(finfo->name)-1) == '\\')) - { - finfo->mode=aDIR; - } - else - finfo->mode=0; /* we don't care about mode at the moment, we'll - * just make it a regular file */ - /* - * Bug fix by richard@sj.co.uk - * - * REC: restore times correctly (as does tar) - * We only get the modification time of the file; set the creation time - * from the mod. time, and the access time to current time - */ - finfo->mtime = finfo->ctime = strtol(hb->dbuf.mtime, NULL, 8); - finfo->atime = time(NULL); - finfo->size = unoct(hb->dbuf.size, sizeof(hb->dbuf.size)); - - return True; + return True; } /**************************************************************************** Write out the tar buffer to tape or wherever ****************************************************************************/ + static int dotarbuf(int f, char *b, int n) { - int fail=1, writ=n; - - if (dry_run) { - return writ; - } - /* This routine and the next one should be the only ones that do write()s */ - if (tp + n >= tbufsiz) - { - int diff; - - diff=tbufsiz-tp; - memcpy(tarbuf + tp, b, diff); - fail=fail && (1+write(f, tarbuf, tbufsiz)); - n-=diff; - b+=diff; - tp=0; - - while (n >= tbufsiz) - { - fail=fail && (1 + write(f, b, tbufsiz)); - n-=tbufsiz; - b+=tbufsiz; + int fail=1, writ=n; + + if (dry_run) { + return writ; + } + /* This routine and the next one should be the only ones that do write()s */ + if (tp + n >= tbufsiz) { + int diff; + + diff=tbufsiz-tp; + memcpy(tarbuf + tp, b, diff); + fail=fail && (1+write(f, tarbuf, tbufsiz)); + n-=diff; + b+=diff; + tp=0; + + while (n >= tbufsiz) { + fail=fail && (1 + write(f, b, tbufsiz)); + n-=tbufsiz; + b+=tbufsiz; + } } - } - if (n>0) { - memcpy(tarbuf+tp, b, n); - tp+=n; - } - return(fail ? writ : 0); + if (n>0) { + memcpy(tarbuf+tp, b, n); + tp+=n; + } + + return(fail ? writ : 0); } /**************************************************************************** Write zeros to buffer / tape ****************************************************************************/ + static void dozerobuf(int f, int n) { - /* short routine just to write out n zeros to buffer - - * used to round files to nearest block - * and to do tar EOFs */ + /* short routine just to write out n zeros to buffer - + * used to round files to nearest block + * and to do tar EOFs */ - if (dry_run) - return; + if (dry_run) + return; - if (n+tp >= tbufsiz) - { - memset(tarbuf+tp, 0, tbufsiz-tp); - - write(f, tarbuf, tbufsiz); - memset(tarbuf, 0, (tp+=n-tbufsiz)); - } - else - { - memset(tarbuf+tp, 0, n); - tp+=n; - } + if (n+tp >= tbufsiz) { + memset(tarbuf+tp, 0, tbufsiz-tp); + write(f, tarbuf, tbufsiz); + memset(tarbuf, 0, (tp+=n-tbufsiz)); + } else { + memset(tarbuf+tp, 0, n); + tp+=n; + } } /**************************************************************************** Malloc tape buffer ****************************************************************************/ + static void initarbuf(void) { - /* initialize tar buffer */ - tbufsiz=blocksize*TBLOCK; - tarbuf=malloc(tbufsiz); /* FIXME: We might not get the buffer */ + /* initialize tar buffer */ + tbufsiz=blocksize*TBLOCK; + tarbuf=malloc(tbufsiz); /* FIXME: We might not get the buffer */ - /* reset tar buffer pointer and tar file counter and total dumped */ - tp=0; ntarf=0; ttarf=0; + /* reset tar buffer pointer and tar file counter and total dumped */ + tp=0; ntarf=0; ttarf=0; } /**************************************************************************** Write two zero blocks at end of file ****************************************************************************/ + static void dotareof(int f) { - SMB_STRUCT_STAT stbuf; - /* Two zero blocks at end of file, write out full buffer */ + SMB_STRUCT_STAT stbuf; + /* Two zero blocks at end of file, write out full buffer */ - if (dry_run) - return; + if (dry_run) + return; - (void) dozerobuf(f, TBLOCK); - (void) dozerobuf(f, TBLOCK); + (void) dozerobuf(f, TBLOCK); + (void) dozerobuf(f, TBLOCK); - if (sys_fstat(f, &stbuf) == -1) - { - DEBUG(0, ("Couldn't stat file handle\n")); - return; - } + if (sys_fstat(f, &stbuf) == -1) { + DEBUG(0, ("Couldn't stat file handle\n")); + return; + } - /* Could be a pipe, in which case S_ISREG should fail, - * and we should write out at full size */ - if (tp > 0) write(f, tarbuf, S_ISREG(stbuf.st_mode) ? tp : tbufsiz); + /* Could be a pipe, in which case S_ISREG should fail, + * and we should write out at full size */ + if (tp > 0) + write(f, tarbuf, S_ISREG(stbuf.st_mode) ? tp : tbufsiz); } /**************************************************************************** (Un)mangle DOS pathname, make nonabsolute ****************************************************************************/ + static void fixtarname(char *tptr, const char *fp, int l) { /* add a '.' to start of file name, convert from ugly dos \'s in path @@ -437,43 +432,43 @@ static void fixtarname(char *tptr, const char *fp, int l) /**************************************************************************** Convert from decimal to octal string ****************************************************************************/ + static void oct_it (SMB_BIG_UINT value, int ndgs, char *p) { - /* Converts long to octal string, pads with leading zeros */ + /* Converts long to octal string, pads with leading zeros */ - /* skip final null, but do final space */ - --ndgs; - p[--ndgs] = ' '; + /* skip final null, but do final space */ + --ndgs; + p[--ndgs] = ' '; - /* Loop does at least one digit */ - do { - p[--ndgs] = '0' + (char) (value & 7); - value >>= 3; - } - while (ndgs > 0 && value != 0); + /* Loop does at least one digit */ + do { + p[--ndgs] = '0' + (char) (value & 7); + value >>= 3; + } while (ndgs > 0 && value != 0); - /* Do leading zeros */ - while (ndgs > 0) - p[--ndgs] = '0'; + /* Do leading zeros */ + while (ndgs > 0) + p[--ndgs] = '0'; } /**************************************************************************** Convert from octal string to long ***************************************************************************/ + static long unoct(char *p, int ndgs) { - long value=0; - /* Converts octal string to long, ignoring any non-digit */ + long value=0; + /* Converts octal string to long, ignoring any non-digit */ - while (--ndgs) - { - if (isdigit((int)*p)) - value = (value << 3) | (long) (*p - '0'); + while (--ndgs) { + if (isdigit((int)*p)) + value = (value << 3) | (long) (*p - '0'); - p++; - } + p++; + } - return value; + return value; } /**************************************************************************** @@ -481,90 +476,86 @@ Compare two strings in a slash insensitive way, allowing s1 to match s2 if s1 is an "initial" string (up to directory marker). Thus, if s2 is a file in any subdirectory of s1, declare a match. ***************************************************************************/ + static int strslashcmp(char *s1, char *s2) { - char *s1_0=s1; + char *s1_0=s1; - while(*s1 && *s2 && - (*s1 == *s2 - || tolower(*s1) == tolower(*s2) - || (*s1 == '\\' && *s2=='/') - || (*s1 == '/' && *s2=='\\'))) { - s1++; s2++; - } + while(*s1 && *s2 && (*s1 == *s2 || tolower(*s1) == tolower(*s2) || + (*s1 == '\\' && *s2=='/') || (*s1 == '/' && *s2=='\\'))) { + s1++; s2++; + } - /* if s1 has a trailing slash, it compared equal, so s1 is an "initial" - string of s2. - */ - if (!*s1 && s1 != s1_0 && (*(s1-1) == '/' || *(s1-1) == '\\')) return 0; + /* if s1 has a trailing slash, it compared equal, so s1 is an "initial" + string of s2. + */ + if (!*s1 && s1 != s1_0 && (*(s1-1) == '/' || *(s1-1) == '\\')) + return 0; - /* ignore trailing slash on s1 */ - if (!*s2 && (*s1 == '/' || *s1 == '\\') && !*(s1+1)) return 0; + /* ignore trailing slash on s1 */ + if (!*s2 && (*s1 == '/' || *s1 == '\\') && !*(s1+1)) + return 0; - /* check for s1 is an "initial" string of s2 */ - if ((*s2 == '/' || *s2 == '\\') && !*s1) return 0; + /* check for s1 is an "initial" string of s2 */ + if ((*s2 == '/' || *s2 == '\\') && !*s1) + return 0; - return *s1-*s2; + return *s1-*s2; } - /**************************************************************************** Ensure a remote path exists (make if necessary) ***************************************************************************/ + static BOOL ensurepath(char *fname) { - /* *must* be called with buffer ready malloc'ed */ - /* ensures path exists */ - - char *partpath, *ffname; - char *p=fname, *basehack; - - DEBUG(5, ( "Ensurepath called with: %s\n", fname)); + /* *must* be called with buffer ready malloc'ed */ + /* ensures path exists */ - partpath = string_create_s(strlen(fname)); - ffname = string_create_s(strlen(fname)); + char *partpath, *ffname; + char *p=fname, *basehack; - if ((partpath == NULL) || (ffname == NULL)){ + DEBUG(5, ( "Ensurepath called with: %s\n", fname)); - DEBUG(0, ("Out of memory in ensurepath: %s\n", fname)); - return(False); + partpath = string_create_s(strlen(fname)); + ffname = string_create_s(strlen(fname)); - } + if ((partpath == NULL) || (ffname == NULL)){ + DEBUG(0, ("Out of memory in ensurepath: %s\n", fname)); + return(False); + } - *partpath = 0; + *partpath = 0; - /* fname copied to ffname so can strtok */ + /* fname copied to ffname so can strtok */ - safe_strcpy(ffname, fname, strlen(fname)); + safe_strcpy(ffname, fname, strlen(fname)); - /* do a `basename' on ffname, so don't try and make file name directory */ - if ((basehack=strrchr_m(ffname, '\\')) == NULL) - return True; - else - *basehack='\0'; + /* do a `basename' on ffname, so don't try and make file name directory */ + if ((basehack=strrchr_m(ffname, '\\')) == NULL) + return True; + else + *basehack='\0'; - p=strtok(ffname, "\\"); + p=strtok(ffname, "\\"); - while (p) - { - safe_strcat(partpath, p, strlen(fname) + 1); + while (p) { + safe_strcat(partpath, p, strlen(fname) + 1); - if (!cli_chkpath(cli, partpath)) { - if (!cli_mkdir(cli, partpath)) - { - DEBUG(0, ("Error mkdirhiering\n")); - return False; - } - else - DEBUG(3, ("mkdirhiering %s\n", partpath)); - - } + if (!cli_chkpath(cli, partpath)) { + if (!cli_mkdir(cli, partpath)) { + DEBUG(0, ("Error mkdirhiering\n")); + return False; + } else { + DEBUG(3, ("mkdirhiering %s\n", partpath)); + } + } - safe_strcat(partpath, "\\", strlen(fname) + 1); - p = strtok(NULL,"/\\"); - } + safe_strcat(partpath, "\\", strlen(fname) + 1); + p = strtok(NULL,"/\\"); + } - return True; + return True; } static int padit(char *buf, int bufsize, int padsize) @@ -583,7 +574,6 @@ static int padit(char *buf, int bufsize, int padsize) return berr; } - static void do_setrattr(char *name, uint16 attr, int set) { uint16 oldattr; @@ -601,268 +591,258 @@ static void do_setrattr(char *name, uint16 attr, int set) } } - /**************************************************************************** append one remote file to the tar file ***************************************************************************/ + static void do_atar(char *rname,char *lname,file_info *finfo1) { - int fnum; - SMB_BIG_UINT nread=0; - char ftype; - file_info2 finfo; - BOOL close_done = False; - BOOL shallitime=True; - char data[65520]; - int read_size = 65520; - int datalen=0; - - struct timeval tp_start; - GetTimeOfDay(&tp_start); - - ftype = '0'; /* An ordinary file ... */ - - if (finfo1) { - finfo.size = finfo1 -> size; - finfo.mode = finfo1 -> mode; - finfo.uid = finfo1 -> uid; - finfo.gid = finfo1 -> gid; - finfo.mtime = finfo1 -> mtime; - finfo.atime = finfo1 -> atime; - finfo.ctime = finfo1 -> ctime; - finfo.name = finfo1 -> name; - } - else { - finfo.size = def_finfo.size; - finfo.mode = def_finfo.mode; - finfo.uid = def_finfo.uid; - finfo.gid = def_finfo.gid; - finfo.mtime = def_finfo.mtime; - finfo.atime = def_finfo.atime; - finfo.ctime = def_finfo.ctime; - finfo.name = def_finfo.name; - } - - if (dry_run) - { - DEBUG(3,("skipping file %s of size %12.0f bytes\n", - finfo.name, - (double)finfo.size)); - shallitime=0; - ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK); - ntarf++; - return; - } - - fnum = cli_open(cli, rname, O_RDONLY, DENY_NONE); - - dos_clean_name(rname); - - if (fnum == -1) { - DEBUG(0,("%s opening remote file %s (%s)\n", - cli_errstr(cli),rname, cur_dir)); - return; - } - - finfo.name = string_create_s(strlen(rname)); - if (finfo.name == NULL) { - DEBUG(0, ("Unable to allocate space for finfo.name in do_atar\n")); - return; - } - - safe_strcpy(finfo.name,rname, strlen(rname)); - if (!finfo1) { - if (!cli_getattrE(cli, fnum, &finfo.mode, &finfo.size, NULL, &finfo.atime, &finfo.mtime)) { - DEBUG(0, ("getattrE: %s\n", cli_errstr(cli))); - return; - } - finfo.ctime = finfo.mtime; - } - - DEBUG(3,("file %s attrib 0x%X\n",finfo.name,finfo.mode)); - - if (tar_inc && !(finfo.mode & aARCH)) - { - DEBUG(4, ("skipping %s - archive bit not set\n", finfo.name)); - shallitime=0; - } - else if (!tar_system && (finfo.mode & aSYSTEM)) - { - DEBUG(4, ("skipping %s - system bit is set\n", finfo.name)); - shallitime=0; - } - else if (!tar_hidden && (finfo.mode & aHIDDEN)) - { - DEBUG(4, ("skipping %s - hidden bit is set\n", finfo.name)); - shallitime=0; - } - else - { - DEBUG(3,("getting file %s of size %.0f bytes as a tar file %s", - finfo.name, - (double)finfo.size, - lname)); + int fnum; + SMB_BIG_UINT nread=0; + char ftype; + file_info2 finfo; + BOOL close_done = False; + BOOL shallitime=True; + char data[65520]; + int read_size = 65520; + int datalen=0; + + struct timeval tp_start; + + GetTimeOfDay(&tp_start); + + ftype = '0'; /* An ordinary file ... */ + + if (finfo1) { + finfo.size = finfo1 -> size; + finfo.mode = finfo1 -> mode; + finfo.uid = finfo1 -> uid; + finfo.gid = finfo1 -> gid; + finfo.mtime = finfo1 -> mtime; + finfo.atime = finfo1 -> atime; + finfo.ctime = finfo1 -> ctime; + finfo.name = finfo1 -> name; + } else { + finfo.size = def_finfo.size; + finfo.mode = def_finfo.mode; + finfo.uid = def_finfo.uid; + finfo.gid = def_finfo.gid; + finfo.mtime = def_finfo.mtime; + finfo.atime = def_finfo.atime; + finfo.ctime = def_finfo.ctime; + finfo.name = def_finfo.name; + } + + if (dry_run) { + DEBUG(3,("skipping file %s of size %12.0f bytes\n", finfo.name, + (double)finfo.size)); + shallitime=0; + ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK); + ntarf++; + return; + } + + fnum = cli_open(cli, rname, O_RDONLY, DENY_NONE); + + dos_clean_name(rname); + + if (fnum == -1) { + DEBUG(0,("%s opening remote file %s (%s)\n", + cli_errstr(cli),rname, cur_dir)); + return; + } + + finfo.name = string_create_s(strlen(rname)); + if (finfo.name == NULL) { + DEBUG(0, ("Unable to allocate space for finfo.name in do_atar\n")); + return; + } + + safe_strcpy(finfo.name,rname, strlen(rname)); + if (!finfo1) { + if (!cli_getattrE(cli, fnum, &finfo.mode, &finfo.size, NULL, &finfo.atime, &finfo.mtime)) { + DEBUG(0, ("getattrE: %s\n", cli_errstr(cli))); + return; + } + finfo.ctime = finfo.mtime; + } + + DEBUG(3,("file %s attrib 0x%X\n",finfo.name,finfo.mode)); + + if (tar_inc && !(finfo.mode & aARCH)) { + DEBUG(4, ("skipping %s - archive bit not set\n", finfo.name)); + shallitime=0; + } else if (!tar_system && (finfo.mode & aSYSTEM)) { + DEBUG(4, ("skipping %s - system bit is set\n", finfo.name)); + shallitime=0; + } else if (!tar_hidden && (finfo.mode & aHIDDEN)) { + DEBUG(4, ("skipping %s - hidden bit is set\n", finfo.name)); + shallitime=0; + } else { + DEBUG(3,("getting file %s of size %.0f bytes as a tar file %s", + finfo.name, (double)finfo.size, lname)); - /* write a tar header, don't bother with mode - just set to 100644 */ - writetarheader(tarhandle, rname, finfo.size, finfo.mtime, "100644 \0", ftype); + /* write a tar header, don't bother with mode - just set to 100644 */ + writetarheader(tarhandle, rname, finfo.size, finfo.mtime, "100644 \0", ftype); - while (nread < finfo.size && !close_done) { + while (nread < finfo.size && !close_done) { - DEBUG(3,("nread=%.0f\n",(double)nread)); + DEBUG(3,("nread=%.0f\n",(double)nread)); - datalen = cli_read(cli, fnum, data, nread, read_size); + datalen = cli_read(cli, fnum, data, nread, read_size); - if (datalen == -1) { - DEBUG(0,("Error reading file %s : %s\n", rname, cli_errstr(cli))); - break; - } + if (datalen == -1) { + DEBUG(0,("Error reading file %s : %s\n", rname, cli_errstr(cli))); + break; + } - nread += datalen; - - /* if file size has increased since we made file size query, truncate - read so tar header for this file will be correct. - */ - - if (nread > finfo.size) { - datalen -= nread - finfo.size; - DEBUG(0,("File size change - truncating %s to %.0f bytes\n", finfo.name, (double)finfo.size)); - } - - /* add received bits of file to buffer - dotarbuf will - * write out in 512 byte intervals */ - if (dotarbuf(tarhandle,data,datalen) != datalen) { - DEBUG(0,("Error writing to tar file - %s\n", strerror(errno))); - break; - } + nread += datalen; + + /* if file size has increased since we made file size query, truncate + read so tar header for this file will be correct. + */ + + if (nread > finfo.size) { + datalen -= nread - finfo.size; + DEBUG(0,("File size change - truncating %s to %.0f bytes\n", + finfo.name, (double)finfo.size)); + } + + /* add received bits of file to buffer - dotarbuf will + * write out in 512 byte intervals */ + + if (dotarbuf(tarhandle,data,datalen) != datalen) { + DEBUG(0,("Error writing to tar file - %s\n", strerror(errno))); + break; + } - if (datalen == 0) { - DEBUG(0,("Error reading file %s. Got 0 bytes\n", rname)); - break; - } - - datalen=0; - } - - /* pad tar file with zero's if we couldn't get entire file */ - if (nread < finfo.size) { - DEBUG(0, ("Didn't get entire file. size=%.0f, nread=%d\n", (double)finfo.size, (int)nread)); - if (padit(data, sizeof(data), finfo.size - nread)) - DEBUG(0,("Error writing tar file - %s\n", strerror(errno))); - } - - /* round tar file to nearest block */ - if (finfo.size % TBLOCK) - dozerobuf(tarhandle, TBLOCK - (finfo.size % TBLOCK)); + if (datalen == 0) { + DEBUG(0,("Error reading file %s. Got 0 bytes\n", rname)); + break; + } + + datalen=0; + } + + /* pad tar file with zero's if we couldn't get entire file */ + if (nread < finfo.size) { + DEBUG(0, ("Didn't get entire file. size=%.0f, nread=%d\n", + (double)finfo.size, (int)nread)); + if (padit(data, sizeof(data), finfo.size - nread)) + DEBUG(0,("Error writing tar file - %s\n", strerror(errno))); + } + + /* round tar file to nearest block */ + if (finfo.size % TBLOCK) + dozerobuf(tarhandle, TBLOCK - (finfo.size % TBLOCK)); - ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK); - ntarf++; - } + ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK); + ntarf++; + } - cli_close(cli, fnum); + cli_close(cli, fnum); - if (shallitime) - { - struct timeval tp_end; - int this_time; + if (shallitime) { + struct timeval tp_end; + int this_time; - /* if shallitime is true then we didn't skip */ - if (tar_reset && !dry_run) - (void) do_setrattr(finfo.name, aARCH, ATTRRESET); + /* if shallitime is true then we didn't skip */ + if (tar_reset && !dry_run) + (void) do_setrattr(finfo.name, aARCH, ATTRRESET); - GetTimeOfDay(&tp_end); - this_time = - (tp_end.tv_sec - tp_start.tv_sec)*1000 + - (tp_end.tv_usec - tp_start.tv_usec)/1000; - get_total_time_ms += this_time; - get_total_size += finfo.size; - - if (tar_noisy) - { - DEBUG(0, ("%12.0f (%7.1f kb/s) %s\n", - (double)finfo.size, finfo.size / MAX(0.001, (1.024*this_time)), - finfo.name)); - } + GetTimeOfDay(&tp_end); + this_time = (tp_end.tv_sec - tp_start.tv_sec)*1000 + (tp_end.tv_usec - tp_start.tv_usec)/1000; + get_total_time_ms += this_time; + get_total_size += finfo.size; + + if (tar_noisy) { + DEBUG(0, ("%12.0f (%7.1f kb/s) %s\n", + (double)finfo.size, finfo.size / MAX(0.001, (1.024*this_time)), + finfo.name)); + } - /* Thanks to Carel-Jan Engel (ease@mail.wirehub.nl) for this one */ - DEBUG(3,("(%g kb/s) (average %g kb/s)\n", - finfo.size / MAX(0.001, (1.024*this_time)), - get_total_size / MAX(0.001, (1.024*get_total_time_ms)))); - } + /* Thanks to Carel-Jan Engel (ease@mail.wirehub.nl) for this one */ + DEBUG(3,("(%g kb/s) (average %g kb/s)\n", + finfo.size / MAX(0.001, (1.024*this_time)), + get_total_size / MAX(0.001, (1.024*get_total_time_ms)))); + } } /**************************************************************************** Append single file to tar file (or not) ***************************************************************************/ + static void do_tar(file_info *finfo) { - pstring rname; + pstring rname; - if (strequal(finfo->name,"..") || strequal(finfo->name,".")) - return; + if (strequal(finfo->name,"..") || strequal(finfo->name,".")) + return; - /* Is it on the exclude list ? */ - if (!tar_excl && clipn) { - pstring exclaim; + /* Is it on the exclude list ? */ + if (!tar_excl && clipn) { + pstring exclaim; - DEBUG(5, ("Excl: strlen(cur_dir) = %d\n", (int)strlen(cur_dir))); + DEBUG(5, ("Excl: strlen(cur_dir) = %d\n", (int)strlen(cur_dir))); - pstrcpy(exclaim, cur_dir); - *(exclaim+strlen(exclaim)-1)='\0'; + pstrcpy(exclaim, cur_dir); + *(exclaim+strlen(exclaim)-1)='\0'; - pstrcat(exclaim, "\\"); - pstrcat(exclaim, finfo->name); + pstrcat(exclaim, "\\"); + pstrcat(exclaim, finfo->name); - DEBUG(5, ("...tar_re_search: %d\n", tar_re_search)); + DEBUG(5, ("...tar_re_search: %d\n", tar_re_search)); - if ((!tar_re_search && clipfind(cliplist, clipn, exclaim)) || + if ((!tar_re_search && clipfind(cliplist, clipn, exclaim)) || #ifdef HAVE_REGEX_H - (tar_re_search && !regexec(preg, exclaim, 0, NULL, 0))) { + (tar_re_search && !regexec(preg, exclaim, 0, NULL, 0))) { #else - (tar_re_search && mask_match(exclaim, cliplist[0], True))) { + (tar_re_search && mask_match(exclaim, cliplist[0], True))) { #endif - DEBUG(3,("Skipping file %s\n", exclaim)); - return; - } - } - - if (finfo->mode & aDIR) - { - pstring saved_curdir; - pstring mtar_mask; - - pstrcpy(saved_curdir, cur_dir); - - DEBUG(5, ("Sizeof(cur_dir)=%d, strlen(cur_dir)=%d, strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n", (int)sizeof(cur_dir), (int)strlen(cur_dir), (int)strlen(finfo->name), finfo->name, cur_dir)); - - pstrcat(cur_dir,finfo->name); - pstrcat(cur_dir,"\\"); - - DEBUG(5, ("Writing a dir, Name = %s\n", cur_dir)); - - /* write a tar directory, don't bother with mode - just set it to - * 40755 */ - writetarheader(tarhandle, cur_dir, 0, finfo->mtime, "040755 \0", '5'); - if (tar_noisy) { - DEBUG(0,(" directory %s\n", cur_dir)); - } - ntarf++; /* Make sure we have a file on there */ - pstrcpy(mtar_mask,cur_dir); - pstrcat(mtar_mask,"*"); - DEBUG(5, ("Doing list with mtar_mask: %s\n", mtar_mask)); - do_list(mtar_mask, attribute, do_tar, False, True); - pstrcpy(cur_dir,saved_curdir); - } - else - { - pstrcpy(rname,cur_dir); - pstrcat(rname,finfo->name); - do_atar(rname,finfo->name,finfo); - } + DEBUG(3,("Skipping file %s\n", exclaim)); + return; + } + } + + if (finfo->mode & aDIR) { + pstring saved_curdir; + pstring mtar_mask; + + pstrcpy(saved_curdir, cur_dir); + + DEBUG(5, ("Sizeof(cur_dir)=%d, strlen(cur_dir)=%d, \ +strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n", + (int)sizeof(cur_dir), (int)strlen(cur_dir), + (int)strlen(finfo->name), finfo->name, cur_dir)); + + pstrcat(cur_dir,finfo->name); + pstrcat(cur_dir,"\\"); + + DEBUG(5, ("Writing a dir, Name = %s\n", cur_dir)); + + /* write a tar directory, don't bother with mode - just set it to + * 40755 */ + writetarheader(tarhandle, cur_dir, 0, finfo->mtime, "040755 \0", '5'); + if (tar_noisy) { + DEBUG(0,(" directory %s\n", cur_dir)); + } + ntarf++; /* Make sure we have a file on there */ + pstrcpy(mtar_mask,cur_dir); + pstrcat(mtar_mask,"*"); + DEBUG(5, ("Doing list with mtar_mask: %s\n", mtar_mask)); + do_list(mtar_mask, attribute, do_tar, False, True); + pstrcpy(cur_dir,saved_curdir); + } else { + pstrcpy(rname,cur_dir); + pstrcat(rname,finfo->name); + do_atar(rname,finfo->name,finfo); + } } /**************************************************************************** Convert from UNIX to DOS file names ***************************************************************************/ + static void unfixtarname(char *tptr, char *fp, int l, BOOL first) { /* remove '.' from start of file name, convert from unix /'s to @@ -886,79 +866,72 @@ static void unfixtarname(char *tptr, char *fp, int l, BOOL first) string_replace(tptr, '/', '\\'); } - /**************************************************************************** Move to the next block in the buffer, which may mean read in another set of blocks. FIXME, we should allow more than one block to be skipped. ****************************************************************************/ + static int next_block(char *ltarbuf, char **bufferp, int bufsiz) { - int bufread, total = 0; - - DEBUG(5, ("Advancing to next block: %0lx\n", (unsigned long)*bufferp)); - *bufferp += TBLOCK; - total = TBLOCK; - - if (*bufferp >= (ltarbuf + bufsiz)) { - - DEBUG(5, ("Reading more data into ltarbuf ...\n")); - - /* - * Bugfix from Bob Boehmer <boehmer@worldnet.att.net> - * Fixes bug where read can return short if coming from - * a pipe. - */ - - bufread = read(tarhandle, ltarbuf, bufsiz); - total = bufread; - - while (total < bufsiz) { - if (bufread < 0) { /* An error, return false */ - return (total > 0 ? -2 : bufread); - } - if (bufread == 0) { - if (total <= 0) { - return -2; - } - break; - } - bufread = read(tarhandle, <arbuf[total], bufsiz - total); - total += bufread; - } - - DEBUG(5, ("Total bytes read ... %i\n", total)); - - *bufferp = ltarbuf; + int bufread, total = 0; + + DEBUG(5, ("Advancing to next block: %0lx\n", (unsigned long)*bufferp)); + *bufferp += TBLOCK; + total = TBLOCK; + + if (*bufferp >= (ltarbuf + bufsiz)) { + + DEBUG(5, ("Reading more data into ltarbuf ...\n")); + + /* + * Bugfix from Bob Boehmer <boehmer@worldnet.att.net> + * Fixes bug where read can return short if coming from + * a pipe. + */ + + bufread = read(tarhandle, ltarbuf, bufsiz); + total = bufread; + + while (total < bufsiz) { + if (bufread < 0) { /* An error, return false */ + return (total > 0 ? -2 : bufread); + } + if (bufread == 0) { + if (total <= 0) { + return -2; + } + break; + } + bufread = read(tarhandle, <arbuf[total], bufsiz - total); + total += bufread; + } - } + DEBUG(5, ("Total bytes read ... %i\n", total)); - return(total); + *bufferp = ltarbuf; + } + return(total); } /* Skip a file, even if it includes a long file name? */ static int skip_file(int skipsize) { - int dsize = skipsize; - - DEBUG(5, ("Skiping file. Size = %i\n", skipsize)); - - /* FIXME, we should skip more than one block at a time */ - - while (dsize > 0) { + int dsize = skipsize; - if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) { + DEBUG(5, ("Skiping file. Size = %i\n", skipsize)); - DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); - return(False); + /* FIXME, we should skip more than one block at a time */ - } - - dsize -= TBLOCK; - - } + while (dsize > 0) { + if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) { + DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); + return(False); + } + dsize -= TBLOCK; + } - return(True); + return(True); } /************************************************************* @@ -969,103 +942,94 @@ static int skip_file(int skipsize) static int get_file(file_info2 finfo) { - int fnum = -1, pos = 0, dsize = 0, bpos = 0; - SMB_BIG_UINT rsize = 0; - - DEBUG(5, ("get_file: file: %s, size %.0f\n", finfo.name, (double)finfo.size)); - - if (ensurepath(finfo.name) && - (fnum=cli_open(cli, finfo.name, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) == -1) { - DEBUG(0, ("abandoning restore\n")); - return(False); - } - - /* read the blocks from the tar file and write to the remote file */ - - rsize = finfo.size; /* This is how much to write */ - - while (rsize > 0) { + int fnum = -1, pos = 0, dsize = 0, bpos = 0; + SMB_BIG_UINT rsize = 0; - /* We can only write up to the end of the buffer */ + DEBUG(5, ("get_file: file: %s, size %.0f\n", finfo.name, (double)finfo.size)); - dsize = MIN(tbufsiz - (buffer_p - tarbuf) - bpos, 65520); /* Calculate the size to write */ - dsize = MIN(dsize, rsize); /* Should be only what is left */ - DEBUG(5, ("writing %i bytes, bpos = %i ...\n", dsize, bpos)); - - if (cli_write(cli, fnum, 0, buffer_p + bpos, pos, dsize) != dsize) { - DEBUG(0, ("Error writing remote file\n")); - return 0; - } - - rsize -= dsize; - pos += dsize; - - /* Now figure out how much to move in the buffer */ + if (ensurepath(finfo.name) && + (fnum=cli_open(cli, finfo.name, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) == -1) { + DEBUG(0, ("abandoning restore\n")); + return(False); + } - /* FIXME, we should skip more than one block at a time */ + /* read the blocks from the tar file and write to the remote file */ - /* First, skip any initial part of the part written that is left over */ - /* from the end of the first TBLOCK */ + rsize = finfo.size; /* This is how much to write */ - if ((bpos) && ((bpos + dsize) >= TBLOCK)) { + while (rsize > 0) { - dsize -= (TBLOCK - bpos); /* Get rid of the end of the first block */ - bpos = 0; + /* We can only write up to the end of the buffer */ + dsize = MIN(tbufsiz - (buffer_p - tarbuf) - bpos, 65520); /* Calculate the size to write */ + dsize = MIN(dsize, rsize); /* Should be only what is left */ + DEBUG(5, ("writing %i bytes, bpos = %i ...\n", dsize, bpos)); - if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) { /* and skip the block */ - DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); - return False; + if (cli_write(cli, fnum, 0, buffer_p + bpos, pos, dsize) != dsize) { + DEBUG(0, ("Error writing remote file\n")); + return 0; + } - } + rsize -= dsize; + pos += dsize; - } + /* Now figure out how much to move in the buffer */ - /* - * Bugfix from Bob Boehmer <boehmer@worldnet.att.net>. - * If the file being extracted is an exact multiple of - * TBLOCK bytes then we don't want to extract the next - * block from the tarfile here, as it will be done in - * the caller of get_file(). - */ + /* FIXME, we should skip more than one block at a time */ - while (((rsize != 0) && (dsize >= TBLOCK)) || - ((rsize == 0) && (dsize > TBLOCK))) { + /* First, skip any initial part of the part written that is left over */ + /* from the end of the first TBLOCK */ - if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) { - DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); - return False; - } + if ((bpos) && ((bpos + dsize) >= TBLOCK)) { + dsize -= (TBLOCK - bpos); /* Get rid of the end of the first block */ + bpos = 0; - dsize -= TBLOCK; - } + if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) { /* and skip the block */ + DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); + return False; + } + } - bpos = dsize; + /* + * Bugfix from Bob Boehmer <boehmer@worldnet.att.net>. + * If the file being extracted is an exact multiple of + * TBLOCK bytes then we don't want to extract the next + * block from the tarfile here, as it will be done in + * the caller of get_file(). + */ - } + while (((rsize != 0) && (dsize >= TBLOCK)) || + ((rsize == 0) && (dsize > TBLOCK))) { - /* Now close the file ... */ + if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) { + DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); + return False; + } - if (!cli_close(cli, fnum)) { - DEBUG(0, ("Error closing remote file\n")); - return(False); - } + dsize -= TBLOCK; + } + bpos = dsize; + } - /* Now we update the creation date ... */ + /* Now close the file ... */ - DEBUG(5, ("Updating creation date on %s\n", finfo.name)); + if (!cli_close(cli, fnum)) { + DEBUG(0, ("Error closing remote file\n")); + return(False); + } - if (!cli_setatr(cli, finfo.name, finfo.mode, finfo.mtime)) { - if (tar_real_noisy) { - DEBUG(0, ("Could not set time on file: %s\n", finfo.name)); - /*return(False); */ /* Ignore, as Win95 does not allow changes */ - } - } + /* Now we update the creation date ... */ + DEBUG(5, ("Updating creation date on %s\n", finfo.name)); - ntarf++; + if (!cli_setatr(cli, finfo.name, finfo.mode, finfo.mtime)) { + if (tar_real_noisy) { + DEBUG(0, ("Could not set time on file: %s\n", finfo.name)); + /*return(False); */ /* Ignore, as Win95 does not allow changes */ + } + } - DEBUG(0, ("restore tar file %s of size %.0f bytes\n", finfo.name, (double)finfo.size)); - - return(True); + ntarf++; + DEBUG(0, ("restore tar file %s of size %.0f bytes\n", finfo.name, (double)finfo.size)); + return(True); } /* Create a directory. We just ensure that the path exists and return as there @@ -1073,214 +1037,167 @@ static int get_file(file_info2 finfo) */ static int get_dir(file_info2 finfo) { + DEBUG(0, ("restore directory %s\n", finfo.name)); - DEBUG(0, ("restore directory %s\n", finfo.name)); - - if (!ensurepath(finfo.name)) { - - DEBUG(0, ("Problems creating directory\n")); - return(False); - - } - - ntarf++; - return(True); - + if (!ensurepath(finfo.name)) { + DEBUG(0, ("Problems creating directory\n")); + return(False); + } + ntarf++; + return(True); } + /* Get a file with a long file name ... first file has file name, next file has the data. We only want the long file name, as the loop in do_tarput will deal with the rest. */ static char * get_longfilename(file_info2 finfo) { - int namesize = strlen(finfo.name) + strlen(cur_dir) + 2; - char *longname = malloc(namesize); - int offset = 0, left = finfo.size; - BOOL first = True; - - DEBUG(5, ("Restoring a long file name: %s\n", finfo.name)); - DEBUG(5, ("Len = %.0f\n", (double)finfo.size)); - - if (longname == NULL) { - - DEBUG(0, ("could not allocate buffer of size %d for longname\n", - namesize)); - return(NULL); - } - - /* First, add cur_dir to the long file name */ + int namesize = strlen(finfo.name) + strlen(cur_dir) + 2; + char *longname = malloc(namesize); + int offset = 0, left = finfo.size; + BOOL first = True; - if (strlen(cur_dir) > 0) { - strncpy(longname, cur_dir, namesize); - offset = strlen(cur_dir); - } + DEBUG(5, ("Restoring a long file name: %s\n", finfo.name)); + DEBUG(5, ("Len = %.0f\n", (double)finfo.size)); - /* Loop through the blocks picking up the name */ - - while (left > 0) { - - if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) { + if (longname == NULL) { + DEBUG(0, ("could not allocate buffer of size %d for longname\n", namesize)); + return(NULL); + } - DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); - return(NULL); + /* First, add cur_dir to the long file name */ - } + if (strlen(cur_dir) > 0) { + strncpy(longname, cur_dir, namesize); + offset = strlen(cur_dir); + } - unfixtarname(longname + offset, buffer_p, MIN(TBLOCK, finfo.size), first--); - DEBUG(5, ("UnfixedName: %s, buffer: %s\n", longname, buffer_p)); + /* Loop through the blocks picking up the name */ - offset += TBLOCK; - left -= TBLOCK; + while (left > 0) { + if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) { + DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); + return(NULL); + } - } + unfixtarname(longname + offset, buffer_p, MIN(TBLOCK, finfo.size), first--); + DEBUG(5, ("UnfixedName: %s, buffer: %s\n", longname, buffer_p)); - return(longname); + offset += TBLOCK; + left -= TBLOCK; + } + return(longname); } static void do_tarput(void) { - file_info2 finfo; - struct timeval tp_start; - char *longfilename = NULL, linkflag; - int skip = False; - - GetTimeOfDay(&tp_start); - - DEBUG(5, ("RJS do_tarput called ...\n")); - - buffer_p = tarbuf + tbufsiz; /* init this to force first read */ - - /* Now read through those files ... */ - - while (True) { - - /* Get us to the next block, or the first block first time around */ - - if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) { - - DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); - - return; - - } - - DEBUG(5, ("Reading the next header ...\n")); - - switch (readtarheader((union hblock *) buffer_p, &finfo, cur_dir)) { - - case -2: /* Hmm, not good, but not fatal */ - DEBUG(0, ("Skipping %s...\n", finfo.name)); - if ((next_block(tarbuf, &buffer_p, tbufsiz) <= 0) && - !skip_file(finfo.size)) { - - DEBUG(0, ("Short file, bailing out...\n")); - return; - - } - - break; - - case -1: - DEBUG(0, ("abandoning restore, -1 from read tar header\n")); - return; - - case 0: /* chksum is zero - looks like an EOF */ - DEBUG(0, ("tar: restored %d files and directories\n", ntarf)); - return; /* Hmmm, bad here ... */ - - default: - /* No action */ - - break; - - } + file_info2 finfo; + struct timeval tp_start; + char *longfilename = NULL, linkflag; + int skip = False; + + GetTimeOfDay(&tp_start); + DEBUG(5, ("RJS do_tarput called ...\n")); + + buffer_p = tarbuf + tbufsiz; /* init this to force first read */ + + /* Now read through those files ... */ + while (True) { + /* Get us to the next block, or the first block first time around */ + if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) { + DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); + return; + } - /* Now, do we have a long file name? */ + DEBUG(5, ("Reading the next header ...\n")); - if (longfilename != NULL) { + switch (readtarheader((union hblock *) buffer_p, &finfo, cur_dir)) { + case -2: /* Hmm, not good, but not fatal */ + DEBUG(0, ("Skipping %s...\n", finfo.name)); + if ((next_block(tarbuf, &buffer_p, tbufsiz) <= 0) && !skip_file(finfo.size)) { + DEBUG(0, ("Short file, bailing out...\n")); + return; + } + break; - SAFE_FREE(finfo.name); /* Free the space already allocated */ - finfo.name = longfilename; - longfilename = NULL; + case -1: + DEBUG(0, ("abandoning restore, -1 from read tar header\n")); + return; - } + case 0: /* chksum is zero - looks like an EOF */ + DEBUG(0, ("tar: restored %d files and directories\n", ntarf)); + return; /* Hmmm, bad here ... */ - /* Well, now we have a header, process the file ... */ + default: + /* No action */ + break; + } - /* Should we skip the file? We have the long name as well here */ + /* Now, do we have a long file name? */ + if (longfilename != NULL) { + SAFE_FREE(finfo.name); /* Free the space already allocated */ + finfo.name = longfilename; + longfilename = NULL; + } - skip = clipn && - ((!tar_re_search && clipfind(cliplist, clipn, finfo.name) ^ tar_excl) + /* Well, now we have a header, process the file ... */ + /* Should we skip the file? We have the long name as well here */ + skip = clipn && ((!tar_re_search && clipfind(cliplist, clipn, finfo.name) ^ tar_excl) || #ifdef HAVE_REGEX_H - || (tar_re_search && !regexec(preg, finfo.name, 0, NULL, 0))); + (tar_re_search && !regexec(preg, finfo.name, 0, NULL, 0))); #else - || (tar_re_search && mask_match(finfo.name, cliplist[0], True))); + (tar_re_search && mask_match(finfo.name, cliplist[0], True))); #endif - DEBUG(5, ("Skip = %i, cliplist=%s, file=%s\n", skip, (cliplist?cliplist[0]:NULL), finfo.name)); - - if (skip) { - - skip_file(finfo.size); - continue; - - } - - /* We only get this far if we should process the file */ - linkflag = ((union hblock *)buffer_p) -> dbuf.linkflag; - - switch (linkflag) { - - case '0': /* Should use symbolic names--FIXME */ - - /* - * Skip to the next block first, so we can get the file, FIXME, should - * be in get_file ... - * The 'finfo.size != 0' fix is from Bob Boehmer <boehmer@worldnet.att.net> - * Fixes bug where file size in tarfile is zero. - */ - - if ((finfo.size != 0) && next_block(tarbuf, &buffer_p, tbufsiz) <=0) { - DEBUG(0, ("Short file, bailing out...\n")); - return; - } - if (!get_file(finfo)) { - DEBUG(0, ("Abandoning restore\n")); - return; - - } - break; - - case '5': - if (!get_dir(finfo)) { - DEBUG(0, ("Abandoning restore \n")); - return; - } - break; - - case 'L': - longfilename = get_longfilename(finfo); - if (!longfilename) { - DEBUG(0, ("abandoning restore\n")); - return; - - } - DEBUG(5, ("Long file name: %s\n", longfilename)); - break; - - default: - skip_file(finfo.size); /* Don't handle these yet */ - break; - - } - - } - + DEBUG(5, ("Skip = %i, cliplist=%s, file=%s\n", skip, (cliplist?cliplist[0]:NULL), finfo.name)); + if (skip) { + skip_file(finfo.size); + continue; + } + /* We only get this far if we should process the file */ + linkflag = ((union hblock *)buffer_p) -> dbuf.linkflag; + switch (linkflag) { + case '0': /* Should use symbolic names--FIXME */ + /* + * Skip to the next block first, so we can get the file, FIXME, should + * be in get_file ... + * The 'finfo.size != 0' fix is from Bob Boehmer <boehmer@worldnet.att.net> + * Fixes bug where file size in tarfile is zero. + */ + if ((finfo.size != 0) && next_block(tarbuf, &buffer_p, tbufsiz) <=0) { + DEBUG(0, ("Short file, bailing out...\n")); + return; + } + if (!get_file(finfo)) { + DEBUG(0, ("Abandoning restore\n")); + return; + } + break; + case '5': + if (!get_dir(finfo)) { + DEBUG(0, ("Abandoning restore \n")); + return; + } + break; + case 'L': + longfilename = get_longfilename(finfo); + if (!longfilename) { + DEBUG(0, ("abandoning restore\n")); + return; + } + DEBUG(5, ("Long file name: %s\n", longfilename)); + break; + + default: + skip_file(finfo.size); /* Don't handle these yet */ + break; + } + } } - /* * samba interactive commands */ @@ -1288,577 +1205,594 @@ static void do_tarput(void) /**************************************************************************** Blocksize command ***************************************************************************/ + int cmd_block(void) { - fstring buf; - int block; - - if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) - { - DEBUG(0, ("blocksize <n>\n")); - return 1; - } - - block=atoi(buf); - if (block < 0 || block > 65535) - { - DEBUG(0, ("blocksize out of range")); - return 1; - } - - blocksize=block; - DEBUG(2,("blocksize is now %d\n", blocksize)); - - return 0; + fstring buf; + int block; + + if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { + DEBUG(0, ("blocksize <n>\n")); + return 1; + } + + block=atoi(buf); + if (block < 0 || block > 65535) { + DEBUG(0, ("blocksize out of range")); + return 1; + } + + blocksize=block; + DEBUG(2,("blocksize is now %d\n", blocksize)); + + return 0; } /**************************************************************************** command to set incremental / reset mode ***************************************************************************/ + int cmd_tarmode(void) { - fstring buf; - - while (next_token_nr(NULL,buf,NULL,sizeof(buf))) { - if (strequal(buf, "full")) - tar_inc=False; - else if (strequal(buf, "inc")) - tar_inc=True; - else if (strequal(buf, "reset")) - tar_reset=True; - else if (strequal(buf, "noreset")) - tar_reset=False; - else if (strequal(buf, "system")) - tar_system=True; - else if (strequal(buf, "nosystem")) - tar_system=False; - else if (strequal(buf, "hidden")) - tar_hidden=True; - else if (strequal(buf, "nohidden")) - tar_hidden=False; - else if (strequal(buf, "verbose") || strequal(buf, "noquiet")) - tar_noisy=True; - else if (strequal(buf, "quiet") || strequal(buf, "noverbose")) - tar_noisy=False; - else DEBUG(0, ("tarmode: unrecognised option %s\n", buf)); - } - - DEBUG(0, ("tarmode is now %s, %s, %s, %s, %s\n", - tar_inc ? "incremental" : "full", - tar_system ? "system" : "nosystem", - tar_hidden ? "hidden" : "nohidden", - tar_reset ? "reset" : "noreset", - tar_noisy ? "verbose" : "quiet")); - - return 0; + fstring buf; + + while (next_token_nr(NULL,buf,NULL,sizeof(buf))) { + if (strequal(buf, "full")) + tar_inc=False; + else if (strequal(buf, "inc")) + tar_inc=True; + else if (strequal(buf, "reset")) + tar_reset=True; + else if (strequal(buf, "noreset")) + tar_reset=False; + else if (strequal(buf, "system")) + tar_system=True; + else if (strequal(buf, "nosystem")) + tar_system=False; + else if (strequal(buf, "hidden")) + tar_hidden=True; + else if (strequal(buf, "nohidden")) + tar_hidden=False; + else if (strequal(buf, "verbose") || strequal(buf, "noquiet")) + tar_noisy=True; + else if (strequal(buf, "quiet") || strequal(buf, "noverbose")) + tar_noisy=False; + else + DEBUG(0, ("tarmode: unrecognised option %s\n", buf)); + } + + DEBUG(0, ("tarmode is now %s, %s, %s, %s, %s\n", + tar_inc ? "incremental" : "full", + tar_system ? "system" : "nosystem", + tar_hidden ? "hidden" : "nohidden", + tar_reset ? "reset" : "noreset", + tar_noisy ? "verbose" : "quiet")); + return 0; } /**************************************************************************** Feeble attrib command ***************************************************************************/ + int cmd_setmode(void) { - char *q; - fstring buf; - pstring fname; - uint16 attra[2]; - int direct=1; - - attra[0] = attra[1] = 0; - - if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) - { - DEBUG(0, ("setmode <filename> <[+|-]rsha>\n")); - return 1; - } - - pstrcpy(fname, cur_dir); - pstrcat(fname, buf); - - while (next_token_nr(NULL,buf,NULL,sizeof(buf))) { - q=buf; - - while(*q) - switch (*q++) { - case '+': direct=1; - break; - case '-': direct=0; - break; - case 'r': attra[direct]|=aRONLY; - break; - case 'h': attra[direct]|=aHIDDEN; - break; - case 's': attra[direct]|=aSYSTEM; - break; - case 'a': attra[direct]|=aARCH; - break; - default: DEBUG(0, ("setmode <filename> <perm=[+|-]rsha>\n")); - return 1; - } - } + char *q; + fstring buf; + pstring fname; + uint16 attra[2]; + int direct=1; + + attra[0] = attra[1] = 0; - if (attra[ATTRSET]==0 && attra[ATTRRESET]==0) - { - DEBUG(0, ("setmode <filename> <[+|-]rsha>\n")); - return 1; - } + if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { + DEBUG(0, ("setmode <filename> <[+|-]rsha>\n")); + return 1; + } + + pstrcpy(fname, cur_dir); + pstrcat(fname, buf); + + while (next_token_nr(NULL,buf,NULL,sizeof(buf))) { + q=buf; + + while(*q) { + switch (*q++) { + case '+': + direct=1; + break; + case '-': + direct=0; + break; + case 'r': + attra[direct]|=aRONLY; + break; + case 'h': + attra[direct]|=aHIDDEN; + break; + case 's': + attra[direct]|=aSYSTEM; + break; + case 'a': + attra[direct]|=aARCH; + break; + default: + DEBUG(0, ("setmode <filename> <perm=[+|-]rsha>\n")); + return 1; + } + } + } - DEBUG(2, ("\nperm set %d %d\n", attra[ATTRSET], attra[ATTRRESET])); - do_setrattr(fname, attra[ATTRSET], ATTRSET); - do_setrattr(fname, attra[ATTRRESET], ATTRRESET); + if (attra[ATTRSET]==0 && attra[ATTRRESET]==0) { + DEBUG(0, ("setmode <filename> <[+|-]rsha>\n")); + return 1; + } - return 0; + DEBUG(2, ("\nperm set %d %d\n", attra[ATTRSET], attra[ATTRRESET])); + do_setrattr(fname, attra[ATTRSET], ATTRSET); + do_setrattr(fname, attra[ATTRRESET], ATTRRESET); + return 0; } /**************************************************************************** Principal command for creating / extracting ***************************************************************************/ + int cmd_tar(void) { - fstring buf; - char **argl; - int argcl; - - if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) - { - DEBUG(0,("tar <c|x>[IXbgan] <filename>\n")); - return 1; - } - - argl=toktocliplist(&argcl, NULL); - if (!tar_parseargs(argcl, argl, buf, 0)) - return 1; + fstring buf; + char **argl; + int argcl; - process_tar(); + if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { + DEBUG(0,("tar <c|x>[IXbgan] <filename>\n")); + return 1; + } - SAFE_FREE(argl); + argl=toktocliplist(&argcl, NULL); + if (!tar_parseargs(argcl, argl, buf, 0)) + return 1; - return 0; + process_tar(); + SAFE_FREE(argl); + return 0; } /**************************************************************************** Command line (option) version ***************************************************************************/ + int process_tar(void) { - initarbuf(); - switch(tar_type) { - case 'x': + initarbuf(); + switch(tar_type) { + case 'x': #if 0 - do_tarput2(); + do_tarput2(); #else - do_tarput(); + do_tarput(); #endif - SAFE_FREE(tarbuf); - close(tarhandle); - break; - case 'r': - case 'c': - if (clipn && tar_excl) { - int i; - pstring tarmac; - - for (i=0; i<clipn; i++) { - DEBUG(5,("arg %d = %s\n", i, cliplist[i])); - - if (*(cliplist[i]+strlen(cliplist[i])-1)=='\\') { - *(cliplist[i]+strlen(cliplist[i])-1)='\0'; - } + SAFE_FREE(tarbuf); + close(tarhandle); + break; + case 'r': + case 'c': + if (clipn && tar_excl) { + int i; + pstring tarmac; + + for (i=0; i<clipn; i++) { + DEBUG(5,("arg %d = %s\n", i, cliplist[i])); + + if (*(cliplist[i]+strlen(cliplist[i])-1)=='\\') { + *(cliplist[i]+strlen(cliplist[i])-1)='\0'; + } - if (strrchr_m(cliplist[i], '\\')) { - pstring saved_dir; + if (strrchr_m(cliplist[i], '\\')) { + pstring saved_dir; - pstrcpy(saved_dir, cur_dir); + pstrcpy(saved_dir, cur_dir); - if (*cliplist[i]=='\\') { - pstrcpy(tarmac, cliplist[i]); - } else { - pstrcpy(tarmac, cur_dir); - pstrcat(tarmac, cliplist[i]); - } - pstrcpy(cur_dir, tarmac); - *(strrchr_m(cur_dir, '\\')+1)='\0'; - - DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac)); - do_list(tarmac,attribute,do_tar, False, True); - pstrcpy(cur_dir,saved_dir); - } else { - pstrcpy(tarmac, cur_dir); - pstrcat(tarmac, cliplist[i]); - DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac)); - do_list(tarmac,attribute,do_tar, False, True); - } - } - } else { - pstring mask; - pstrcpy(mask,cur_dir); - DEBUG(5, ("process_tar, do_list with mask: %s\n", mask)); - pstrcat(mask,"\\*"); - do_list(mask,attribute,do_tar,False, True); - } + if (*cliplist[i]=='\\') { + pstrcpy(tarmac, cliplist[i]); + } else { + pstrcpy(tarmac, cur_dir); + pstrcat(tarmac, cliplist[i]); + } + pstrcpy(cur_dir, tarmac); + *(strrchr_m(cur_dir, '\\')+1)='\0'; + + DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac)); + do_list(tarmac,attribute,do_tar, False, True); + pstrcpy(cur_dir,saved_dir); + } else { + pstrcpy(tarmac, cur_dir); + pstrcat(tarmac, cliplist[i]); + DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac)); + do_list(tarmac,attribute,do_tar, False, True); + } + } + } else { + pstring mask; + pstrcpy(mask,cur_dir); + DEBUG(5, ("process_tar, do_list with mask: %s\n", mask)); + pstrcat(mask,"\\*"); + do_list(mask,attribute,do_tar,False, True); + } - if (ntarf) dotareof(tarhandle); - close(tarhandle); - SAFE_FREE(tarbuf); + if (ntarf) + dotareof(tarhandle); + close(tarhandle); + SAFE_FREE(tarbuf); - DEBUG(0, ("tar: dumped %d files and directories\n", ntarf)); - DEBUG(0, ("Total bytes written: %.0f\n", (double)ttarf)); - break; - } - - if (must_free_cliplist) { - int i; - for (i = 0; i < clipn; ++i) { - SAFE_FREE(cliplist[i]); - } - SAFE_FREE(cliplist); - cliplist = NULL; - clipn = 0; - must_free_cliplist = False; - } - - return(0); + DEBUG(0, ("tar: dumped %d files and directories\n", ntarf)); + DEBUG(0, ("Total bytes written: %.0f\n", (double)ttarf)); + break; + } + + if (must_free_cliplist) { + int i; + for (i = 0; i < clipn; ++i) { + SAFE_FREE(cliplist[i]); + } + SAFE_FREE(cliplist); + cliplist = NULL; + clipn = 0; + must_free_cliplist = False; + } + return(0); } /**************************************************************************** Find a token (filename) in a clip list ***************************************************************************/ + static int clipfind(char **aret, int ret, char *tok) { - if (aret==NULL) return 0; + if (aret==NULL) + return 0; - /* ignore leading slashes or dots in token */ - while(strchr_m("/\\.", *tok)) tok++; + /* ignore leading slashes or dots in token */ + while(strchr_m("/\\.", *tok)) + tok++; - while(ret--) { - char *pkey=*aret++; + while(ret--) { + char *pkey=*aret++; - /* ignore leading slashes or dots in list */ - while(strchr_m("/\\.", *pkey)) pkey++; + /* ignore leading slashes or dots in list */ + while(strchr_m("/\\.", *pkey)) + pkey++; - if (!strslashcmp(pkey, tok)) return 1; - } - - return 0; + if (!strslashcmp(pkey, tok)) + return 1; + } + return 0; } /**************************************************************************** Read list of files to include from the file and initialize cliplist accordingly. ***************************************************************************/ + static int read_inclusion_file(char *filename) { - XFILE *inclusion = NULL; - char buf[MAXPATHLEN + 1]; - char *inclusion_buffer = NULL; - int inclusion_buffer_size = 0; - int inclusion_buffer_sofar = 0; - char *p; - char *tmpstr; - int i; - int error = 0; - - clipn = 0; - buf[MAXPATHLEN] = '\0'; /* guarantee null-termination */ - if ((inclusion = x_fopen(filename, O_RDONLY, 0)) == NULL) { - /* XXX It would be better to include a reason for failure, but without - * autoconf, it's hard to use strerror, sys_errlist, etc. - */ - DEBUG(0,("Unable to open inclusion file %s\n", filename)); - return 0; - } - - while ((! error) && (x_fgets(buf, sizeof(buf)-1, inclusion))) { - if (inclusion_buffer == NULL) { - inclusion_buffer_size = 1024; - if ((inclusion_buffer = malloc(inclusion_buffer_size)) == NULL) { - DEBUG(0,("failure allocating buffer to read inclusion file\n")); - error = 1; - break; - } - } + XFILE *inclusion = NULL; + char buf[MAXPATHLEN + 1]; + char *inclusion_buffer = NULL; + int inclusion_buffer_size = 0; + int inclusion_buffer_sofar = 0; + char *p; + char *tmpstr; + int i; + int error = 0; + + clipn = 0; + buf[MAXPATHLEN] = '\0'; /* guarantee null-termination */ + if ((inclusion = x_fopen(filename, O_RDONLY, 0)) == NULL) { + /* XXX It would be better to include a reason for failure, but without + * autoconf, it's hard to use strerror, sys_errlist, etc. + */ + DEBUG(0,("Unable to open inclusion file %s\n", filename)); + return 0; + } + + while ((! error) && (x_fgets(buf, sizeof(buf)-1, inclusion))) { + if (inclusion_buffer == NULL) { + inclusion_buffer_size = 1024; + if ((inclusion_buffer = malloc(inclusion_buffer_size)) == NULL) { + DEBUG(0,("failure allocating buffer to read inclusion file\n")); + error = 1; + break; + } + } - if (buf[strlen(buf)-1] == '\n') { - buf[strlen(buf)-1] = '\0'; - } + if (buf[strlen(buf)-1] == '\n') { + buf[strlen(buf)-1] = '\0'; + } - if ((strlen(buf) + 1 + inclusion_buffer_sofar) >= inclusion_buffer_size) { - char *ib; - inclusion_buffer_size *= 2; - ib = Realloc(inclusion_buffer,inclusion_buffer_size); - if (! ib) { - DEBUG(0,("failure enlarging inclusion buffer to %d bytes\n", - inclusion_buffer_size)); - error = 1; - break; - } - else inclusion_buffer = ib; - } + if ((strlen(buf) + 1 + inclusion_buffer_sofar) >= inclusion_buffer_size) { + char *ib; + inclusion_buffer_size *= 2; + ib = Realloc(inclusion_buffer,inclusion_buffer_size); + if (! ib) { + DEBUG(0,("failure enlarging inclusion buffer to %d bytes\n", + inclusion_buffer_size)); + error = 1; + break; + } else { + inclusion_buffer = ib; + } + } - safe_strcpy(inclusion_buffer + inclusion_buffer_sofar, buf, inclusion_buffer_size - inclusion_buffer_sofar); - inclusion_buffer_sofar += strlen(buf) + 1; - clipn++; - } - x_fclose(inclusion); - - if (! error) { - /* Allocate an array of clipn + 1 char*'s for cliplist */ - cliplist = malloc((clipn + 1) * sizeof(char *)); - if (cliplist == NULL) { - DEBUG(0,("failure allocating memory for cliplist\n")); - error = 1; - } else { - cliplist[clipn] = NULL; - p = inclusion_buffer; - for (i = 0; (! error) && (i < clipn); i++) { - /* set current item to NULL so array will be null-terminated even if - * malloc fails below. */ - cliplist[i] = NULL; - if ((tmpstr = (char *)malloc(strlen(p)+1)) == NULL) { - DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", i)); - error = 1; - } else { - unfixtarname(tmpstr, p, strlen(p) + 1, True); - cliplist[i] = tmpstr; - if ((p = strchr_m(p, '\000')) == NULL) { - DEBUG(0,("INTERNAL ERROR: inclusion_buffer is of unexpected contents.\n")); - abort(); - } + safe_strcpy(inclusion_buffer + inclusion_buffer_sofar, buf, inclusion_buffer_size - inclusion_buffer_sofar); + inclusion_buffer_sofar += strlen(buf) + 1; + clipn++; + } + x_fclose(inclusion); + + if (! error) { + /* Allocate an array of clipn + 1 char*'s for cliplist */ + cliplist = malloc((clipn + 1) * sizeof(char *)); + if (cliplist == NULL) { + DEBUG(0,("failure allocating memory for cliplist\n")); + error = 1; + } else { + cliplist[clipn] = NULL; + p = inclusion_buffer; + for (i = 0; (! error) && (i < clipn); i++) { + /* set current item to NULL so array will be null-terminated even if + * malloc fails below. */ + cliplist[i] = NULL; + if ((tmpstr = (char *)malloc(strlen(p)+1)) == NULL) { + DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", i)); + error = 1; + } else { + unfixtarname(tmpstr, p, strlen(p) + 1, True); + cliplist[i] = tmpstr; + if ((p = strchr_m(p, '\000')) == NULL) { + DEBUG(0,("INTERNAL ERROR: inclusion_buffer is of unexpected contents.\n")); + abort(); + } + } + ++p; + } + must_free_cliplist = True; + } + } + + SAFE_FREE(inclusion_buffer); + if (error) { + if (cliplist) { + char **pp; + /* We know cliplist is always null-terminated */ + for (pp = cliplist; *pp; ++pp) { + SAFE_FREE(*pp); + } + SAFE_FREE(cliplist); + cliplist = NULL; + must_free_cliplist = False; + } + return 0; } - ++p; - } - must_free_cliplist = True; - } - } - - SAFE_FREE(inclusion_buffer); - if (error) { - if (cliplist) { - char **pp; - /* We know cliplist is always null-terminated */ - for (pp = cliplist; *pp; ++pp) { - SAFE_FREE(*pp); - } - SAFE_FREE(cliplist); - cliplist = NULL; - must_free_cliplist = False; - } - return 0; - } - /* cliplist and its elements are freed at the end of process_tar. */ - return 1; + /* cliplist and its elements are freed at the end of process_tar. */ + return 1; } /**************************************************************************** Parse tar arguments. Sets tar_type, tar_excl, etc. ***************************************************************************/ + int tar_parseargs(int argc, char *argv[], char *Optarg, int Optind) { - char tar_clipfl='\0'; - - /* Reset back to defaults - could be from interactive version - * reset mode and archive mode left as they are though - */ - tar_type='\0'; - tar_excl=True; - dry_run=False; - - while (*Optarg) - switch(*Optarg++) { - case 'c': - tar_type='c'; - break; - case 'x': - if (tar_type=='c') { - printf("Tar must be followed by only one of c or x.\n"); - return 0; - } - tar_type='x'; - break; - case 'b': - if (Optind>=argc || !(blocksize=atoi(argv[Optind]))) { - DEBUG(0,("Option b must be followed by valid blocksize\n")); - return 0; - } else { - Optind++; - } - break; - case 'g': - tar_inc=True; - break; - case 'N': - if (Optind>=argc) { - DEBUG(0,("Option N must be followed by valid file name\n")); - return 0; - } else { - SMB_STRUCT_STAT stbuf; - extern time_t newer_than; + int newOptind = Optind; + char tar_clipfl='\0'; + + /* Reset back to defaults - could be from interactive version + * reset mode and archive mode left as they are though + */ + tar_type='\0'; + tar_excl=True; + dry_run=False; + + while (*Optarg) { + switch(*Optarg++) { + case 'c': + tar_type='c'; + break; + case 'x': + if (tar_type=='c') { + printf("Tar must be followed by only one of c or x.\n"); + return 0; + } + tar_type='x'; + break; + case 'b': + if (Optind>=argc || !(blocksize=atoi(argv[Optind]))) { + DEBUG(0,("Option b must be followed by valid blocksize\n")); + return 0; + } else { + Optind++; + newOptind++; + } + break; + case 'g': + tar_inc=True; + break; + case 'N': + if (Optind>=argc) { + DEBUG(0,("Option N must be followed by valid file name\n")); + return 0; + } else { + SMB_STRUCT_STAT stbuf; + extern time_t newer_than; - if (sys_stat(argv[Optind], &stbuf) == 0) { - newer_than = stbuf.st_mtime; - DEBUG(1,("Getting files newer than %s", - asctime(LocalTime(&newer_than)))); - Optind++; - } else { - DEBUG(0,("Error setting newer-than time\n")); - return 0; + if (sys_stat(argv[Optind], &stbuf) == 0) { + newer_than = stbuf.st_mtime; + DEBUG(1,("Getting files newer than %s", + asctime(LocalTime(&newer_than)))); + newOptind++; + Optind++; + } else { + DEBUG(0,("Error setting newer-than time\n")); + return 0; + } + } + break; + case 'a': + tar_reset=True; + break; + case 'q': + tar_noisy=False; + break; + case 'I': + if (tar_clipfl) { + DEBUG(0,("Only one of I,X,F must be specified\n")); + return 0; + } + tar_clipfl='I'; + break; + case 'X': + if (tar_clipfl) { + DEBUG(0,("Only one of I,X,F must be specified\n")); + return 0; + } + tar_clipfl='X'; + break; + case 'F': + if (tar_clipfl) { + DEBUG(0,("Only one of I,X,F must be specified\n")); + return 0; + } + tar_clipfl='F'; + break; + case 'r': + DEBUG(0, ("tar_re_search set\n")); + tar_re_search = True; + break; + case 'n': + if (tar_type == 'c') { + DEBUG(0, ("dry_run set\n")); + dry_run = True; + } else { + DEBUG(0, ("n is only meaningful when creating a tar-file\n")); + return 0; + } + break; + default: + DEBUG(0,("Unknown tar option\n")); + return 0; + } } - } - break; - case 'a': - tar_reset=True; - break; - case 'q': - tar_noisy=False; - break; - case 'I': - if (tar_clipfl) { - DEBUG(0,("Only one of I,X,F must be specified\n")); - return 0; - } - tar_clipfl='I'; - break; - case 'X': - if (tar_clipfl) { - DEBUG(0,("Only one of I,X,F must be specified\n")); - return 0; - } - tar_clipfl='X'; - break; - case 'F': - if (tar_clipfl) { - DEBUG(0,("Only one of I,X,F must be specified\n")); - return 0; - } - tar_clipfl='F'; - break; - case 'r': - DEBUG(0, ("tar_re_search set\n")); - tar_re_search = True; - break; - case 'n': - if (tar_type == 'c') { - DEBUG(0, ("dry_run set\n")); - dry_run = True; - } else { - DEBUG(0, ("n is only meaningful when creating a tar-file\n")); - return 0; - } - break; - default: - DEBUG(0,("Unknown tar option\n")); - return 0; - } - - if (!tar_type) { - printf("Option T must be followed by one of c or x.\n"); - return 0; - } - - /* tar_excl is true if cliplist lists files to be included. - * Both 'I' and 'F' mean include. */ - tar_excl=tar_clipfl!='X'; - - if (tar_clipfl=='F') { - if (argc-Optind-1 != 1) { - DEBUG(0,("Option F must be followed by exactly one filename.\n")); - return 0; - } - if (! read_inclusion_file(argv[Optind+1])) { - return 0; - } - } else if (Optind+1<argc && !tar_re_search) { /* For backwards compatibility */ - char *tmpstr; - char **tmplist; - int clipcount; - - cliplist=argv+Optind+1; - clipn=argc-Optind-1; - clipcount = clipn; - - if ((tmplist=malloc(clipn*sizeof(char *))) == NULL) { - DEBUG(0, ("Could not allocate space to process cliplist, count = %i\n", - clipn) - ); - return 0; - } - - for (clipcount = 0; clipcount < clipn; clipcount++) { - - DEBUG(5, ("Processing an item, %s\n", cliplist[clipcount])); - - if ((tmpstr = (char *)malloc(strlen(cliplist[clipcount])+1)) == NULL) { - DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", - clipcount) - ); - return 0; - } - unfixtarname(tmpstr, cliplist[clipcount], strlen(cliplist[clipcount]) + 1, True); - tmplist[clipcount] = tmpstr; - DEBUG(5, ("Processed an item, %s\n", tmpstr)); - - DEBUG(5, ("Cliplist is: %s\n", cliplist[0])); - } - cliplist = tmplist; - must_free_cliplist = True; - } - - if (Optind+1<argc && tar_re_search) { /* Doing regular expression seaches */ -#ifdef HAVE_REGEX_H - int errcode; - if ((preg = (regex_t *)malloc(65536)) == NULL) { + if (!tar_type) { + printf("Option T must be followed by one of c or x.\n"); + return 0; + } - DEBUG(0, ("Could not allocate buffer for regular expression search\n")); - return; + /* tar_excl is true if cliplist lists files to be included. + * Both 'I' and 'F' mean include. */ + tar_excl=tar_clipfl!='X'; - } + if (tar_clipfl=='F') { + if (argc-Optind-1 != 1) { + DEBUG(0,("Option F must be followed by exactly one filename.\n")); + return 0; + } + newOptind++; + Optind++; + if (! read_inclusion_file(argv[Optind])) { + return 0; + } + } else if (Optind+1<argc && !tar_re_search) { /* For backwards compatibility */ + char *tmpstr; + char **tmplist; + int clipcount; + + cliplist=argv+Optind+1; + clipn=argc-Optind-1; + clipcount = clipn; + + if ((tmplist=malloc(clipn*sizeof(char *))) == NULL) { + DEBUG(0, ("Could not allocate space to process cliplist, count = %i\n", clipn)); + return 0; + } - if (errcode = regcomp(preg, argv[Optind + 1], REG_EXTENDED)) { - char errstr[1024]; - size_t errlen; + for (clipcount = 0; clipcount < clipn; clipcount++) { - errlen = regerror(errcode, preg, errstr, sizeof(errstr) - 1); - - DEBUG(0, ("Could not compile pattern buffer for re search: %s\n%s\n", argv[Optind + 1], errstr)); - return; + DEBUG(5, ("Processing an item, %s\n", cliplist[clipcount])); + + if ((tmpstr = (char *)malloc(strlen(cliplist[clipcount])+1)) == NULL) { + DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", clipcount)); + return 0; + } + + unfixtarname(tmpstr, cliplist[clipcount], strlen(cliplist[clipcount]) + 1, True); + tmplist[clipcount] = tmpstr; + DEBUG(5, ("Processed an item, %s\n", tmpstr)); + + DEBUG(5, ("Cliplist is: %s\n", cliplist[0])); + } - } + cliplist = tmplist; + must_free_cliplist = True; + + newOptind += clipn; + } + + if (Optind+1<argc && tar_re_search) { /* Doing regular expression seaches */ +#ifdef HAVE_REGEX_H + int errcode; + + if ((preg = (regex_t *)malloc(65536)) == NULL) { + + DEBUG(0, ("Could not allocate buffer for regular expression search\n")); + return; + } + + if (errcode = regcomp(preg, argv[Optind + 1], REG_EXTENDED)) { + char errstr[1024]; + size_t errlen; + + errlen = regerror(errcode, preg, errstr, sizeof(errstr) - 1); + DEBUG(0, ("Could not compile pattern buffer for re search: %s\n%s\n", argv[Optind + 1], errstr)); + return; + } #endif - clipn=argc-Optind-1; - cliplist=argv+Optind+1; - - } - - if (Optind>=argc || !strcmp(argv[Optind], "-")) { - /* Sets tar handle to either 0 or 1, as appropriate */ - tarhandle=(tar_type=='c'); - /* - * Make sure that dbf points to stderr if we are using stdout for - * tar output - */ - if (tarhandle == 1) - dbf = x_stderr; - } else { - if (tar_type=='c' && (dry_run || strcmp(argv[Optind], "/dev/null")==0)) - { - if (!dry_run) { - DEBUG(0,("Output is /dev/null, assuming dry_run\n")); - dry_run = True; + clipn=argc-Optind-1; + cliplist=argv+Optind+1; + newOptind += clipn; + } + + if (Optind>=argc || !strcmp(argv[Optind], "-")) { + /* Sets tar handle to either 0 or 1, as appropriate */ + tarhandle=(tar_type=='c'); + /* + * Make sure that dbf points to stderr if we are using stdout for + * tar output + */ + if (tarhandle == 1) { + dbf = x_stderr; + } + if (!strcmp(argv[Optind], "-")) { + newOptind++; + } + + } else { + if (tar_type=='c' && (dry_run || strcmp(argv[Optind], "/dev/null")==0)) { + if (!dry_run) { + DEBUG(0,("Output is /dev/null, assuming dry_run\n")); + dry_run = True; + } + tarhandle=-1; + } else if ((tar_type=='x' && (tarhandle = sys_open(argv[Optind], O_RDONLY, 0)) == -1) + || (tar_type=='c' && (tarhandle=sys_creat(argv[Optind], 0644)) < 0)) { + DEBUG(0,("Error opening local file %s - %s\n", argv[Optind], strerror(errno))); + return(0); + } + newOptind++; } - tarhandle=-1; - } else - if ((tar_type=='x' && (tarhandle = sys_open(argv[Optind], O_RDONLY, 0)) == -1) - || (tar_type=='c' && (tarhandle=sys_creat(argv[Optind], 0644)) < 0)) - { - DEBUG(0,("Error opening local file %s - %s\n", - argv[Optind], strerror(errno))); - return(0); - } - } - return 1; + return newOptind; } diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c index 68165792da..5daefec5a5 100644 --- a/source3/client/smbspool.c +++ b/source3/client/smbspool.c @@ -282,7 +282,7 @@ smb_connect(const char *workgroup, /* I - Workgroup */ get_myname(myname); nt_status = cli_full_connection(&c, myname, server, NULL, 0, share, "?????", - username, workgroup, password, 0, NULL); + username, workgroup, password, 0, Undefined, NULL); if (!NT_STATUS_IS_OK(nt_status)) { fprintf(stderr, "ERROR: Connection failed with error %s\n", nt_errstr(nt_status)); diff --git a/source3/client/tree.c b/source3/client/tree.c index 3b90d15f65..97ad7742e3 100644 --- a/source3/client/tree.c +++ b/source3/client/tree.c @@ -69,7 +69,7 @@ static void tree_error_message(gchar *message) { * workgroup type and return a path from there */ -static char path_string[1024]; +static pstring path_string; char *get_path(GtkWidget *item) { @@ -112,7 +112,7 @@ char *get_path(GtkWidget *item) * Now, build the path */ - snprintf(path_string, sizeof(path_string), "smb:/"); + pstrcpy( path_string, "smb:/" ); for (j = i - 1; j >= 0; j--) { @@ -151,7 +151,7 @@ static void cb_select_child (GtkWidget *root_tree, GtkWidget *child, char dirbuf[512]; struct smbc_dirent *dirp; struct stat st1; - char path[1024], path1[1024]; + pstring path, path1; g_print ("select_child called for root tree %p, subtree %p, child %p\n", root_tree, subtree, child); diff --git a/source3/configure.in b/source3/configure.in index fd7ee9fc30..f964bc719f 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -152,12 +152,10 @@ AC_SUBST(LIBSMBCLIENT) AC_SUBST(PRINTLIBS) AC_SUBST(AUTHLIBS) AC_SUBST(ACLLIBS) -AC_SUBST(ADSLIBS) AC_SUBST(PASSDBLIBS) AC_SUBST(IDMAP_LIBS) AC_SUBST(KRB5_LIBS) AC_SUBST(LDAP_LIBS) -AC_SUBST(LDAP_OBJ) AC_SUBST(SHLIB_PROGS) AC_SUBST(SMBWRAPPER) AC_SUBST(EXTRA_BIN_PROGS) @@ -289,7 +287,7 @@ dnl These have to be built static: default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin" dnl These are preferably build shared, and static if dlopen() is not available -default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms" +default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms vfs_default_quota" if test "x$developer" = xyes; then default_static_modules="$default_static_modules rpc_echo" @@ -552,7 +550,7 @@ AC_CHECK_HEADERS(shadow.h netinet/ip.h netinet/tcp.h netinet/in_systm.h netinet/ AC_CHECK_HEADERS(nss.h nss_common.h ns_api.h sys/security.h security/pam_appl.h security/pam_modules.h) AC_CHECK_HEADERS(stropts.h poll.h) AC_CHECK_HEADERS(sys/capability.h syscall.h sys/syscall.h) -AC_CHECK_HEADERS(sys/acl.h attr/xattr.h sys/cdefs.h glob.h) +AC_CHECK_HEADERS(sys/acl.h sys/attributes.h attr/xattr.h sys/cdefs.h glob.h) # For experimental utmp support (lastlog on some BSD-like systems) AC_CHECK_HEADERS(utmp.h utmpx.h lastlog.h) @@ -843,7 +841,7 @@ AC_CHECK_FUNCS(setpriv setgidx setuidx setgroups sysconf mktime rename ftruncate AC_CHECK_FUNCS(lstat64 fopen64 atexit grantpt dup2 lseek64 ftruncate64 readdir64) AC_CHECK_FUNCS(fseek64 fseeko64 ftell64 ftello64 setluid getpwanam setlinebuf) AC_CHECK_FUNCS(srandom random srand rand setenv usleep strcasecmp fcvt fcvtl symlink readlink) -AC_CHECK_FUNCS(syslog vsyslog getgrouplist timegm) +AC_CHECK_FUNCS(syslog vsyslog timegm) AC_CHECK_FUNCS(setlocale nl_langinfo) # setbuffer, shmget, shm_open are needed for smbtorture AC_CHECK_FUNCS(setbuffer shmget shm_open backtrace_symbols) @@ -867,6 +865,38 @@ AC_CHECK_FUNCS(pwrite _pwrite __pwrite pwrite64 _pwrite64 __pwrite64) AC_CHECK_FUNCS(open64 _open64 __open64 creat64) # +# +# +case "$host_os" in + *linux*) + # glibc <= 2.3.2 has a broken getgrouplist + AC_TRY_RUN([ +#include <unistd.h> +#include <sys/utsname.h> +main() { + /* glibc up to 2.3 has a broken getgrouplist */ +#if defined(__GLIBC__) && defined(__GLIBC_MINOR__) + int libc_major = __GLIBC__; + int libc_minor = __GLIBC_MINOR__; + + if (libc_major < 2) + exit(1); + if ((libc_major == 2) && (libc_minor <= 3)) + exit(1); +#endif + exit(0); +} +], [linux_getgrouplist_ok=yes], [linux_getgrouplist_ok=no]) + if test x"$linux_getgrouplist_ok" = x"yes"; then + AC_DEFINE(HAVE_GETGROUPLIST, 1, [Have good getgrouplist]) + fi + ;; + *) + AC_CHECK_FUNCS(getgrouplist) + ;; +esac + +# # stat64 family may need <sys/stat.h> on some systems, notably ReliantUNIX # @@ -946,6 +976,8 @@ AC_SEARCH_LIBS(getxattr, [attr]) AC_CHECK_FUNCS(getxattr lgetxattr fgetxattr listxattr llistxattr) AC_CHECK_FUNCS(flistxattr removexattr lremovexattr fremovexattr) AC_CHECK_FUNCS(setxattr lsetxattr fsetxattr) +AC_CHECK_FUNCS(attr_get attr_list attr_set attr_remove) +AC_CHECK_FUNCS(attr_getf attr_listf attr_setf attr_removef) # Assume non-shared by default and override below BLDSHARED="false" @@ -2095,14 +2127,105 @@ AC_ARG_WITH(dfs, AC_MSG_RESULT(no) ) +######################################################## +# Compile with LDAP support? + +with_ldap_support=auto +AC_MSG_CHECKING([for LDAP support]) + +AC_ARG_WITH(ldap, +[ --with-ldap LDAP support (default yes)], +[ case "$withval" in + yes|no) + with_ldap_support=$withval + ;; + esac ]) + +AC_MSG_RESULT($with_ldap_support) + +SMBLDAP="" +AC_SUBST(SMBLDAP) +if test x"$with_ldap_support" != x"no"; then + + ################################################################## + # first test for ldap.h and lber.h + # (ldap.h is required for this test) + AC_CHECK_HEADERS(ldap.h lber.h) + + if test x"$ac_cv_header_ldap_h" != x"yes"; then + if test x"$with_ldap_support" = x"yes"; then + AC_MSG_ERROR(ldap.h is needed for LDAP support) + else + AC_MSG_WARN(ldap.h is needed for LDAP support) + fi + + with_ldap_support=no + fi +fi + +if test x"$with_ldap_support" != x"no"; then + ac_save_LIBS=$LIBS + + ################################################################## + # we might need the lber lib on some systems. To avoid link errors + # this test must be before the libldap test + AC_CHECK_LIB_EXT(lber, LDAP_LIBS, ber_scanf) + + ######################################################## + # now see if we can find the ldap libs in standard paths + AC_CHECK_LIB_EXT(ldap, LDAP_LIBS, ldap_init) + + AC_CHECK_FUNC_EXT(ldap_domain2hostlist,$LDAP_LIBS) + + ######################################################## + # If we have LDAP, does it's rebind procedure take 2 or 3 arguments? + # Check found in pam_ldap 145. + AC_CHECK_FUNC_EXT(ldap_set_rebind_proc,$LDAP_LIBS) + + LIBS="$LIBS $LDAP_LIBS" + AC_CACHE_CHECK(whether ldap_set_rebind_proc takes 3 arguments, smb_ldap_cv_ldap_set_rebind_proc, [ + AC_TRY_COMPILE([ + #include <lber.h> + #include <ldap.h>], + [ldap_set_rebind_proc(0, 0, 0);], + [smb_ldap_cv_ldap_set_rebind_proc=3], + [smb_ldap_cv_ldap_set_rebind_proc=2] + ) + ]) + + AC_DEFINE_UNQUOTED(LDAP_SET_REBIND_PROC_ARGS, $smb_ldap_cv_ldap_set_rebind_proc, [Number of arguments to ldap_set_rebind_proc]) + + AC_CHECK_FUNC_EXT(ldap_initialize,$LDAP_LIBS) + + if test x"$ac_cv_lib_ext_ldap_ldap_init" = x"yes" -a x"$ac_cv_func_ext_ldap_domain2hostlist" = x"yes"; then + AC_DEFINE(HAVE_LDAP,1,[Whether ldap is available]) + default_static_modules="$default_static_modules pdb_ldap idmap_ldap"; + SMBLDAP="lib/smbldap.o" + with_ldap_support=yes + AC_MSG_CHECKING(whether LDAP support is used) + AC_MSG_RESULT(yes) + else + if test x"$with_ldap_support" = x"yes"; then + AC_MSG_ERROR(libldap is needed for LDAP support) + else + AC_MSG_WARN(libldap is needed for LDAP support) + fi + + LDAP_LIBS="" + with_ldap_support=no + fi + LIBS=$ac_save_LIBS +fi + + ################################################# # active directory support with_ads_support=auto -AC_MSG_CHECKING([whether to use Active Directory]) +AC_MSG_CHECKING([for Active Directory and krb5 support]) AC_ARG_WITH(ads, -[ --with-ads Active Directory support (default yes)], +[ --with-ads Active Directory support (default auto)], [ case "$withval" in yes|no) with_ads_support="$withval" @@ -2114,22 +2237,34 @@ AC_MSG_RESULT($with_ads_support) FOUND_KRB5=no KRB5_LIBS="" +if test x"$with_ldap_support" != x"yes"; then + if test x"$with_ads_support" = x"yes"; then + AC_MSG_ERROR(Active Directory Support requires LDAP support) + elif test x"$with_ads_support" != x"no"; then + AC_MSG_WARN(Active Directory Support requires LDAP support) + fi + with_ads_support=no +fi + if test x"$with_ads_support" != x"no"; then # Do no harm to the values of CFLAGS and LIBS while testing for # Kerberos support. - ac_save_CFLAGS="$CFLAGS" - ac_save_LIBS="$LIBS" - ################################################# # check for krb5-config from recent MIT and Heimdal kerberos 5 AC_PATH_PROG(KRB5_CONFIG, krb5-config) AC_MSG_CHECKING(for working krb5-config) if test -x "$KRB5_CONFIG"; then - LIBS="$LIBS `$KRB5_CONFIG --libs`" - CFLAGS="$CFLAGS `$KRB5_CONFIG --cflags | sed s/@INCLUDE_des@//`" - CPPFLAGS="$CPPFLAGS `$KRB5_CONFIG --cflags | sed s/@INCLUDE_des@//`" + ac_save_CFLAGS=$CFLAGS + CFLAGS="";export CFLAGS + ac_save_LDFLAGS=$LDFLAGS + LDFLAGS="";export LDFLAGS + KRB5_LIBS="`$KRB5_CONFIG --libs gssapi`" + KRB5_CFLAGS="`$KRB5_CONFIG --cflags | sed s/@INCLUDE_des@//`" + KRB5_CPPFLAGS="`$KRB5_CONFIG --cflags | sed s/@INCLUDE_des@//`" + CFLAGS=$ac_save_CFLAGS;export CFLAGS + LDFLAGS=$ac_save_LDFLAGS;export LDFLAGS FOUND_KRB5=yes AC_MSG_RESULT(yes) else @@ -2144,18 +2279,21 @@ if test x"$with_ads_support" != x"no"; then [ --with-krb5=base-dir Locate Kerberos 5 support (default=/usr)], [ case "$withval" in no) - AC_MSG_RESULT(no) + AC_MSG_RESULT(no krb5-path given) + ;; + yes) + AC_MSG_RESULT(/usr) + FOUND_KRB5=yes ;; *) - AC_MSG_RESULT(yes) - LIBS="$LIBS -lkrb5" - CFLAGS="$CFLAGS -I$withval/include" - CPPFLAGS="$CPPFLAGS -I$withval/include" - LDFLAGS="$LDFLAGS -L$withval/lib" + AC_MSG_RESULT($withval) + KRB5_CFLAGS="-I$withval/include" + KRB5_CPPFLAGS="-I$withval/include" + KRB5_LDFLAGS="-L$withval/lib" FOUND_KRB5=yes ;; esac ], - AC_MSG_RESULT(no) + AC_MSG_RESULT(no krb5-path given) ) fi @@ -2165,15 +2303,13 @@ if test x"$with_ads_support" != x"no"; then AC_MSG_CHECKING(for /usr/include/heimdal) if test -d /usr/include/heimdal; then if test -f /usr/lib/heimdal/lib/libkrb5.a; then - LIBS="$LIBS -lkrb5" - CFLAGS="$CFLAGS -I/usr/include/heimdal" - CPPFLAGS="$CPPFLAGS -I/usr/include/heimdal" - LDFLAGS="$LDFLAGS -L/usr/lib/heimdal/lib" + KRB5_CFLAGS="-I/usr/include/heimdal" + KRB5_CPPFLAGS="-I/usr/include/heimdal" + KRB5_LDFLAGS="-L/usr/lib/heimdal/lib" AC_MSG_RESULT(yes) else - LIBS="$LIBS -lkrb5" - CFLAGS="$CFLAGS -I/usr/include/heimdal" - CPPFLAGS="$CPPFLAGS -I/usr/include/heimdal" + KRB5_CFLAGS="-I/usr/include/heimdal" + KRB5_CPPFLAGS="-I/usr/include/heimdal" AC_MSG_RESULT(yes) fi else @@ -2186,16 +2322,25 @@ if test x"$with_ads_support" != x"no"; then # see if this box has the RedHat location for kerberos AC_MSG_CHECKING(for /usr/kerberos) if test -d /usr/kerberos -a -f /usr/kerberos/lib/libkrb5.a; then - LIBS="$LIBS -lkrb5" - LDFLAGS="$LDFLAGS -L/usr/kerberos/lib" - CFLAGS="$CFLAGS -I/usr/kerberos/include" - CPPFLAGS="$CPPFLAGS -I/usr/kerberos/include" + KRB5_LDFLAGS="-L/usr/kerberos/lib" + KRB5_CFLAGS="-I/usr/kerberos/include" + KRB5_CPPFLAGS="-I/usr/kerberos/include" AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi fi + ac_save_CFLAGS=$CFLAGS + ac_save_CPPFLAGS=$CPPFLAGS + ac_save_LDFLAGS=$LDFLAGS + + CFLAGS="$CFLAGS $KRB5_CFLAGS" + CPPFLAGS="$CPPFLAGS $KRB5_CPPFLAGS" + LDFLAGS="$LDFLAGS $KRB5_LDFLAGS" + + KRB5_LIBS="$KRB5_LDFLAGS $KRB5_LIBS" + # now check for krb5.h. Some systems have the libraries without the headers! # note that this check is done here to allow for different kerberos # include paths @@ -2215,24 +2360,17 @@ if test x"$with_ads_support" != x"no"; then # Turn off AD support and restore CFLAGS and LIBS variables with_ads_support="no" - - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - - else - - # Get rid of case where $with_ads_support=auto - - with_ads_support="yes" - + + CFLAGS=$ac_save_CFLAGS + CPPFLAGS=$ac_save_CPPFLAGS + LDFLAGS=$ac_save_LDFLAGS fi fi # Now we have determined whether we really want ADS support -if test x"$with_ads_support" = x"yes"; then - - AC_DEFINE(WITH_ADS,1,[Whether to include Active Directory support]) +if test x"$with_ads_support" != x"no"; then + ac_save_LIBS=$LIBS # now check for gssapi headers. This is also done here to allow for # different kerberos include paths @@ -2240,62 +2378,46 @@ if test x"$with_ads_support" = x"yes"; then ################################################################## # we might need the k5crypto and com_err libraries on some systems - AC_CHECK_LIB(com_err, _et_list) - AC_CHECK_LIB(k5crypto, krb5_encrypt_data) + AC_CHECK_LIB_EXT(com_err, KRB5_LIBS, _et_list) + AC_CHECK_LIB_EXT(k5crypto, KRB5_LIBS, krb5_encrypt_data) # Heimdal checks. - AC_CHECK_LIB(crypto, des_set_key) - AC_CHECK_LIB(asn1, copy_Authenticator) - AC_CHECK_LIB(roken, roken_getaddrinfo_hostspec) + AC_CHECK_LIB_EXT(crypto, KRB5_LIBS, des_set_key) + AC_CHECK_LIB_EXT(asn1, KRB5_LIBS, copy_Authenticator) + AC_CHECK_LIB_EXT(roken, KRB5_LIBS, roken_getaddrinfo_hostspec) # Heimdal checks. On static Heimdal gssapi must be linked before krb5. - AC_CHECK_LIB(gssapi, gss_display_status, [LIBS="$LIBS -lgssapi -lkrb5"; - AC_DEFINE(HAVE_GSSAPI,1,[Whether GSSAPI is available])]) - - AC_CHECK_LIB(krb5, krb5_set_real_time, - [AC_DEFINE(HAVE_KRB5_SET_REAL_TIME,1, - [Whether krb5_set_real_time is available])]) - AC_CHECK_LIB(krb5, krb5_set_default_in_tkt_etypes, - [AC_DEFINE(HAVE_KRB5_SET_DEFAULT_IN_TKT_ETYPES,1, - [Whether krb5_set_default_in_tkt_etypes, is available])]) - AC_CHECK_LIB(krb5, krb5_set_default_tgs_ktypes, - [AC_DEFINE(HAVE_KRB5_SET_DEFAULT_TGS_KTYPES,1, - [Whether krb5_set_default_tgs_ktypes is available])]) - - AC_CHECK_LIB(krb5, krb5_principal2salt, - [AC_DEFINE(HAVE_KRB5_PRINCIPAL2SALT,1, - [Whether krb5_principal2salt is available])]) - AC_CHECK_LIB(krb5, krb5_use_enctype, - [AC_DEFINE(HAVE_KRB5_USE_ENCTYPE,1, - [Whether krb5_use_enctype is available])]) - AC_CHECK_LIB(krb5, krb5_string_to_key, - [AC_DEFINE(HAVE_KRB5_STRING_TO_KEY,1, - [Whether krb5_string_to_key is available])]) - AC_CHECK_LIB(krb5, krb5_get_pw_salt, - [AC_DEFINE(HAVE_KRB5_GET_PW_SALT,1, - [Whether krb5_get_pw_salt is available])]) - AC_CHECK_LIB(krb5, krb5_string_to_key_salt, - [AC_DEFINE(HAVE_KRB5_STRING_TO_KEY_SALT,1, - [Whether krb5_string_to_key_salt is available])]) - AC_CHECK_LIB(krb5, krb5_auth_con_setkey, - [AC_DEFINE(HAVE_KRB5_AUTH_CON_SETKEY,1, - [Whether krb5_auth_con_setkey is available])]) - AC_CHECK_LIB(krb5, krb5_auth_con_setuseruserkey, - [AC_DEFINE(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY,1, - [Whether krb5_auth_con_setuseruserkey is available])]) - AC_CHECK_LIB(krb5, krb5_locate_kdc, - [AC_DEFINE(HAVE_KRB5_LOCATE_KDC,1, - [Whether krb5_locate_kdc is available])]) - AC_CHECK_LIB(krb5, krb5_get_permitted_enctypes, - [AC_DEFINE(HAVE_KRB5_GET_PERMITTED_ENCTYPES,1, - [Whether krb5_get_permitted_enctypes is available])]) - AC_CHECK_LIB(krb5, krb5_get_default_in_tkt_etypes, - [AC_DEFINE(HAVE_KRB5_GET_DEFAULT_IN_TKT_ETYPES,1, - [Whether krb5_get_default_in_tkt_etypes is available])]) - AC_CHECK_LIB(krb5, krb5_free_ktypes, - [AC_DEFINE(HAVE_KRB5_FREE_KTYPES,1, - [Whether krb5_free_ktypes is available])]) + AC_CHECK_LIB_EXT(gssapi, KRB5_LIBS, gss_display_status,[],[], + AC_DEFINE(HAVE_GSSAPI,1,[Whether GSSAPI is available])) + ######################################################## + # now see if we can find the krb5 libs in standard paths + # or as specified above + AC_CHECK_LIB_EXT(krb5, KRB5_LIBS, krb5_mk_req_extended) + + ######################################################## + # now see if we can find the gssapi libs in standard paths + AC_CHECK_LIB_EXT(gssapi_krb5, KRB5_LIBS,gss_display_status,[],[], + AC_DEFINE(HAVE_GSSAPI,1,[Whether GSSAPI is available])) + + AC_CHECK_FUNC_EXT(krb5_set_real_time, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_set_default_in_tkt_etypes, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_set_default_tgs_ktypes, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_principal2salt, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_use_enctype, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_string_to_key, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_get_pw_salt, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_string_to_key_salt, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_auth_con_setkey, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_auth_con_setuseruserkey, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_locate_kdc, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_get_permitted_enctypes, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_get_default_in_tkt_etypes, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_free_ktypes, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_principal_get_comp_string, $KRB5_LIBS) + + LIBS="$LIBS $KRB5_LIBS" + AC_CACHE_CHECK([for addrtype in krb5_address], samba_cv_HAVE_ADDRTYPE_IN_KRB5_ADDRESS,[ AC_TRY_COMPILE([#include <krb5.h>], @@ -2355,87 +2477,34 @@ if test x"$with_ads_support" = x"yes"; then [Whether the ENCTYPE_ARCFOUR_HMAC_MD5 key type is available]) fi - ######################################################## - # now see if we can find the krb5 libs in standard paths - # or as specified above - AC_CHECK_LIB(krb5, krb5_mk_req_extended, [KRB5_LIBS="$LIBS -lkrb5"; - KRB5_CFLAGS="$CFLAGS"; - AC_DEFINE(HAVE_KRB5,1,[Whether KRB5 is available])]) + AC_CACHE_CHECK([for the krb5_princ_component macro], + samba_cv_HAVE_KRB5_PRINC_COMPONENT,[ + AC_TRY_LINK([#include <krb5.h>], + [const krb5_data *pkdata; krb5_context context; krb5_principal principal; pkdata = krb5_princ_component(context, principal, 0);], + samba_cv_HAVE_KRB5_PRINC_COMPONENT=yes, + samba_cv_HAVE_KRB5_PRINC_COMPONENT=no)]) - ######################################################## - # now see if we can find the gssapi libs in standard paths - AC_CHECK_LIB(gssapi_krb5, gss_display_status, - [KRB5_LIBS="$KRB5_LIBS -lgssapi_krb5"; - AC_DEFINE(HAVE_GSSAPI,1,[Whether GSSAPI is available])]) - - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" -fi - -######################################################## -# Compile with LDAP support? - -LDAP_OBJ="" -with_ldap_support=yes -AC_MSG_CHECKING([whether to use LDAP]) - -AC_ARG_WITH(ldap, -[ --with-ldap LDAP support (default yes)], -[ case "$withval" in - no) - with_ldap_support=no - ;; - esac ]) - -AC_MSG_RESULT($with_ldap_support) + if test x"$samba_cv_HAVE_KRB5_PRINC_COMPONENT" = x"yes"; then + AC_DEFINE(HAVE_KRB5_PRINC_COMPONENT,1, + [Whether krb5_princ_component is available]) + fi -SMBLDAP="" -if test x"$with_ldap_support" = x"yes"; then - ac_save_LIBS="$LIBS" - LIBS="" - ################################################################## - # we might need the lber lib on some systems. To avoid link errors - # this test must be before the libldap test - AC_CHECK_LIB(lber, ber_scanf) - - ######################################################## - # now see if we can find the ldap libs in standard paths - if test x$have_ldap != xyes; then - AC_CHECK_LIB(ldap, ldap_init, [ - LIBS="$LIBS -lldap"; - AC_CHECK_LIB(ldap, ldap_domain2hostlist, [ - AC_DEFINE(HAVE_LDAP,1,[Whether ldap is available]) - AC_CHECK_HEADERS([ldap.h lber.h], - [default_static_modules="$default_static_modules pdb_ldap idmap_ldap"; - SMBLDAP="lib/smbldap.o"]) - ]) - ]) - - ######################################################## - # If we have LDAP, does it's rebind procedure take 2 or 3 arguments? - # Check found in pam_ldap 145. - AC_CHECK_FUNCS(ldap_set_rebind_proc) - AC_CACHE_CHECK(whether ldap_set_rebind_proc takes 3 arguments, pam_ldap_cv_ldap_set_rebind_proc, [ - AC_TRY_COMPILE([ - #include <lber.h> - #include <ldap.h>], [ldap_set_rebind_proc(0, 0, 0);], [pam_ldap_cv_ldap_set_rebind_proc=3], [pam_ldap_cv_ldap_set_rebind_proc=2]) ]) - AC_DEFINE_UNQUOTED(LDAP_SET_REBIND_PROC_ARGS, $pam_ldap_cv_ldap_set_rebind_proc, [Number of arguments to ldap_set_rebind_proc]) - AC_CHECK_FUNCS(ldap_initialize) - fi - - AC_SUBST(SMBLDAP) - LDAP_LIBS="$LIBS"; - LIBS="$ac_save_LIBS"; -else - # Can't have ADS support without LDAP + if test x"$ac_cv_lib_ext_krb5_krb5_mk_req_extended" = x"yes"; then + AC_DEFINE(HAVE_KRB5,1,[Whether to have KRB5 support]) + AC_DEFINE(WITH_ADS,1,[Whether to include Active Directory support]) + AC_MSG_CHECKING(whether Active Directory and krb5 support is used) + AC_MSG_RESULT(yes) + else if test x"$with_ads_support" = x"yes"; then - AC_MSG_ERROR(Active directory support requires LDAP) + AC_MSG_ERROR(libkrb5 is needed for Active Directory support) + else + AC_MSG_WARN(libkrb5 is needed for Active Directory support) fi -fi - -if test x"$with_ads_support" = x"yes"; then - ADSLIBS="$LDAP_LIBS $KRB5_LIBS" + KRB5_LIBS="" + with_ads_support=no + fi + LIBS="$ac_save_LIBS" fi ######################################################## @@ -3641,7 +3710,7 @@ WINBIND_WINS_NSS="nsswitch/libnss_wins.$SHLIBEXT" WINBIND_NSS_LDSHFLAGS=$LDSHFLAGS case "$host_os" in - *linux*) + *linux*|*freebsd*) WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_linux.o" ;; *irix*) @@ -3887,6 +3956,7 @@ SMB_MODULE(vfs_audit, \$(VFS_AUDIT_OBJ), "bin/audit.$SHLIBEXT", VFS) SMB_MODULE(vfs_extd_audit, \$(VFS_EXTD_AUDIT_OBJ), "bin/extd_audit.$SHLIBEXT", VFS) SMB_MODULE(vfs_netatalk, \$(VFS_NETATALK_OBJ), "bin/netatalk.$SHLIBEXT", VFS) SMB_MODULE(vfs_fake_perms, \$(VFS_FAKE_PERMS_OBJ), "bin/fake_perms.$SHLIBEXT", VFS) +SMB_MODULE(vfs_default_quota, \$(VFS_DEFAULT_QUOTA_OBJ), "bin/default_quota.$SHLIBEXT", VFS) SMB_SUBSYSTEM(VFS) AC_DEFINE_UNQUOTED(STRING_STATIC_MODULES, "$string_static_modules", [String list of builtin modules]) @@ -3903,10 +3973,10 @@ fi AC_MSG_RESULT([Using libraries:]) AC_MSG_RESULT([ LIBS = $LIBS]) -if test x"$with_ads_support" = x"yes"; then +if test x"$with_ads_support" != x"no"; then AC_MSG_RESULT([ KRB5_LIBS = $KRB5_LIBS]) fi -if test x"$with_ldap_support" = x"yes"; then +if test x"$with_ldap_support" != x"no"; then AC_MSG_RESULT([ LDAP_LIBS = $LDAP_LIBS]) fi diff --git a/source3/dynconfig.c b/source3/dynconfig.c index 4577c3947c..34c716926c 100644 --- a/source3/dynconfig.c +++ b/source3/dynconfig.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. Copyright (C) 2001 by Martin Pool <mbp@samba.org> - Copyright (C) 2003 by Anthony Liguori <aliguor@us.ibm.com> + Copyright (C) 2003 by Jim McDonough <jmcd@us.ibm.com> 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 diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c index 3d2af5d0ba..cd903fa28b 100644 --- a/source3/groupdb/mapping.c +++ b/source3/groupdb/mapping.c @@ -509,7 +509,7 @@ BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map) return False; } - DEBUG(10, ("get_domain_group_from_sid: SID is mapped to gid:%d\n",map->gid)); + DEBUG(10, ("get_domain_group_from_sid: SID is mapped to gid:%lu\n",(unsigned long)map->gid)); if ( (grp=getgrgid(map->gid)) == NULL) { DEBUG(10, ("get_domain_group_from_sid: gid DOESN'T exist in UNIX security\n")); diff --git a/source3/include/authdata.h b/source3/include/authdata.h index 0798b72bdf..9d80745fb0 100644 --- a/source3/include/authdata.h +++ b/source3/include/authdata.h @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. Kerberos authorization data - Copyright (C) Jim McDonough 2003 + Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003 This program is free software; you can redistribute it and/or modify diff --git a/source3/include/byteorder.h b/source3/include/byteorder.h index c262dd2d33..0eef557306 100644 --- a/source3/include/byteorder.h +++ b/source3/include/byteorder.h @@ -105,7 +105,7 @@ it also defines lots of intermediate macros, just ignore those :-) #define CAREFUL_ALIGNMENT 1 #endif -#define CVAL(buf,pos) (((const unsigned char *)(buf))[pos]) +#define CVAL(buf,pos) ((unsigned)(((const unsigned char *)(buf))[pos])) #define CVAL_NC(buf,pos) (((unsigned char *)(buf))[pos]) /* Non-const version of CVAL */ #define PVAL(buf,pos) (CVAL(buf,pos)) #define SCVAL(buf,pos,val) (CVAL_NC(buf,pos) = (val)) diff --git a/source3/include/charset.h b/source3/include/charset.h index c56984ca7b..f999a9cf72 100644 --- a/source3/include/charset.h +++ b/source3/include/charset.h @@ -24,9 +24,9 @@ typedef enum {CH_UCS2=0, CH_UNIX=1, CH_DISPLAY=2, CH_DOS=3, CH_UTF8=4} charset_t #define NUM_CHARSETS 5 -/* - * for each charset we have a function that pulls from that charset to - * a ucs2 buffer, and a function that pushes to a ucs2 buffer +/* + * for each charset we have a function that pushes from that charset to a ucs2 + * buffer, and a function that pulls from ucs2 buffer to that charset. * */ struct charset_functions { diff --git a/source3/include/client.h b/source3/include/client.h index fad2c099b9..598e6c0bda 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -57,18 +57,6 @@ struct print_job_info time_t t; }; -typedef struct smb_sign_info { - void (*sign_outgoing_message)(struct cli_state *cli); - BOOL (*check_incoming_message)(struct cli_state *cli); - void (*free_signing_context)(struct cli_state *cli); - void *signing_context; - - BOOL negotiated_smb_signing; - BOOL allow_smb_signing; - BOOL doing_signing; - BOOL mandatory_signing; -} smb_sign_info; - struct cli_state { int port; int fd; diff --git a/source3/include/dynconfig.h b/source3/include/dynconfig.h index ce256f0613..a74d77e41f 100644 --- a/source3/include/dynconfig.h +++ b/source3/include/dynconfig.h @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. Copyright (C) 2001 by Martin Pool <mbp@samba.org> - Copyright (C) 2003 by Anthony Liguori <aliguor@us.ibm.com> + Copyright (C) 2003 by Jim McDonough <jmcd@us.ibm.com> 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 diff --git a/source3/include/idmap.h b/source3/include/idmap.h index ae7e4e5101..20b1015285 100644 --- a/source3/include/idmap.h +++ b/source3/include/idmap.h @@ -5,7 +5,7 @@ Idmap headers - Copyright (C) Anthony Liguori 2003 + Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003 Copyright (C) Simo Sorce 2003 This library is free software; you can redistribute it and/or diff --git a/source3/include/includes.h b/source3/include/includes.h index edaeda3abe..eb7f73b9d3 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -835,6 +835,8 @@ extern int errno; #include "nsswitch/winbind_client.h" +#include "spnego.h" + /* * Type for wide character dirent structure. * Only d_name is defined by POSIX. @@ -1232,6 +1234,14 @@ int snprintf(char *,size_t ,const char *, ...) PRINTF_ATTRIBUTE(3,4); int asprintf(char **,const char *, ...) PRINTF_ATTRIBUTE(2,3); #endif +/* Fix prototype problem with non-C99 compliant snprintf implementations, esp + HPUX 11. Don't change the sense of this #if statement. Read the comments + in lib/snprint.c if you think you need to. See also bugzilla bug 174. */ + +#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF) +#define snprintf smb_snprintf +#endif + void sys_adminlog(int priority, const char *format_str, ...) PRINTF_ATTRIBUTE(2,3); int pstr_sprintf(pstring s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); @@ -1288,7 +1298,7 @@ krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt); krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters); krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes); void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes); -BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16]); +BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16], BOOL remote); #endif /* HAVE_KRB5 */ /* TRUE and FALSE are part of the C99 standard and gcc, but diff --git a/source3/include/popt_common.h b/source3/include/popt_common.h index 57850bf682..6db30fbc0a 100644 --- a/source3/include/popt_common.h +++ b/source3/include/popt_common.h @@ -41,6 +41,7 @@ struct user_auth_info { pstring password; BOOL got_pass; BOOL use_kerberos; + int signing_state; }; extern struct user_auth_info cmdline_auth_info; diff --git a/source3/include/rpc_ds.h b/source3/include/rpc_ds.h index c01d10554e..7350fdba1f 100644 --- a/source3/include/rpc_ds.h +++ b/source3/include/rpc_ds.h @@ -28,6 +28,10 @@ #define DS_GETPRIMDOMINFO 0x00 +/* Opcodes available on PIPE_NETLOGON */ + +#define DS_ENUM_DOM_TRUSTS 0x28 + /* macros for RPC's */ @@ -50,10 +54,9 @@ typedef struct GUID domain_guid; UNISTR2 netbios_domain; - /* these 2 might be reversed in order. I can't tell from - my tests as both values are the same --jerry */ - UNISTR2 dns_domain; - UNISTR2 forest_domain; + + UNISTR2 dns_domain; /* our dns domain */ + UNISTR2 forest_domain; /* root domain of the forest to which we belong */ } DSROLE_PRIMARY_DOMAIN_INFO_BASIC; typedef struct @@ -85,7 +88,58 @@ typedef struct NTSTATUS status; } DS_R_GETPRIMDOMINFO; +typedef struct { + /* static portion of structure */ + uint32 netbios_ptr; + uint32 dns_ptr; + uint32 flags; + uint32 parent_index; + uint32 trust_type; + uint32 trust_attributes; + uint32 sid_ptr; + GUID guid; + + UNISTR2 netbios_domain; + UNISTR2 dns_domain; + DOM_SID2 sid; + +} DS_DOMAIN_TRUSTS; + +typedef struct { + + uint32 ptr; + uint32 max_count; + DS_DOMAIN_TRUSTS *trusts; + +} DS_DOMAIN_TRUSTS_CTR; + +#define DS_DOMAIN_IN_FOREST 0x0001 /* domains in the forest to which + we belong; even different domain trees */ +#define DS_DOMAIN_DIRECT_OUTBOUND 0x0002 /* trusted domains */ +#define DS_DOMAIN_TREE_ROOT 0x0004 /* root of our forest; also available in + DsRoleGetPrimaryDomainInfo() */ +#define DS_DOMAIN_PRIMARY 0x0008 /* our domain */ +#define DS_DOMAIN_NATIVE_MODE 0x0010 /* native mode AD servers */ +#define DS_DOMAIN_DIRECT_INBOUND 0x0020 /* trusting domains */ + +/* DS_Q_ENUM_DOM_TRUSTS - DsEnumerateDomainTrusts() request */ +typedef struct +{ + uint32 server_ptr; + UNISTR2 server; + uint32 flags; + +} DS_Q_ENUM_DOM_TRUSTS; + +/* DS_R_ENUM_DOM_TRUSTS - DsEnumerateDomainTrusts() response */ +typedef struct +{ + uint32 num_domains; + DS_DOMAIN_TRUSTS_CTR domains; + + NTSTATUS status; +} DS_R_ENUM_DOM_TRUSTS; #endif /* _RPC_DS_H */ diff --git a/source3/include/rpc_samr.h b/source3/include/rpc_samr.h index 7d28a0f3a7..8ec274176a 100644 --- a/source3/include/rpc_samr.h +++ b/source3/include/rpc_samr.h @@ -5,8 +5,7 @@ Copyright (C) Luke Kenneth Casson Leighton 1996-2000 Copyright (C) Paul Ashton 1997-2000 Copyright (C) Jean François Micouleau 1998-2001 - Copyright (C) Anthony Liguori 2002 - Copyright (C) Jim McDonough 2002 + Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002 This program is free software; you can redistribute it and/or modify diff --git a/source3/include/rpc_secdes.h b/source3/include/rpc_secdes.h index fb7060cde3..5e718f8167 100644 --- a/source3/include/rpc_secdes.h +++ b/source3/include/rpc_secdes.h @@ -305,12 +305,12 @@ typedef struct standard_mapping { SA_RIGHT_FILE_EXECUTE) -/* SAM Object specific access rights */ +/* SAM server specific access rights */ -#define SA_RIGHT_SAM_UNKNOWN_1 0x00000001 +#define SA_RIGHT_SAM_CONNECT_SERVER 0x00000001 #define SA_RIGHT_SAM_SHUTDOWN_SERVER 0x00000002 -#define SA_RIGHT_SAM_UNKNOWN_4 0x00000004 -#define SA_RIGHT_SAM_UNKNOWN_8 0x00000008 +#define SA_RIGHT_SAM_INITIALISE_SERVER 0x00000004 +#define SA_RIGHT_SAM_CREATE_DOMAIN 0x00000008 #define SA_RIGHT_SAM_ENUM_DOMAINS 0x00000010 #define SA_RIGHT_SAM_OPEN_DOMAIN 0x00000020 @@ -326,14 +326,14 @@ typedef struct standard_mapping { #define GENERIC_RIGHTS_SAM_WRITE \ (STANDARD_RIGHTS_WRITE_ACCESS | \ - SA_RIGHT_SAM_UNKNOWN_8 | \ - SA_RIGHT_SAM_UNKNOWN_4 | \ + SA_RIGHT_SAM_CREATE_DOMAIN | \ + SA_RIGHT_SAM_INITIALISE_SERVER | \ SA_RIGHT_SAM_SHUTDOWN_SERVER) #define GENERIC_RIGHTS_SAM_EXECUTE \ (STANDARD_RIGHTS_EXECUTE_ACCESS | \ SA_RIGHT_SAM_OPEN_DOMAIN | \ - SA_RIGHT_SAM_UNKNOWN_1) + SA_RIGHT_SAM_CONNECT_SERVER) /* Domain Object specific access rights */ @@ -388,8 +388,8 @@ typedef struct standard_mapping { #define SA_RIGHT_USER_CHANGE_PASSWORD 0x00000040 #define SA_RIGHT_USER_SET_PASSWORD 0x00000080 #define SA_RIGHT_USER_GET_GROUPS 0x00000100 -#define SA_RIGHT_USER_UNKNOWN_200 0x00000200 -#define SA_RIGHT_USER_UNKNOWN_400 0x00000400 +#define SA_RIGHT_USER_READ_GROUP_MEM 0x00000200 +#define SA_RIGHT_USER_CHANGE_GROUP_MEM 0x00000400 #define SA_RIGHT_USER_ALL_ACCESS 0x000007FF @@ -399,7 +399,7 @@ typedef struct standard_mapping { #define GENERIC_RIGHTS_USER_READ \ (STANDARD_RIGHTS_READ_ACCESS | \ - SA_RIGHT_USER_UNKNOWN_200 | \ + SA_RIGHT_USER_READ_GROUP_MEM | \ SA_RIGHT_USER_GET_GROUPS | \ SA_RIGHT_USER_ACCT_FLAGS_EXPIRY | \ SA_RIGHT_USER_GET_LOGONINFO | \ diff --git a/source3/include/smb.h b/source3/include/smb.h index d2714e78bc..deeb61034d 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -42,6 +42,7 @@ #define SMB_PORT2 139 #define SMB_PORTS "445 139" +#define Undefined (-1) #define False (0) #define True (1) #define Auto (2) @@ -79,9 +80,7 @@ typedef int BOOL; #define READ_TIMEOUT 1 #define READ_EOF 2 #define READ_ERROR 3 - -/* This error code can go into the client smb_rw_error. */ -#define WRITE_ERROR 4 +#define WRITE_ERROR 4 /* This error code can go into the client smb_rw_error. */ #define READ_BAD_SIG 5 #define DIR_STRUCT_SIZE 43 @@ -707,13 +706,14 @@ struct bitmap { unsigned int n; }; -#define FLAG_BASIC 0x0001 /* fundamental options */ +/* The following flags are used in SWAT */ +#define FLAG_BASIC 0x0001 /* Display only in BASIC view */ #define FLAG_SHARE 0x0002 /* file sharing options */ #define FLAG_PRINT 0x0004 /* printing options */ #define FLAG_GLOBAL 0x0008 /* local options that should be globally settable in SWAT */ #define FLAG_WIZARD 0x0010 /* Parameters that the wizard will operate on */ -#define FLAG_ADVANCED 0x0020 /* Parameters that the wizard will operate on */ -#define FLAG_DEVELOPER 0x0040 /* Parameters that the wizard will operate on */ +#define FLAG_ADVANCED 0x0020 /* Parameters that will be visible in advanced view */ +#define FLAG_DEVELOPER 0x0040 /* No longer used */ #define FLAG_DEPRECATED 0x1000 /* options that should no longer be used */ #define FLAG_HIDE 0x2000 /* options that should be hidden in SWAT */ #define FLAG_DOS_STRING 0x4000 /* convert from UNIX to DOS codepage when reading this string. */ @@ -1630,4 +1630,18 @@ struct ip_service { unsigned port; }; +/* Used by the SMB signing functions. */ + +typedef struct smb_sign_info { + void (*sign_outgoing_message)(char *outbuf, struct smb_sign_info *si); + BOOL (*check_incoming_message)(char *inbuf, struct smb_sign_info *si); + void (*free_signing_context)(struct smb_sign_info *si); + void *signing_context; + + BOOL negotiated_smb_signing; + BOOL allow_smb_signing; + BOOL doing_signing; + BOOL mandatory_signing; +} smb_sign_info; + #endif /* _SMB_H */ diff --git a/source3/include/smbldap.h b/source3/include/smbldap.h index 589d01aa6d..826fc3c55a 100644 --- a/source3/include/smbldap.h +++ b/source3/include/smbldap.h @@ -132,6 +132,9 @@ struct smbldap_state { char *bind_secret; unsigned int num_failures; + + time_t last_use; + smb_event_id_t event_id; }; #endif /* HAVE_LDAP */ diff --git a/source3/include/sysquotas.h b/source3/include/sysquotas.h index cfdac0609a..b803e6277a 100644 --- a/source3/include/sysquotas.h +++ b/source3/include/sysquotas.h @@ -189,6 +189,22 @@ #define SMB_QUOTAS_NO_LIMIT ((SMB_BIG_UINT)(0)) #define SMB_QUOTAS_NO_SPACE ((SMB_BIG_UINT)(1)) +#define SMB_QUOTAS_SET_NO_LIMIT(dp) \ +{\ + (dp)->softlimit = SMB_QUOTAS_NO_LIMIT;\ + (dp)->hardlimit = SMB_QUOTAS_NO_LIMIT;\ + (dp)->isoftlimit = SMB_QUOTAS_NO_LIMIT;\ + (dp)->ihardlimit = SMB_QUOTAS_NO_LIMIT;\ +} + +#define SMB_QUOTAS_SET_NO_SPACE(dp) \ +{\ + (dp)->softlimit = SMB_QUOTAS_NO_SPACE;\ + (dp)->hardlimit = SMB_QUOTAS_NO_SPACE;\ + (dp)->isoftlimit = SMB_QUOTAS_NO_SPACE;\ + (dp)->ihardlimit = SMB_QUOTAS_NO_SPACE;\ +} + typedef struct _SMB_DISK_QUOTA { enum SMB_QUOTA_TYPE qtype; SMB_BIG_UINT bsize; diff --git a/source3/include/version.h b/source3/include/version.h index 5e2d47e1de..68bc140daf 100644 --- a/source3/include/version.h +++ b/source3/include/version.h @@ -1 +1 @@ -#define VERSION "3.0.0beta3" +#define VERSION "3.0.0rc1" diff --git a/source3/include/vfs.h b/source3/include/vfs.h index 924d706321..452f4dc23b 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -466,6 +466,9 @@ typedef struct vfs_handle_struct { } \ } +/* Check whether module-specific data handle was already allocated or not */ +#define SMB_VFS_HANDLE_TEST_DATA(handle) ( !(handle) || !(handle)->data ? False : True ) + #define SMB_VFS_OP(x) ((void *) x) diff --git a/source3/lib/account_pol.c b/source3/lib/account_pol.c index e8b382c7ab..dc131985a1 100644 --- a/source3/lib/account_pol.c +++ b/source3/lib/account_pol.c @@ -53,7 +53,7 @@ BOOL init_account_policy(void) account_policy_set(AP_MIN_PASSWORD_LEN, MINPASSWDLENGTH); /* 5 chars minimum */ account_policy_set(AP_PASSWORD_HISTORY, 0); /* don't keep any old password */ account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, 0); /* don't force user to logon */ - account_policy_set(AP_MAX_PASSWORD_AGE, MAX_PASSWORD_AGE); /* 21 days */ + account_policy_set(AP_MAX_PASSWORD_AGE, (uint32)-1); /* don't expire */ account_policy_set(AP_MIN_PASSWORD_AGE, 0); /* 0 days */ account_policy_set(AP_LOCK_ACCOUNT_DURATION, 0); /* lockout for 0 minutes */ account_policy_set(AP_RESET_COUNT_TIME, 0); /* reset immediatly */ diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index 4e9c2c1592..ca5e378970 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -190,8 +190,8 @@ size_t convert_string(charset_t from, charset_t to, break; case E2BIG: reason="No more room"; - DEBUG(0, ("convert_string: Required %d, available %d\n", - srclen, destlen)); + DEBUG(0, ("convert_string: Required %lu, available %lu\n", + (unsigned long)srclen, (unsigned long)destlen)); /* we are not sure we need srclen bytes, may be more, may be less. We only know we need more than destlen @@ -319,8 +319,7 @@ size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen) size_t size; smb_ucs2_t *buffer; - size = convert_string_allocate(CH_UNIX, CH_UCS2, src, srclen, - (void **) &buffer); + size = push_ucs2_allocate(&buffer, src); if (size == -1) { smb_panic("failed to create UCS2 buffer"); } @@ -334,6 +333,33 @@ size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen) return size; } +/** + strdup() a unix string to upper case. +**/ + +char *strdup_upper(const char *s) +{ + size_t size; + smb_ucs2_t *buffer; + char *out_buffer; + + size = push_ucs2_allocate(&buffer, s); + if (size == -1) { + return NULL; + } + + strupper_w(buffer); + + size = pull_ucs2_allocate(&out_buffer, buffer); + SAFE_FREE(buffer); + + if (size == -1) { + return NULL; + } + + return out_buffer; +} + size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen) { size_t size; @@ -353,6 +379,32 @@ size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen) return size; } +/** + strdup() a unix string to lower case. +**/ + +char *strdup_lower(const char *s) +{ + size_t size; + smb_ucs2_t *buffer; + char *out_buffer; + + size = push_ucs2_allocate(&buffer, s); + if (size == -1) { + return NULL; + } + + strlower_w(buffer); + + size = pull_ucs2_allocate(&out_buffer, buffer); + SAFE_FREE(buffer); + + if (size == -1) { + return NULL; + } + + return out_buffer; +} static size_t ucs2_align(const void *base_ptr, const void *p, int flags) { @@ -480,18 +532,11 @@ size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_ { size_t len=0; size_t src_len = strlen(src); - pstring tmpbuf; /* treat a pstring as "unlimited" length */ if (dest_len == (size_t)-1) dest_len = sizeof(pstring); - if (flags & STR_UPPER) { - pstrcpy(tmpbuf, src); - strupper_m(tmpbuf); - src = tmpbuf; - } - if (flags & STR_TERMINATE) src_len++; @@ -506,6 +551,18 @@ size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_ dest_len &= ~1; len += convert_string(CH_UNIX, CH_UCS2, src, src_len, dest, dest_len); + + if (flags & STR_UPPER) { + smb_ucs2_t *dest_ucs2 = dest; + size_t i; + for (i = 0; i < (dest_len / 2) && dest_ucs2[i]; i++) { + smb_ucs2_t v = toupper_w(dest_ucs2[i]); + if (v != dest_ucs2[i]) { + dest_ucs2[i] = v; + } + } + } + return len; } @@ -809,44 +866,3 @@ size_t align_string(const void *base_ptr, const char *p, int flags) return 0; } -/** - Convert from unix to ucs2 charset and return the - allocated and converted string or NULL if an error occurred. - You must provide a zero terminated string. - The returning string will be zero terminated. -**/ - -smb_ucs2_t *acnv_uxu2(const char *src) -{ - size_t slen; - size_t dlen; - void *dest; - - slen = strlen(src) + 1; - dlen = convert_string_allocate(CH_UNIX, CH_UCS2, src, slen, &dest); - if (dlen == (size_t)-1) - return NULL; - else - return dest; -} - -/** - Convert from dos to ucs2 charset and return the - allocated and converted string or NULL if an error occurred. - You must provide a zero terminated string. - The returning string will be zero terminated. -**/ - -smb_ucs2_t *acnv_dosu2(const char *src) -{ - size_t slen; - size_t dlen; - void *dest; - - slen = strlen(src) + 1; - dlen = convert_string_allocate(CH_DOS, CH_UCS2, src, slen, &dest); - if (dlen == (size_t)-1) - return NULL; - else - return dest; -} diff --git a/source3/lib/popt_common.c b/source3/lib/popt_common.c index b8e77b2d9e..af1cbcfe80 100644 --- a/source3/lib/popt_common.c +++ b/source3/lib/popt_common.c @@ -258,19 +258,21 @@ static void get_credentials_file(const char *file, struct user_auth_info *info) * -A,--authentication-file * -k,--use-kerberos * -N,--no-pass + * -S,--signing */ static void popt_common_credentials_callback(poptContext con, - enum poptCallbackReason reason, - const struct poptOption *opt, - const char *arg, const void *data) + enum poptCallbackReason reason, + const struct poptOption *opt, + const char *arg, const void *data) { char *p; if (reason == POPT_CALLBACK_REASON_PRE) { cmdline_auth_info.use_kerberos = False; cmdline_auth_info.got_pass = False; + cmdline_auth_info.signing_state = Undefined; pstrcpy(cmdline_auth_info.username, "GUEST"); if (getenv("LOGNAME"))pstrcpy(cmdline_auth_info.username,getenv("LOGNAME")); @@ -327,6 +329,22 @@ static void popt_common_credentials_callback(poptContext con, cmdline_auth_info.got_pass = True; #endif break; + + case 'S': + { + cmdline_auth_info.signing_state = -1; + if (strequal(arg, "off") || strequal(arg, "no") || strequal(arg, "false")) + cmdline_auth_info.signing_state = False; + else if (strequal(arg, "on") || strequal(arg, "yes") || strequal(arg, "true")) + cmdline_auth_info.signing_state = True; + else if (strequal(arg, "force") || strequal(arg, "required") || strequal(arg, "forced")) + cmdline_auth_info.signing_state = Required; + else { + fprintf(stderr, "Unknown signing option %s\n", arg ); + exit(1); + } + } + break; } } @@ -338,5 +356,6 @@ struct poptOption popt_common_credentials[] = { { "no-pass", 'N', POPT_ARG_NONE, &cmdline_auth_info.got_pass, 0, "Don't ask for a password" }, { "kerberos", 'k', POPT_ARG_NONE, &cmdline_auth_info.use_kerberos, 'k', "Use kerberos (active directory) authentication" }, { "authentication-file", 'A', POPT_ARG_STRING, NULL, 'A', "Get the credentials from a file", "FILE" }, + { "signing", 'S', POPT_ARG_STRING, NULL, 'S', "Set the client signing state", "on|off|required" }, POPT_TABLEEND }; diff --git a/source3/lib/replace.c b/source3/lib/replace.c index 0c62ec9bfa..cd48b8d160 100644 --- a/source3/lib/replace.c +++ b/source3/lib/replace.c @@ -447,21 +447,3 @@ char *rep_inet_ntoa(struct in_addr ip) return t; } #endif - -#ifndef HAVE_SETENV - int setenv(const char *name, const char *value, int overwrite) -{ - char *p = NULL; - int ret = -1; - - asprintf(&p, "%s=%s", name, value); - - if (overwrite || getenv(name)) { - if (p) ret = putenv(p); - } else { - ret = 0; - } - - return ret; -} -#endif diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index 39c1990dec..3f56d066ec 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -5,7 +5,7 @@ Copyright (C) Gerald Carter 2001-2003 Copyright (C) Shahms King 2001 Copyright (C) Andrew Bartlett 2002-2003 - Copyright (C) Stefan (metze) Metzmacher 2002 + Copyright (C) Stefan (metze) Metzmacher 2002-2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -35,6 +35,8 @@ #define SMBLDAP_DONT_PING_TIME 10 /* ping only all 10 seconds */ #define SMBLDAP_NUM_RETRIES 8 /* retry only 8 times */ +#define SMBLDAP_IDLE_TIME 150 /* After 2.5 minutes disconnect */ + /* attributes used by Samba 2.2 */ @@ -925,6 +927,8 @@ int smbldap_search(struct smbldap_state *ldap_state, smbldap_close(ldap_state); } + ldap_state->last_use = time(NULL); + SAFE_FREE(utf8_filter); return rc; } @@ -954,6 +958,8 @@ int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *at smbldap_close(ldap_state); } + ldap_state->last_use = time(NULL); + SAFE_FREE(utf8_dn); return rc; } @@ -983,6 +989,8 @@ int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs smbldap_close(ldap_state); } + ldap_state->last_use = time(NULL); + SAFE_FREE(utf8_dn); return rc; } @@ -1012,6 +1020,8 @@ int smbldap_delete(struct smbldap_state *ldap_state, const char *dn) smbldap_close(ldap_state); } + ldap_state->last_use = time(NULL); + SAFE_FREE(utf8_dn); return rc; } @@ -1041,6 +1051,8 @@ int smbldap_extended_operation(struct smbldap_state *ldap_state, smbldap_close(ldap_state); } + ldap_state->last_use = time(NULL); + return rc; } @@ -1071,6 +1083,24 @@ int smbldap_search_suffix (struct smbldap_state *ldap_state, const char *filter, return rc; } +static void smbldap_idle_fn(void **data, time_t *interval, time_t now) +{ + struct smbldap_state *state = (struct smbldap_state *)(*data); + + if (state->ldap_struct == NULL) { + DEBUG(10,("ldap connection not connected...\n")); + return; + } + + if ((state->last_use+SMBLDAP_IDLE_TIME) > now) { + DEBUG(10,("ldap connection not idle...\n")); + return; + } + + DEBUG(7,("ldap connection idle...closing connection\n")); + smbldap_close(state); +} + /********************************************************************** Housekeeping *********************************************************************/ @@ -1086,6 +1116,8 @@ void smbldap_free_struct(struct smbldap_state **ldap_state) SAFE_FREE((*ldap_state)->bind_dn); SAFE_FREE((*ldap_state)->bind_secret); + smb_unregister_idle_event((*ldap_state)->event_id); + *ldap_state = NULL; /* No need to free any further, as it is talloc()ed */ @@ -1109,6 +1141,16 @@ NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, const char *location, struct smbldap_ } else { (*smbldap_state)->uri = "ldap://localhost"; } + + (*smbldap_state)->event_id = + smb_register_idle_event(smbldap_idle_fn, (void *)(*smbldap_state), + SMBLDAP_IDLE_TIME); + + if ((*smbldap_state)->event_id == SMB_EVENT_ID_INVALID) { + DEBUG(0,("Failed to register LDAP idle event!\n")); + return NT_STATUS_INVALID_HANDLE; + } + return NT_STATUS_OK; } @@ -1155,7 +1197,7 @@ static NTSTATUS add_new_domain_info(struct smbldap_state *ldap_state, DEBUG(3,("Adding new domain\n")); ldap_op = LDAP_MOD_ADD; - snprintf(dn, sizeof(dn), "%s=%s,%s", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), + pstr_sprintf(dn, "%s=%s,%s", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), domain_name, lp_ldap_suffix()); /* Free original search */ @@ -1220,7 +1262,7 @@ NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state, char **attr_list; int count; - snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(%s=%s))", + pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))", LDAP_OBJ_DOMINFO, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), domain_name); diff --git a/source3/lib/snprintf.c b/source3/lib/snprintf.c index 9b9ceb60ca..a2f9f592db 100644 --- a/source3/lib/snprintf.c +++ b/source3/lib/snprintf.c @@ -823,12 +823,10 @@ static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c) * * The logic for these two is that we need our own definition if the * OS *either* has no definition of *sprintf, or if it does have one - * that doesn't work properly according to the autoconf test. Perhaps - * these should really be smb_snprintf to avoid conflicts with buggy - * linkers? -- mbp + * that doesn't work properly according to the autoconf test. */ #if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF) - int snprintf(char *str,size_t count,const char *fmt,...) +int smb_snprintf(char *str,size_t count,const char *fmt,...) { size_t ret; va_list ap; diff --git a/source3/lib/substitute.c b/source3/lib/substitute.c index ac2cf687c4..c0d0096806 100644 --- a/source3/lib/substitute.c +++ b/source3/lib/substitute.c @@ -58,8 +58,8 @@ void set_local_machine_name(const char* local_name, BOOL perm) fstrcpy(tmp_local_machine,local_name); trim_string(tmp_local_machine," "," "); - strlower_m(tmp_local_machine); alpha_strcpy(local_machine,tmp_local_machine,SAFE_NETBIOS_CHARS,sizeof(local_machine)-1); + strlower_m(local_machine); } /** @@ -80,8 +80,8 @@ void set_remote_machine_name(const char* remote_name, BOOL perm) fstrcpy(tmp_remote_machine,remote_name); trim_string(tmp_remote_machine," "," "); - strlower_m(tmp_remote_machine); alpha_strcpy(remote_machine,tmp_remote_machine,SAFE_NETBIOS_CHARS,sizeof(remote_machine)-1); + strlower_m(remote_machine); } const char* get_remote_machine_name(void) diff --git a/source3/lib/sysquotas.c b/source3/lib/sysquotas.c index efc9e65b9d..617f624dae 100644 --- a/source3/lib/sysquotas.c +++ b/source3/lib/sysquotas.c @@ -48,12 +48,6 @@ static int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ switch (qtype) { case SMB_USER_QUOTA_TYPE: - /* we use id.uid == 0 for default quotas */ - if (id.uid == 0) { - ret = 0; - break; - } - if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (CADDR_T)&D))) { return ret; } @@ -88,13 +82,19 @@ static int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ qflags |= QUOTAS_DENY_DISK; } - /* get the default quotas stored in the root's (uid =0) record */ - if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, 0, (CADDR_T)&D))) { - return ret; + ret = 0; + break; +#ifdef HAVE_GROUP_QUOTA + case SMB_GROUP_FS_QUOTA_TYPE: + id.gid = getgid(); + + if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (CADDR_T)&D))==0) { + qflags |= QUOTAS_DENY_DISK; } ret = 0; break; +#endif /* HAVE_GROUP_QUOTA */ default: errno = ENOSYS; return -1; @@ -122,6 +122,7 @@ static int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ { int ret = -1; uint32 qflags = 0; + uint32 oldqflags = 0; struct SYS_DQBLK D; SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE; @@ -146,10 +147,7 @@ static int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ switch (qtype) { case SMB_USER_QUOTA_TYPE: - /* we use id.uid == 0 for default quotas */ - if (id.uid>0) { - ret = quotactl(QCMD(Q_SETQLIM,USRQUOTA), bdev, id.uid, (CADDR_T)&D); - } + ret = quotactl(QCMD(Q_SETQLIM,USRQUOTA), bdev, id.uid, (CADDR_T)&D); break; #ifdef HAVE_GROUP_QUOTA case SMB_GROUP_QUOTA_TYPE: @@ -160,7 +158,7 @@ static int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ /* this stuff didn't work as it should: * switching on/off quota via quotactl() * didn't work! - * So we only set the default limits + * So we just return 0 * --metze * * On HPUX we didn't have the mount path, @@ -168,9 +166,9 @@ static int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ * */ #if 0 - uid = getuid(); + id.uid = getuid(); - ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, uid, (CADDR_T)&D); + ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (CADDR_T)&D); if ((qflags"AS_DENY_DISK)||(qflags"AS_ENABLED)) { if (ret == 0) { @@ -197,14 +195,79 @@ static int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ } DEBUG(0,("vfs_fs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n", - ret,errno,strerror(errno),uid,bdev)); + ret,errno,strerror(errno),id.uid,bdev)); +#else + id.uid = getuid(); + + if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (CADDR_T)&D))==0) { + oldqflags |= QUOTAS_DENY_DISK; + } + + if (oldqflags == qflags) { + ret = 0; + } else { + ret = -1; + } #endif - - /* we use uid == 0 for default quotas */ - ret = quotactl(QCMD(Q_SETQLIM,USRQUOTA), bdev, 0, (CADDR_T)&D); - break; +#ifdef HAVE_GROUP_QUOTA + case SMB_GROUP_FS_QUOTA_TYPE: + /* this stuff didn't work as it should: + * switching on/off quota via quotactl() + * didn't work! + * So we just return 0 + * --metze + * + * On HPUX we didn't have the mount path, + * we need to fix sys_path_to_bdev() + * + */ +#if 0 + id.gid = getgid(); + + ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id, (CADDR_T)&D); + + if ((qflags"AS_DENY_DISK)||(qflags"AS_ENABLED)) { + if (ret == 0) { + char *quota_file = NULL; + + asprintf("a_file,"/%s/%s%s",path, QUOTAFILENAME,GROUPQUOTAFILE_EXTENSION); + if (quota_file == NULL) { + DEBUG(0,("asprintf() failed!\n")); + errno = ENOMEM; + return -1; + } + + ret = quotactl(QCMD(Q_QUOTAON,GRPQUOTA), bdev, -1,(CADDR_T)quota_file); + } else { + ret = 0; + } + } else { + if (ret != 0) { + /* turn off */ + ret = quotactl(QCMD(Q_QUOTAOFF,GRPQUOTA), bdev, -1, (CADDR_T)0); + } else { + ret = 0; + } + } + + DEBUG(0,("vfs_fs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n", + ret,errno,strerror(errno),id.gid,bdev)); +#else + id.gid = getgid(); + + if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (CADDR_T)&D))==0) { + oldqflags |= QUOTAS_DENY_DISK; + } + if (oldqflags == qflags) { + ret = 0; + } else { + ret = -1; + } +#endif + break; +#endif /* HAVE_GROUP_QUOTA */ default: errno = ENOSYS; return -1; @@ -383,7 +446,7 @@ static int sys_path_to_bdev(const char *path, char **mntpath, char **bdev, char ****************************************************************************/ static int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) { - int ret; + int ret = -1; uint32 qflags = 0; SMB_BIG_UINT bsize = (SMB_BIG_UINT)BBSIZE; struct fs_disk_quota D; @@ -399,11 +462,6 @@ static int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ switch (qtype) { case SMB_USER_QUOTA_TYPE: - /* we use id.uid == 0 for default quotas */ - if (id.uid == 0) { - ret = 0; - break; - } if ((ret=quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), bdev, id.uid, (CADDR_T)&D))) return ret; break; @@ -413,10 +471,8 @@ static int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ return ret; break; #endif /* HAVE_GROUP_QUOTA */ - case SMB_USER_FS_QUOTA_TYPE: - /* TODO: get quota status from quotactl() ... */ - if ((ret = quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (CADDR_T)&F))) - return ret; + case SMB_USER_FS_QUOTA_TYPE: + quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (CADDR_T)&F); if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) { qflags |= QUOTAS_DENY_DISK; @@ -425,11 +481,24 @@ static int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ qflags |= QUOTAS_ENABLED; } - /* we use uid == 0 for default quotas */ - if ((ret=quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), bdev, 0, (CADDR_T)&D))) - return ret; + ret = 0; break; +#ifdef HAVE_GROUP_QUOTA + case SMB_GROUP_FS_QUOTA_TYPE: + quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (CADDR_T)&F); + + if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) { + qflags |= QUOTAS_DENY_DISK; + } + else if (F.qs_flags & XFS_QUOTA_UDQ_ACCT) { + qflags |= QUOTAS_ENABLED; + } + + ret = 0; + + break; +#endif /* HAVE_GROUP_QUOTA */ default: errno = ENOSYS; return -1; @@ -481,11 +550,8 @@ static int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ switch (qtype) { case SMB_USER_QUOTA_TYPE: - /* we use uid == 0 for default quotas */ - if (id.uid>0) { - D.d_fieldmask |= FS_DQ_LIMIT_MASK; - ret = quotactl(QCMD(Q_XSETQLIM,USRQUOTA), bdev, id.uid, (CADDR_T)&D); - } + D.d_fieldmask |= FS_DQ_LIMIT_MASK; + ret = quotactl(QCMD(Q_XSETQLIM,USRQUOTA), bdev, id.uid, (CADDR_T)&D); break; #ifdef HAVE_GROUP_QUOTA case SMB_GROUP_QUOTA_TYPE: @@ -494,7 +560,6 @@ static int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ break; #endif /* HAVE_GROUP_QUOTA */ case SMB_USER_FS_QUOTA_TYPE: - /* TODO */ quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (CADDR_T)&F); if (qflags & QUOTAS_DENY_DISK) { @@ -505,6 +570,8 @@ static int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ if (q_on != 0) { ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (CADDR_T)&q_on); + } else { + ret = 0; } } else if (qflags & QUOTAS_ENABLED) { @@ -513,6 +580,8 @@ static int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ if (q_off != 0) { ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (CADDR_T)&q_off); + } else { + ret = 0; } if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT)) @@ -520,6 +589,8 @@ static int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ if (q_on != 0) { ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (CADDR_T)&q_on); + } else { + ret = 0; } } else { #if 0 @@ -533,14 +604,71 @@ static int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ if (q_off !=0) { ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (CADDR_T)&q_off); + } else { + ret = 0; } +#else + ret = -1; #endif } + + break; +#ifdef HAVE_GROUP_QUOTA + case SMB_GROUP_FS_QUOTA_TYPE: + quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (CADDR_T)&F); - /* we use uid == 0 for default quotas */ - D.d_fieldmask |= FS_DQ_LIMIT_MASK; - ret = quotactl(QCMD(Q_XSETQLIM,USRQUOTA), bdev, 0, (CADDR_T)&D); + if (qflags & QUOTAS_DENY_DISK) { + if (!(F.qs_flags & XFS_QUOTA_UDQ_ENFD)) + q_on |= XFS_QUOTA_UDQ_ENFD; + if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT)) + q_on |= XFS_QUOTA_UDQ_ACCT; + + if (q_on != 0) { + ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (CADDR_T)&q_on); + } else { + ret = 0; + } + + } else if (qflags & QUOTAS_ENABLED) { + if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) + q_off |= XFS_QUOTA_UDQ_ENFD; + + if (q_off != 0) { + ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (CADDR_T)&q_off); + } else { + ret = 0; + } + + if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT)) + q_on |= XFS_QUOTA_UDQ_ACCT; + + if (q_on != 0) { + ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (CADDR_T)&q_on); + } else { + ret = 0; + } + } else { +#if 0 + /* Switch on XFS_QUOTA_UDQ_ACCT didn't work! + * only swittching off XFS_QUOTA_UDQ_ACCT work + */ + if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) + q_off |= XFS_QUOTA_UDQ_ENFD; + if (F.qs_flags & XFS_QUOTA_UDQ_ACCT) + q_off |= XFS_QUOTA_UDQ_ACCT; + + if (q_off !=0) { + ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (CADDR_T)&q_off); + } else { + ret = 0; + } +#else + ret = -1; +#endif + } + break; +#endif /* HAVE_GROUP_QUOTA */ default: errno = ENOSYS; return -1; @@ -783,12 +911,17 @@ int sys_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI } if ((ret=sys_path_to_bdev(path,&mntpath,&bdev,&fs))!=0) { + DEBUG(0,("sys_path_to_bdev() failed for path [%s]!\n",path)); return ret; } for (i=0;(fs && sys_quota_backends[i].name && sys_quota_backends[i].get_quota);i++) { if (strcmp(fs,sys_quota_backends[i].name)==0) { ret = sys_quota_backends[i].get_quota(mntpath, bdev, qtype, id, dp); + if (ret!=0) { + DEBUG(10,("sys_get_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n", + fs,mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),ret)); + } ready = True; break; } @@ -796,7 +929,11 @@ int sys_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI if (!ready) { /* use the default vfs quota functions */ - ret = sys_get_vfs_quota(mntpath, bdev, qtype, id, dp); + ret=sys_get_vfs_quota(mntpath, bdev, qtype, id, dp); + if (ret!=0) { + DEBUG(10,("sys_get_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n", + "vfs",mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),ret)); + } } SAFE_FREE(mntpath); @@ -831,12 +968,17 @@ int sys_set_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI } if ((ret=sys_path_to_bdev(path,&mntpath,&bdev,&fs))!=0) { + DEBUG(0,("sys_path_to_bdev() failed for path [%s]!\n",path)); return ret; } for (i=0;(fs && sys_quota_backends[i].name && sys_quota_backends[i].set_quota);i++) { if (strcmp(fs,sys_quota_backends[i].name)==0) { ret = sys_quota_backends[i].set_quota(mntpath, bdev, qtype, id, dp); + if (ret!=0) { + DEBUG(10,("sys_set_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n", + fs,mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),ret)); + } ready = True; break; } @@ -845,6 +987,10 @@ int sys_set_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI if (!ready) { /* use the default vfs quota functions */ ret=sys_set_vfs_quota(mntpath, bdev, qtype, id, dp); + if (ret!=0) { + DEBUG(10,("sys_set_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n", + "vfs",mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),ret)); + } } SAFE_FREE(mntpath); diff --git a/source3/lib/username.c b/source3/lib/username.c index 98b8f33aae..6321d47021 100644 --- a/source3/lib/username.c +++ b/source3/lib/username.c @@ -386,7 +386,7 @@ static BOOL user_in_winbind_group_list(const char *user, const char *gname, BOOL if ( DEBUGLEVEL >= 10 ) { DEBUG(10,("user_in_winbind_group_list: using groups -- ")); for ( i=0; i<num_groups; i++ ) - DEBUGADD(10,("%d ", groups[i])); + DEBUGADD(10,("%lu ", (unsigned long)groups[i])); DEBUGADD(10,("\n")); } @@ -593,7 +593,7 @@ BOOL user_in_list(const char *user,const char **list, gid_t *groups, size_t n_gr will return domain local groups; while NT4 or mixed mode 2k DCs will not */ - if ( winbind_lookup_name(NULL, *list, &g_sid, &name_type) + if ( winbind_lookup_name(domain, groupname, &g_sid, &name_type) && ( name_type==SID_NAME_DOM_GRP || (strequal(lp_workgroup(), domain) && name_type==SID_NAME_ALIAS) ) ) { diff --git a/source3/lib/util.c b/source3/lib/util.c index a7c939fe5a..eaa232a549 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -4,7 +4,7 @@ Copyright (C) Andrew Tridgell 1992-1998 Copyright (C) Jeremy Allison 2001-2002 Copyright (C) Simo Sorce 2001 - Copyright (C) Anthony Liguori 2003 + Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -2247,7 +2247,7 @@ char *pid_path(const char *name) char *lib_path(const char *name) { static pstring fname; - snprintf(fname, sizeof(fname), "%s/%s", dyn_LIBDIR, name); + fstr_sprintf(fname, "%s/%s", dyn_LIBDIR, name); return fname; } diff --git a/source3/lib/util_file.c b/source3/lib/util_file.c index 02acbd4d7e..638a6ca342 100644 --- a/source3/lib/util_file.c +++ b/source3/lib/util_file.c @@ -455,8 +455,8 @@ void *map_file(char *fname, size_t size) p = file_load(fname, &s2); if (!p) return NULL; if (s2 != size) { - DEBUG(1,("incorrect size for %s - got %d expected %d\n", - fname, s2, size)); + DEBUG(1,("incorrect size for %s - got %lu expected %lu\n", + fname, (unsigned long)s2, (unsigned long)size)); if (p) free(p); return NULL; } diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 1bd4c3a96b..b8b8471708 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -289,7 +289,7 @@ ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,un } /**************************************************************************** - read data from the client, reading exactly N bytes. + Read data from the client, reading exactly N bytes. ****************************************************************************/ ssize_t read_data(int fd,char *buffer,size_t N) @@ -397,7 +397,7 @@ static ssize_t write_socket_data(int fd,char *buffer,size_t N) } /**************************************************************************** -write to a socket + Write to a socket. ****************************************************************************/ ssize_t write_socket(int fd,char *buf,size_t len) @@ -416,7 +416,7 @@ ssize_t write_socket(int fd,char *buf,size_t len) } /**************************************************************************** -send a keepalive packet (rfc1002) + Send a keepalive packet (rfc1002). ****************************************************************************/ BOOL send_keepalive(int client) @@ -431,11 +431,11 @@ BOOL send_keepalive(int client) /**************************************************************************** -read 4 bytes of a smb packet and return the smb length of the packet -store the result in the buffer -This version of the function will return a length of zero on receiving -a keepalive packet. -timeout is in milliseconds. + Read 4 bytes of a smb packet and return the smb length of the packet. + Store the result in the buffer. + This version of the function will return a length of zero on receiving + a keepalive packet. + Timeout is in milliseconds. ****************************************************************************/ static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int timeout) @@ -466,10 +466,10 @@ static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int } /**************************************************************************** -read 4 bytes of a smb packet and return the smb length of the packet -store the result in the buffer. This version of the function will -never return a session keepalive (length of zero). -timeout is in milliseconds. + Read 4 bytes of a smb packet and return the smb length of the packet. + Store the result in the buffer. This version of the function will + never return a session keepalive (length of zero). + Timeout is in milliseconds. ****************************************************************************/ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout) @@ -493,11 +493,10 @@ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout) } /**************************************************************************** - read an smb from a fd. Note that the buffer *MUST* be of size - BUFFER_SIZE+SAFETY_MARGIN. - The timeout is in milliseconds. - This function will return on a - receipt of a session keepalive packet. + Read an smb from a fd. Note that the buffer *MUST* be of size + BUFFER_SIZE+SAFETY_MARGIN. + The timeout is in milliseconds. + This function will return on receipt of a session keepalive packet. ****************************************************************************/ BOOL receive_smb(int fd,char *buffer, unsigned int timeout) @@ -553,11 +552,19 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout) } } + /* Check the incoming SMB signature. */ + if (!srv_check_sign_mac(buffer)) { + DEBUG(0, ("receive_smb: SMB Signature verification failed on incoming packet!\n")); + if (smb_read_error == 0) + smb_read_error = READ_BAD_SIG; + return False; + }; + return(True); } /**************************************************************************** - send an smb to a fd + Send an smb to a fd. ****************************************************************************/ BOOL send_smb(int fd,char *buffer) @@ -565,6 +572,10 @@ BOOL send_smb(int fd,char *buffer) size_t len; size_t nwritten=0; ssize_t ret; + + /* Sign the outgoing packet if required. */ + srv_calculate_sign_mac(buffer); + len = smb_len(buffer) + 4; while (nwritten < len) { @@ -647,80 +658,86 @@ int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL reb } /**************************************************************************** - create an outgoing socket. timeout is in milliseconds. - **************************************************************************/ + Create an outgoing socket. timeout is in milliseconds. +**************************************************************************/ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) { - struct sockaddr_in sock_out; - int res,ret; - int connect_loop = 10; - int increment = 10; + struct sockaddr_in sock_out; + int res,ret; + int connect_loop = 10; + int increment = 10; - /* create a socket to write to */ - res = socket(PF_INET, type, 0); - if (res == -1) - { DEBUG(0,("socket error\n")); return -1; } + /* create a socket to write to */ + res = socket(PF_INET, type, 0); + if (res == -1) { + DEBUG(0,("socket error\n")); + return -1; + } - if (type != SOCK_STREAM) return(res); + if (type != SOCK_STREAM) + return(res); - memset((char *)&sock_out,'\0',sizeof(sock_out)); - putip((char *)&sock_out.sin_addr,(char *)addr); + memset((char *)&sock_out,'\0',sizeof(sock_out)); + putip((char *)&sock_out.sin_addr,(char *)addr); - sock_out.sin_port = htons( port ); - sock_out.sin_family = PF_INET; + sock_out.sin_port = htons( port ); + sock_out.sin_family = PF_INET; - /* set it non-blocking */ - set_blocking(res,False); + /* set it non-blocking */ + set_blocking(res,False); - DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port)); + DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port)); - /* and connect it to the destination */ -connect_again: - ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out)); - - /* Some systems return EAGAIN when they mean EINPROGRESS */ - if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || - errno == EAGAIN) && (connect_loop < timeout) ) { - msleep(connect_loop); - connect_loop += increment; - if (increment < 250) { - /* After 8 rounds we end up at a max of 255 msec */ - increment *= 1.5; - } - goto connect_again; - } - - if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || - errno == EAGAIN)) { - DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port)); - close(res); - return -1; - } + /* and connect it to the destination */ + connect_again: + + ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out)); + + /* Some systems return EAGAIN when they mean EINPROGRESS */ + if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || + errno == EAGAIN) && (connect_loop < timeout) ) { + msleep(connect_loop); + connect_loop += increment; + if (increment < 250) { + /* After 8 rounds we end up at a max of 255 msec */ + increment *= 1.5; + } + goto connect_again; + } + + if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || + errno == EAGAIN)) { + DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port)); + close(res); + return -1; + } #ifdef EISCONN - if (ret < 0 && errno == EISCONN) { - errno = 0; - ret = 0; - } + + if (ret < 0 && errno == EISCONN) { + errno = 0; + ret = 0; + } #endif - if (ret < 0) { - DEBUG(2,("error connecting to %s:%d (%s)\n", - inet_ntoa(*addr),port,strerror(errno))); - close(res); - return -1; - } + if (ret < 0) { + DEBUG(2,("error connecting to %s:%d (%s)\n", + inet_ntoa(*addr),port,strerror(errno))); + close(res); + return -1; + } - /* set it blocking again */ - set_blocking(res,True); + /* set it blocking again */ + set_blocking(res,True); - return res; + return res; } -/* - open a connected UDP socket to host on port -*/ +/**************************************************************************** + Open a connected UDP socket to host on port +**************************************************************************/ + int open_udp_socket(const char *host, int port) { int type = SOCK_DGRAM; @@ -783,9 +800,10 @@ struct in_addr *client_inaddr(struct sockaddr *sa) } /******************************************************************* - matchname - determine if host name matches IP address. Used to - confirm a hostname lookup to prevent spoof attacks - ******************************************************************/ + Matchname - determine if host name matches IP address. Used to + confirm a hostname lookup to prevent spoof attacks. +******************************************************************/ + static BOOL matchname(char *remotehost,struct in_addr addr) { struct hostent *hp; @@ -828,10 +846,10 @@ static BOOL matchname(char *remotehost,struct in_addr addr) return False; } - /******************************************************************* - return the DNS name of the remote end of a socket - ******************************************************************/ + Return the DNS name of the remote end of a socket. +******************************************************************/ + char *get_socket_name(int fd, BOOL force_lookup) { static pstring name_buf; @@ -881,8 +899,9 @@ char *get_socket_name(int fd, BOOL force_lookup) } /******************************************************************* - return the IP addr of the remote end of a socket as a string + Return the IP addr of the remote end of a socket as a string. ******************************************************************/ + char *get_socket_addr(int fd) { struct sockaddr sa; @@ -906,7 +925,6 @@ char *get_socket_addr(int fd) return addr_buf; } - /******************************************************************* Create protected unix domain socket. @@ -968,7 +986,7 @@ int create_pipe_sock(const char *socket_dir, goto out_umask; } - snprintf(path, sizeof(path), "%s/%s", socket_dir, socket_name); + pstr_sprintf(path, "%s/%s", socket_dir, socket_name); unlink(path); memset(&sunaddr, 0, sizeof(sunaddr)); diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 96fbc3f124..7569a39e6a 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -181,7 +181,9 @@ int StrCaseCmp(const char *s, const char *t) { const char * ps, * pt; - pstring buf1, buf2; + size_t size; + smb_ucs2_t *buffer_s, *buffer_t; + int ret; for (ps = s, pt = t; ; ps++, pt++) { char us, ut; @@ -206,16 +208,25 @@ int StrCaseCmp(const char *s, const char *t) return +1; } - /* TODO: Don't do this with a fixed-length buffer. This could - * still be much more efficient. */ - /* TODO: Hardcode a char-by-char comparison for UTF-8, which - * can be much faster. */ - /* TODO: Test case for this! */ - - unix_strupper(ps, strlen(ps)+1, buf1, sizeof(buf1)); - unix_strupper(pt, strlen(pt)+1, buf2, sizeof(buf2)); - - return strcmp(buf1, buf2); + size = push_ucs2_allocate(&buffer_s, s); + if (size == (size_t)-1) { + return strcmp(s, t); + /* Not quite the right answer, but finding the right one + under this failure case is expensive, and it's pretty close */ + } + + size = push_ucs2_allocate(&buffer_t, t); + if (size == (size_t)-1) { + SAFE_FREE(buffer_s); + return strcmp(s, t); + /* Not quite the right answer, but finding the right one + under this failure case is expensive, and it's pretty close */ + } + + ret = strcasecmp_w(buffer_s, buffer_t); + SAFE_FREE(buffer_s); + SAFE_FREE(buffer_t); + return ret; } @@ -351,7 +362,7 @@ BOOL strisnormal(const char *s) NOTE: oldc and newc must be 7 bit characters **/ -void string_replace(char *s,char oldc,char newc) +void string_replace(pstring s,char oldc,char newc) { push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE); string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc)); @@ -1156,21 +1167,6 @@ void strlower_m(char *s) } /** - Duplicate convert a string to lower case. -**/ - -char *strdup_lower(const char *s) -{ - char *t = strdup(s); - if (t == NULL) { - DEBUG(0, ("strdup_lower: Out of memory!\n")); - return NULL; - } - strlower_m(t); - return t; -} - -/** Convert a string to upper case. **/ @@ -1195,21 +1191,6 @@ void strupper_m(char *s) } /** - Convert a string to upper case. -**/ - -char *strdup_upper(const char *s) -{ - char *t = strdup(s); - if (t == NULL) { - DEBUG(0, ("strdup_upper: Out of memory!\n")); - return NULL; - } - strupper_m(t); - return t; -} - -/** Return a RFC2254 binary string representation of a buffer. Used in LDAP filters. Caller must free. @@ -1575,7 +1556,7 @@ int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list) count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1; if ( (*ip_list = (struct ip_service*)malloc(count * sizeof(struct ip_service))) == NULL ) { - DEBUG(0,("ipstr_list_parse: malloc failed for %d entries\n", count)); + DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count)); return 0; } diff --git a/source3/lib/util_unistr.c b/source3/lib/util_unistr.c index ae000fba02..fd51f3c57d 100644 --- a/source3/lib/util_unistr.c +++ b/source3/lib/util_unistr.c @@ -759,82 +759,6 @@ smb_ucs2_t *strstr_wa(const smb_ucs2_t *s, const char *ins) return NULL; } -/******************************************************************* -copy a string with max len -********************************************************************/ - -smb_ucs2_t *strncpy_wa(smb_ucs2_t *dest, const char *src, const size_t max) -{ - smb_ucs2_t *ucs2_src; - - if (!dest || !src) return NULL; - if (!(ucs2_src = acnv_uxu2(src))) - return NULL; - - strncpy_w(dest, ucs2_src, max); - SAFE_FREE(ucs2_src); - return dest; -} - -/******************************************************************* -convert and duplicate an ascii string -********************************************************************/ -smb_ucs2_t *strdup_wa(const char *src) -{ - return strndup_wa(src, 0); -} - -/* if len == 0 then duplicate the whole string */ -smb_ucs2_t *strndup_wa(const char *src, size_t len) -{ - smb_ucs2_t *dest, *s; - - s = acnv_dosu2(src); - if (!len) len = strlen_w(s); - dest = (smb_ucs2_t *)malloc((len + 1) * sizeof(smb_ucs2_t)); - if (!dest) { - DEBUG(0,("strdup_w: out of memory!\n")); - SAFE_FREE(s); - return NULL; - } - - memcpy(dest, src, len * sizeof(smb_ucs2_t)); - dest[len] = 0; - - SAFE_FREE(s); - return dest; -} - -/******************************************************************* -append a string of len bytes and add a terminator -********************************************************************/ - -smb_ucs2_t *strncat_wa(smb_ucs2_t *dest, const char *src, const size_t max) -{ - smb_ucs2_t *ucs2_src; - - if (!dest || !src) return NULL; - if (!(ucs2_src = acnv_uxu2(src))) - return NULL; - - strncat_w(dest, ucs2_src, max); - SAFE_FREE(ucs2_src); - return dest; -} - -smb_ucs2_t *strcat_wa(smb_ucs2_t *dest, const char *src) -{ - smb_ucs2_t *ucs2_src; - - if (!dest || !src) return NULL; - if (!(ucs2_src = acnv_uxu2(src))) - return NULL; - - strcat_w(dest, ucs2_src); - SAFE_FREE(ucs2_src); - return dest; -} - BOOL trim_string_wa(smb_ucs2_t *s, const char *front, const char *back) { diff --git a/source3/lib/util_uuid.c b/source3/lib/util_uuid.c index 83553ec28e..56f0ecd85b 100644 --- a/source3/lib/util_uuid.c +++ b/source3/lib/util_uuid.c @@ -2,7 +2,7 @@ * Unix SMB/CIFS implementation. * UUID server routines * Copyright (C) Theodore Ts'o 1996, 1997, - * Copyright (C) Jim McDonough 2002. + * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index c554a02e90..50a9ef2718 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. kerberos authorization data (PAC) utility library - Copyright (C) Jim McDonough 2003 + Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 25b7f9d948..48b61cd1f2 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -60,13 +60,13 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, ZERO_STRUCTP(ap_rep); if (!secrets_init()) { - DEBUG(1,("secrets_init failed\n")); + DEBUG(1,("ads_verify_ticket: secrets_init failed\n")); return NT_STATUS_LOGON_FAILURE; } password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); if (!password_s) { - DEBUG(1,("failed to fetch machine password\n")); + DEBUG(1,("ads_verify_ticket: failed to fetch machine password\n")); return NT_STATUS_LOGON_FAILURE; } @@ -75,13 +75,13 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, ret = krb5_init_context(&context); if (ret) { - DEBUG(1,("krb5_init_context failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_verify_ticket: krb5_init_context failed (%s)\n", error_message(ret))); return NT_STATUS_LOGON_FAILURE; } ret = krb5_set_default_realm(context, ads->auth.realm); if (ret) { - DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_verify_ticket: krb5_set_default_realm failed (%s)\n", error_message(ret))); sret = NT_STATUS_LOGON_FAILURE; goto out; } @@ -92,7 +92,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, ret = krb5_auth_con_init(context, &auth_context); if (ret) { - DEBUG(1,("krb5_auth_con_init failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_verify_ticket: krb5_auth_con_init failed (%s)\n", error_message(ret))); sret = NT_STATUS_LOGON_FAILURE; goto out; } @@ -102,32 +102,31 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm()); ret = krb5_parse_name(context, host_princ_s, &host_princ); if (ret) { - DEBUG(1,("krb5_parse_name(%s) failed (%s)\n", host_princ_s, error_message(ret))); + DEBUG(1,("ads_verify_ticket: krb5_parse_name(%s) failed (%s)\n", + host_princ_s, error_message(ret))); sret = NT_STATUS_LOGON_FAILURE; goto out; } /* - * JRA. We must set the rcache and the allowed addresses in the auth_context - * here. This will prevent replay attacks and ensure the client has got a key from - * the correct IP address. + * JRA. We must set the rcache here. This will prevent replay attacks. */ ret = krb5_get_server_rcache(context, krb5_princ_component(context, host_princ, 0), &rcache); if (ret) { - DEBUG(1,("krb5_get_server_rcache failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_verify_ticket: krb5_get_server_rcache failed (%s)\n", error_message(ret))); sret = NT_STATUS_LOGON_FAILURE; goto out; } ret = krb5_auth_con_setrcache(context, auth_context, rcache); if (ret) { - DEBUG(1,("krb5_auth_con_setrcache failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_verify_ticket: krb5_auth_con_setrcache failed (%s)\n", error_message(ret))); sret = NT_STATUS_LOGON_FAILURE; goto out; } - /* Now we need to add the addresses.... JRA. */ + /* CIFS doesn't use addresses in tickets. This would breat NAT. JRA */ if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { sret = NT_STATUS_NO_MEMORY; @@ -135,13 +134,22 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, } if ((ret = get_kerberos_allowed_etypes(context, &enctypes))) { - DEBUG(1,("krb5_get_permitted_enctypes failed (%s)\n", + DEBUG(1,("ads_verify_ticket: krb5_get_permitted_enctypes failed (%s)\n", error_message(ret))); sret = NT_STATUS_LOGON_FAILURE; goto out; } - /* we need to setup a auth context with each possible encoding type in turn */ + /* Lock a mutex surrounding the replay as there is no locking in the MIT krb5 + * code surrounding the replay cache... */ + + if (!grab_server_mutex("replay cache mutex")) { + DEBUG(1,("ads_verify_ticket: unable to protect replay cache with mutex.\n")); + sret = NT_STATUS_LOGON_FAILURE; + goto out; + } + + /* We need to setup a auth context with each possible encoding type in turn. */ for (i=0;enctypes[i];i++) { if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) { continue; @@ -154,14 +162,22 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, if (!(ret = krb5_rd_req(context, &auth_context, &packet, NULL, keytab, NULL, &tkt))) { + DEBUG(10,("ads_verify_ticket: enc type [%u] decrypted message !\n", + (unsigned int)enctypes[i] )); free_kerberos_etypes(context, enctypes); auth_ok = True; break; } + + DEBUG((ret != KRB5_BAD_ENCTYPE) ? 3 : 10, + ("ads_verify_ticket: enc type [%u] failed to decrypt with error %s\n", + (unsigned int)enctypes[i], error_message(ret))); } + release_server_mutex(); + if (!auth_ok) { - DEBUG(3,("krb5_rd_req with auth failed (%s)\n", + DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n", error_message(ret))); sret = NT_STATUS_LOGON_FAILURE; goto out; @@ -169,7 +185,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, ret = krb5_mk_rep(context, auth_context, &packet); if (ret) { - DEBUG(3,("Failed to generate mutual authentication reply (%s)\n", + DEBUG(3,("ads_verify_ticket: Failed to generate mutual authentication reply (%s)\n", error_message(ret))); sret = NT_STATUS_LOGON_FAILURE; goto out; @@ -178,7 +194,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, *ap_rep = data_blob(packet.data, packet.length); free(packet.data); - get_krb5_smb_session_key(context, auth_context, session_key); + get_krb5_smb_session_key(context, auth_context, session_key, True); #ifdef DEBUG_PASSWORD DEBUG(10,("SMB session key (from ticket) follows:\n")); dump_data(10, session_key, 16); @@ -205,7 +221,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt), principal))) { - DEBUG(3,("krb5_unparse_name failed (%s)\n", + DEBUG(3,("ads_verify_ticket: krb5_unparse_name failed (%s)\n", error_message(ret))); sret = NT_STATUS_LOGON_FAILURE; goto out; diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index cf6f9375f8..5a12288b16 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3,7 +3,7 @@ ads (active directory) utility library Copyright (C) Andrew Tridgell 2001 Copyright (C) Remus Koos 2001 - Copyright (C) Jim McDonough 2002 + Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -106,12 +106,24 @@ static BOOL ads_find_dc(ADS_STRUCT *ads) struct ip_service *ip_list; pstring realm; BOOL got_realm = False; + BOOL use_own_domain = False; + + /* if the realm and workgroup are both empty, assume they are ours */ /* realm */ c_realm = ads->server.realm; + + if ( !c_realm || !*c_realm ) { + /* special case where no realm and no workgroup means our own */ + if ( !ads->server.workgroup || !*ads->server.workgroup ) { + use_own_domain = True; + c_realm = lp_realm(); + } + } + if (c_realm && *c_realm) got_realm = True; - + again: /* we need to try once with the realm name and fallback to the netbios domain name if we fail (if netbios has not been disabled */ @@ -119,7 +131,12 @@ again: if ( !got_realm && !lp_disable_netbios() ) { c_realm = ads->server.workgroup; if (!c_realm || !*c_realm) { - DEBUG(0,("ads_find_dc: no realm or workgroup! Was the structure initialized?\n")); + if ( use_own_domain ) + c_realm = lp_workgroup(); + } + + if ( !c_realm || !*c_realm ) { + DEBUG(0,("ads_find_dc: no realm or workgroup! Don't know what to do\n")); return False; } } @@ -1871,77 +1888,6 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) return ADS_SUCCESS; } - -/** - * find the list of trusted domains - * @param ads connection to ads server - * @param mem_ctx TALLOC_CTX for allocating results - * @param num_trusts pointer to number of trusts - * @param names pointer to trusted domain name list - * @param sids pointer to list of sids of trusted domains - * @return the count of SIDs pulled - **/ -ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, - int *num_trusts, - char ***names, - char ***alt_names, - DOM_SID **sids) -{ - const char *attrs[] = {"name", "flatname", "securityIdentifier", - "trustDirection", NULL}; - ADS_STATUS status; - void *res, *msg; - int count, i; - - *num_trusts = 0; - - status = ads_search(ads, &res, "(objectcategory=trustedDomain)", attrs); - if (!ADS_ERR_OK(status)) return status; - - count = ads_count_replies(ads, res); - if (count == 0) { - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); - } - - (*names) = talloc(mem_ctx, sizeof(char *) * count); - (*alt_names) = talloc(mem_ctx, sizeof(char *) * count); - (*sids) = talloc(mem_ctx, sizeof(DOM_SID) * count); - if (! *names || ! *sids) return ADS_ERROR(LDAP_NO_MEMORY); - - for (i=0, msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { - uint32 direction; - - /* direction is a 2 bit bitfield, 1 means they trust us - but we don't trust them, so we should not list them - as users from that domain can't login */ - if (ads_pull_uint32(ads, msg, "trustDirection", &direction) && - direction == 1) { - continue; - } - - (*names)[i] = ads_pull_string(ads, mem_ctx, msg, "name"); - (*alt_names)[i] = ads_pull_string(ads, mem_ctx, msg, "flatname"); - - if ((*alt_names)[i] && (*alt_names)[i][0]) { - /* we prefer the flatname as the primary name - for consistency with RPC */ - char *name = (*alt_names)[i]; - (*alt_names)[i] = (*names)[i]; - (*names)[i] = name; - } - if (ads_pull_sid(ads, msg, "securityIdentifier", &(*sids)[i])) { - i++; - } - } - - ads_msgfree(ads, res); - - *num_trusts = i; - - return ADS_SUCCESS; -} - /** * find the domain sid for our domain * @param ads connection to ads server diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index b650a5eb38..1448074ea0 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. ads (active directory) printer utility library - Copyright (C) Jim McDonough 2002 + Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index e70249dd78..56a0d8013b 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. ads (active directory) utility library - Copyright (C) Jim McDonough 2002 + Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 598208b17f..910ff3f4dc 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -124,9 +124,10 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip { DATA_BLOB blob; struct berval cred, *scred; + unsigned char sk[16]; int rc; - blob = spnego_gen_negTokenTarg(principal, ads->auth.time_offset); + blob = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, sk); if (!blob.data) { return ADS_ERROR(LDAP_OPERATIONS_ERROR); diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 09d4fbb6c9..576491dd3b 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -322,9 +322,9 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID) asn1_read_uint8(data, &b); oid[0] = 0; - snprintf(el, sizeof(el), "%u", b/40); + fstr_sprintf(el, "%u", b/40); pstrcat(oid, el); - snprintf(el, sizeof(el), " %u", b%40); + fstr_sprintf(el, " %u", b%40); pstrcat(oid, el); while (asn1_tag_remaining(data) > 0) { @@ -333,7 +333,7 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID) asn1_read_uint8(data, &b); v = (v<<7) | (b&0x7f); } while (!data->has_error && b & 0x80); - snprintf(el, sizeof(el), " %u", v); + fstr_sprintf(el, " %u", v); pstrcat(oid, el); } diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index fa9af19bf5..94fe04a480 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -190,7 +190,7 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, char *p; fstring lanman; - snprintf( lanman, sizeof(lanman), "Samba %s", VERSION ); + fstr_sprintf( lanman, "Samba %s", VERSION ); set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); @@ -301,7 +301,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, lm_response = data_blob(NULL, 24); SMBencrypt(pass,cli->secblob.data, lm_response.data); } else { - /* LM disabled, place NT# in LM feild instead */ + /* LM disabled, place NT# in LM field instead */ lm_response = data_blob(nt_response.data, nt_response.length); } @@ -472,6 +472,7 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) /**************************************************************************** Use in-memory credentials cache ****************************************************************************/ + static void use_in_memory_ccache(void) { setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1); } @@ -483,18 +484,23 @@ static void use_in_memory_ccache(void) { static BOOL cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup) { DATA_BLOB blob2, negTokenTarg; - + unsigned char session_key_krb5[16]; + DATA_BLOB null_blob = data_blob(NULL, 0); + DEBUG(2,("Doing kerberos session setup\n")); /* generate the encapsulated kerberos5 ticket */ - negTokenTarg = spnego_gen_negTokenTarg(principal, 0); + negTokenTarg = spnego_gen_negTokenTarg(principal, 0, session_key_krb5); - if (!negTokenTarg.data) return False; + if (!negTokenTarg.data) + return False; #if 0 file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length); #endif + cli_simple_set_signing(cli, session_key_krb5, null_blob); + blob2 = cli_session_setup_blob(cli, negTokenTarg); /* we don't need this blob for kerberos */ @@ -551,7 +557,7 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, blob_in, &blob_out); data_blob_free(&blob_in); if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - DATA_BLOB null = data_blob(NULL, 0); + DATA_BLOB null_blob = data_blob(NULL, 0); if (turn == 1) { /* and wrap it in a SPNEGO wrapper */ msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out); @@ -562,7 +568,7 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, cli_simple_set_signing(cli, ntlmssp_state->session_key.data, - null); + null_blob); /* now send that blob on its way */ if (!cli_session_setup_blob_send(cli, msg1)) { @@ -630,7 +636,7 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, BOOL got_kerberos_mechanism = False; DATA_BLOB blob; - DEBUG(2,("Doing spnego session setup (blob length=%d)\n", cli->secblob.length)); + DEBUG(2,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length)); /* the server might not even do spnego */ if (cli->secblob.length <= 16) { @@ -989,6 +995,11 @@ BOOL cli_negprot(struct cli_state *cli) cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; + if ((cli->protocol < PROTOCOL_NT1) && cli->sign_info.mandatory_signing) { + DEBUG(1,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n")); + return False; + } + if (cli->protocol >= PROTOCOL_NT1) { /* NT protocol */ cli->sec_mode = CVAL(cli->inbuf,smb_vwv1); @@ -1015,7 +1026,7 @@ BOOL cli_negprot(struct cli_state *cli) if ((cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED)) { /* Fail if signing is mandatory and we don't want to support it. */ - if (!lp_client_signing()) { + if (!cli->sign_info.allow_smb_signing) { DEBUG(1,("cli_negprot: SMB signing is mandatory and we have disabled it.\n")); return False; } @@ -1248,6 +1259,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, const char *service, const char *service_type, const char *user, const char *domain, const char *password, int flags, + int signing_state, BOOL *retry) { struct ntuser_creds creds; @@ -1310,6 +1322,8 @@ again: return NT_STATUS_UNSUCCESSFUL; } + cli_setup_signing_state(cli, signing_state); + if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO) cli->use_spnego = False; else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) @@ -1480,7 +1494,7 @@ struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip, nt_status = cli_full_connection(&cli, myname, server, server_ip, 0, "IPC$", "IPC", user_info->username, lp_workgroup(), user_info->password, - CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK, NULL); + CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK, Undefined, NULL); if (NT_STATUS_IS_OK(nt_status)) { return cli; diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 58c5ad8cd3..bc5f1462cc 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -141,7 +141,7 @@ BOOL cli_send_smb(struct cli_state *cli) if (cli->fd == -1) return False; - cli_caclulate_sign_mac(cli); + cli_calculate_sign_mac(cli); len = smb_len(cli->outbuf) + 4; @@ -157,6 +157,10 @@ BOOL cli_send_smb(struct cli_state *cli) } nwritten += ret; } + /* Increment the mid so we can tell between responses. */ + cli->mid++; + if (!cli->mid) + cli->mid++; return True; } @@ -209,6 +213,27 @@ void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) } /**************************************************************************** + Set the signing state (used from the command line). +****************************************************************************/ + +void cli_setup_signing_state(struct cli_state *cli, int signing_state) +{ + if (signing_state == Undefined) + return; + + if (signing_state == False) { + cli->sign_info.allow_smb_signing = False; + cli->sign_info.mandatory_signing = False; + return; + } + + cli->sign_info.allow_smb_signing = True; + + if (signing_state == Required) + cli->sign_info.mandatory_signing = True; +} + +/**************************************************************************** Initialise a client structure. ****************************************************************************/ diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 9ee181a90f..c27e1955e2 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -108,7 +108,7 @@ const char *cli_errstr(struct cli_state *cli) break; case READ_BAD_SIG: slprintf(cli_error_message, sizeof(cli_error_message) - 1, - "Server packet had invalid SMB signiture!"); + "Server packet had invalid SMB signature!"); break; default: slprintf(cli_error_message, sizeof(cli_error_message) - 1, @@ -371,6 +371,9 @@ BOOL cli_is_error(struct cli_state *cli) { uint32 flgs2 = SVAL(cli->inbuf,smb_flg2), rcls = 0; + if (cli->fd == -1 && cli->smb_rw_error != 0) + return True; + if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { /* Return error is error bits are set */ rcls = IVAL(cli->inbuf, smb_rcls); diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index fd5dd91325..beac8cb2c1 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -305,7 +305,7 @@ cleanup_princ: /* get a kerberos5 ticket for the given service */ -DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset) +DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, unsigned char session_key_krb5[16]) { krb5_error_code retval; krb5_data packet; @@ -345,13 +345,15 @@ DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset) } if ((retval = ads_krb5_mk_req(context, - &auth_context, - 0, - principal, - ccdef, &packet))) { + &auth_context, + AP_OPTS_USE_SUBKEY, + principal, + ccdef, &packet))) { goto failed; } + get_krb5_smb_session_key(context, auth_context, session_key_krb5, False); + ret = data_blob(packet.data, packet.length); /* Hmm, heimdal dooesn't have this - what's the correct call? */ /* krb5_free_data_contents(context, &packet); */ @@ -365,17 +367,22 @@ failed: return data_blob(NULL, 0); } - BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16]) + BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16], BOOL remote) { #ifdef ENCTYPE_ARCFOUR_HMAC krb5_keyblock *skey; #endif BOOL ret = False; + krb5_error_code err; memset(session_key, 0, 16); #ifdef ENCTYPE_ARCFOUR_HMAC - if (krb5_auth_con_getremotesubkey(context, auth_context, &skey) == 0 && skey != NULL) { + if (remote) + err = krb5_auth_con_getremotesubkey(context, auth_context, &skey); + else + err = krb5_auth_con_getlocalsubkey(context, auth_context, &skey); + if (err == 0 && skey != NULL) { if (KRB5_KEY_TYPE(skey) == ENCTYPE_ARCFOUR_HMAC && KRB5_KEY_LENGTH(skey) == 16) { @@ -388,9 +395,22 @@ failed: return ret; } + + +#if defined(HAVE_KRB5_PRINCIPAL_GET_COMP_STRING) && !defined(HAVE_KRB5_PRINC_COMPONENT) + const krb5_data *krb5_princ_component(krb5_context context, krb5_principal principal, int i ) +{ + static krb5_data kdata; + + kdata.data = krb5_principal_get_comp_string(context, principal, i); + kdata.length = strlen(kdata.data); + return &kdata; +} +#endif + #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ -DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset) +DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, unsigned char session_key_krb5[16]) { DEBUG(0,("NO KERBEROS SUPPORT\n")); return data_blob(NULL, 0); diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 5bd1283ab7..7822987ada 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -101,13 +101,20 @@ static int interpret_long_filename(struct cli_state *cli, cheap to calculate, I suppose, as no DST tables will be needed */ - finfo->ctime = interpret_long_date(p); p += 8; - finfo->atime = interpret_long_date(p); p += 8; - finfo->mtime = interpret_long_date(p); p += 8; p += 8; - finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0); p += 8; + finfo->ctime = interpret_long_date(p); + p += 8; + finfo->atime = interpret_long_date(p); + p += 8; + finfo->mtime = interpret_long_date(p); + p += 8; + p += 8; + finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0); + p += 8; p += 8; /* alloc size */ - finfo->mode = CVAL(p,0); p += 4; - namelen = IVAL(p,0); p += 4; + finfo->mode = CVAL(p,0); + p += 4; + namelen = IVAL(p,0); + p += 4; p += 4; /* EA size */ slen = SVAL(p, 0); p += 2; @@ -138,7 +145,11 @@ static int interpret_long_filename(struct cli_state *cli, int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(file_info *, const char *, void *), void *state) { +#if 0 + int max_matches = 1366; /* Match W2k - was 512. */ +#else int max_matches = 512; +#endif int info_level; char *p, *p2; pstring mask; @@ -200,7 +211,12 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, &setup, 1, 0, /* setup, length, max */ param, param_len, 10, /* param, length, max */ NULL, 0, - cli->max_xmit /* data, length, max */ +#if 0 + /* w2k value. */ + MIN(16384,cli->max_xmit) /* data, length, max. */ +#else + cli->max_xmit /* data, length, max. */ +#endif )) { break; } @@ -214,7 +230,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, uint8 eclass; uint32 ecode; cli_dos_error(cli, &eclass, &ecode); - if (eclass != ERRSRV || ecode != ERRerror) break; + if (eclass != ERRSRV || ecode != ERRerror) + break; msleep(100); continue; } @@ -222,7 +239,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, if (cli_is_error(cli) || !rdata || !rparam) break; - if (total_received == -1) total_received = 0; + if (total_received == -1) + total_received = 0; /* parse out some important return info */ p = rparam; @@ -245,8 +263,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* we might need the lastname for continuations */ if (ff_lastname > 0) { - switch(info_level) - { + switch(info_level) { case 260: clistr_pull(cli, mask, p+ff_lastname, sizeof(mask), @@ -270,8 +287,9 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, if (!tdl) { DEBUG(0,("cli_list_new: Failed to expand dirlist\n")); break; + } else { + dirlist = tdl; } - else dirlist = tdl; /* put in a length for the last entry, to ensure we can chain entries into the next packet */ @@ -291,7 +309,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, DEBUG(3,("received %d entries (eos=%d)\n", ff_searchcount,ff_eos)); - if (ff_searchcount > 0) loop_count = 0; + if (ff_searchcount > 0) + loop_count = 0; First = False; } diff --git a/source3/libsmb/cliprint.c b/source3/libsmb/cliprint.c index bfa33bc514..f302c045a5 100644 --- a/source3/libsmb/cliprint.c +++ b/source3/libsmb/cliprint.c @@ -65,16 +65,16 @@ int cli_print_queue(struct cli_state *cli, p = param; SSVAL(p,0,76); /* API function number 76 (DosPrintJobEnum) */ p += 2; - pstrcpy(p,"zWrLeh"); /* parameter description? */ + pstrcpy_base(p,"zWrLeh", param); /* parameter description? */ p = skip_string(p,1); - pstrcpy(p,"WWzWWDDzz"); /* returned data format */ + pstrcpy_base(p,"WWzWWDDzz", param); /* returned data format */ p = skip_string(p,1); - pstrcpy(p,cli->share); /* name of queue */ + pstrcpy_base(p,cli->share, param); /* name of queue */ p = skip_string(p,1); SSVAL(p,0,2); /* API function level 2, PRJINFO_2 data structure */ SSVAL(p,2,1000); /* size of bytes of returned data buffer */ p += 4; - pstrcpy(p,""); /* subformat */ + pstrcpy_base(p,"", param); /* subformat */ p = skip_string(p,1); DEBUG(4,("doing cli_print_queue for %s\n", cli->share)); @@ -133,9 +133,9 @@ int cli_printjob_del(struct cli_state *cli, int job) p = param; SSVAL(p,0,81); /* DosPrintJobDel() */ p += 2; - pstrcpy(p,"W"); + pstrcpy_base(p,"W", param); p = skip_string(p,1); - pstrcpy(p,""); + pstrcpy_base(p,"", param); p = skip_string(p,1); SSVAL(p,0,job); p += 2; diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index bb48f57915..b0570b09b6 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. simple kerberos5/SPNEGO routines Copyright (C) Andrew Tridgell 2001 - Copyright (C) Jim McDonough 2002 + Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002 Copyright (C) Luke Howard 2003 This program is free software; you can redistribute it and/or modify @@ -323,13 +323,13 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY kerberos session setup */ -DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset) +DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset, unsigned char session_key_krb5[16]) { DATA_BLOB tkt, tkt_wrapped, targ; const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; - /* get a kerberos ticket for the service */ - tkt = cli_krb5_get_ticket(principal, time_offset); + /* get a kerberos ticket for the service and extract the session key */ + tkt = cli_krb5_get_ticket(principal, time_offset, session_key_krb5); /* wrap that up in a nice GSS-API wrapping */ tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 3d3cd427d7..e6771ac688 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -40,6 +40,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, char *outdata,*outparam; char *p; int pipe_name_len=0; + uint16 mid; this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); @@ -49,6 +50,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, SCVAL(cli->outbuf,smb_com,trans); SSVAL(cli->outbuf,smb_tid, cli->cnum); cli_setup_packet(cli); + mid = cli->mid; if (pipe_name) { pipe_name_len = clistr_push(cli, smb_buf(cli->outbuf), pipe_name, -1, STR_TERMINATE); @@ -84,13 +86,19 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); - if (!cli_send_smb(cli)) + + cli_signing_trans_start(cli); + if (!cli_send_smb(cli)) { + cli_signing_trans_stop(cli); return False; + } if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ - if (!cli_receive_smb(cli) || cli_is_error(cli)) + if (!cli_receive_smb(cli) || cli_is_error(cli)) { + cli_signing_trans_stop(cli); return(False); + } tot_data = this_ldata; tot_param = this_lparam; @@ -122,9 +130,15 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, memcpy(outdata,data+tot_data,this_ldata); cli_setup_bcc(cli, outdata+this_ldata); + /* Ensure this packet has the same MID as + * the primary. Important in signing. JRA. */ + cli->mid = mid; + show_msg(cli->outbuf); - if (!cli_send_smb(cli)) + if (!cli_send_smb(cli)) { + cli_signing_trans_stop(cli); return False; + } tot_data += this_ldata; tot_param += this_lparam; @@ -151,8 +165,10 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, *data_len = *param_len = 0; - if (!cli_receive_smb(cli)) + if (!cli_receive_smb(cli)) { + cli_signing_trans_stop(cli); return False; + } show_msg(cli->inbuf); @@ -161,6 +177,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, DEBUG(0,("Expected %s response, got command 0x%02x\n", trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(cli->inbuf,smb_com))); + cli_signing_trans_stop(cli); return(False); } @@ -171,8 +188,10 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, */ status = cli_nt_error(cli); - if (NT_STATUS_IS_ERR(status)) + if (NT_STATUS_IS_ERR(status)) { + cli_signing_trans_stop(cli); return False; + } /* parse out the lengths */ total_data = SVAL(cli->inbuf,smb_tdrcnt); @@ -183,6 +202,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, tdata = Realloc(*data,total_data); if (!tdata) { DEBUG(0,("cli_receive_trans: failed to enlarge data buffer\n")); + cli_signing_trans_stop(cli); return False; } else @@ -193,6 +213,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, tparam = Realloc(*param,total_param); if (!tparam) { DEBUG(0,("cli_receive_trans: failed to enlarge param buffer\n")); + cli_signing_trans_stop(cli); return False; } else @@ -206,6 +227,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, if (this_data + *data_len > total_data || this_param + *param_len > total_param) { DEBUG(1,("Data overflow in cli_receive_trans\n")); + cli_signing_trans_stop(cli); return False; } @@ -214,6 +236,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, this_param + *param_len < this_param || this_param + *param_len < *param_len) { DEBUG(1,("Data overflow in cli_receive_trans\n")); + cli_signing_trans_stop(cli); return False; } @@ -226,6 +249,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, data_offset_out + this_data < data_offset_out || data_offset_out + this_data < this_data) { DEBUG(1,("Data overflow in cli_receive_trans\n")); + cli_signing_trans_stop(cli); return False; } if (data_offset_in > cli->bufsize || @@ -233,6 +257,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, data_offset_in + this_data < data_offset_in || data_offset_in + this_data < this_data) { DEBUG(1,("Data overflow in cli_receive_trans\n")); + cli_signing_trans_stop(cli); return False; } @@ -247,6 +272,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, param_offset_out + this_param < param_offset_out || param_offset_out + this_param < this_param) { DEBUG(1,("Param overflow in cli_receive_trans\n")); + cli_signing_trans_stop(cli); return False; } if (param_offset_in > cli->bufsize || @@ -254,6 +280,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, param_offset_in + this_param < param_offset_in || param_offset_in + this_param < this_param) { DEBUG(1,("Param overflow in cli_receive_trans\n")); + cli_signing_trans_stop(cli); return False; } @@ -265,8 +292,10 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, if (total_data <= *data_len && total_param <= *param_len) break; - if (!cli_receive_smb(cli)) - return False; + if (!cli_receive_smb(cli)) { + cli_signing_trans_stop(cli); + return False; + } show_msg(cli->inbuf); @@ -275,9 +304,11 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, DEBUG(0,("Expected %s response, got command 0x%02x\n", trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(cli->inbuf,smb_com))); + cli_signing_trans_stop(cli); return(False); } if (NT_STATUS_IS_ERR(cli_nt_error(cli))) { + cli_signing_trans_stop(cli); return(False); } @@ -292,6 +323,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, } + cli_signing_trans_stop(cli); return(True); } @@ -309,6 +341,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli, unsigned int i; unsigned int this_ldata,this_lparam; unsigned int tot_data=0,tot_param=0; + uint16 mid; char *outdata,*outparam; this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ @@ -319,6 +352,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli, SCVAL(cli->outbuf,smb_com,SMBnttrans); SSVAL(cli->outbuf,smb_tid, cli->cnum); cli_setup_packet(cli); + mid = cli->mid; outparam = smb_buf(cli->outbuf)+3; outdata = outparam+this_lparam; @@ -347,13 +381,18 @@ BOOL cli_send_nt_trans(struct cli_state *cli, cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); - if (!cli_send_smb(cli)) + cli_signing_trans_start(cli); + if (!cli_send_smb(cli)) { + cli_signing_trans_stop(cli); return False; + } if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ - if (!cli_receive_smb(cli) || cli_is_error(cli)) + if (!cli_receive_smb(cli) || cli_is_error(cli)) { + cli_signing_trans_stop(cli); return(False); + } tot_data = this_ldata; tot_param = this_lparam; @@ -384,9 +423,16 @@ BOOL cli_send_nt_trans(struct cli_state *cli, memcpy(outdata,data+tot_data,this_ldata); cli_setup_bcc(cli, outdata+this_ldata); + /* Ensure this packet has the same MID as + * the primary. Important in signing. JRA. */ + cli->mid = mid; + show_msg(cli->outbuf); - if (!cli_send_smb(cli)) + + if (!cli_send_smb(cli)) { + cli_signing_trans_stop(cli); return False; + } tot_data += this_ldata; tot_param += this_lparam; @@ -396,8 +442,6 @@ BOOL cli_send_nt_trans(struct cli_state *cli, return(True); } - - /**************************************************************************** receive a SMB nttrans response allocating the necessary memory ****************************************************************************/ @@ -416,8 +460,10 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, *data_len = *param_len = 0; - if (!cli_receive_smb(cli)) + if (!cli_receive_smb(cli)) { + cli_signing_trans_stop(cli); return False; + } show_msg(cli->inbuf); @@ -425,6 +471,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (CVAL(cli->inbuf,smb_com) != SMBnttrans) { DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n", CVAL(cli->inbuf,smb_com))); + cli_signing_trans_stop(cli); return(False); } @@ -435,8 +482,10 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, */ if (cli_is_dos_error(cli)) { cli_dos_error(cli, &eclass, &ecode); - if (cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) + if (cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) { + cli_signing_trans_stop(cli); return(False); + } } /* parse out the lengths */ @@ -448,6 +497,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, tdata = Realloc(*data,total_data); if (!tdata) { DEBUG(0,("cli_receive_nt_trans: failed to enlarge data buffer to %d\n",total_data)); + cli_signing_trans_stop(cli); return False; } else { *data = tdata; @@ -458,6 +508,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, tparam = Realloc(*param,total_param); if (!tparam) { DEBUG(0,("cli_receive_nt_trans: failed to enlarge param buffer to %d\n", total_param)); + cli_signing_trans_stop(cli); return False; } else { *param = tparam; @@ -471,6 +522,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (this_data + *data_len > total_data || this_param + *param_len > total_param) { DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); + cli_signing_trans_stop(cli); return False; } @@ -479,6 +531,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, this_param + *param_len < this_param || this_param + *param_len < *param_len) { DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); + cli_signing_trans_stop(cli); return False; } @@ -491,6 +544,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, data_offset_out + this_data < data_offset_out || data_offset_out + this_data < this_data) { DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); + cli_signing_trans_stop(cli); return False; } if (data_offset_in > cli->bufsize || @@ -498,6 +552,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, data_offset_in + this_data < data_offset_in || data_offset_in + this_data < this_data) { DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); + cli_signing_trans_stop(cli); return False; } @@ -513,6 +568,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, param_offset_out + this_param < param_offset_out || param_offset_out + this_param < this_param) { DEBUG(1,("Param overflow in cli_receive_nt_trans\n")); + cli_signing_trans_stop(cli); return False; } if (param_offset_in > cli->bufsize || @@ -520,6 +576,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, param_offset_in + this_param < param_offset_in || param_offset_in + this_param < this_param) { DEBUG(1,("Param overflow in cli_receive_nt_trans\n")); + cli_signing_trans_stop(cli); return False; } @@ -532,8 +589,10 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (total_data <= *data_len && total_param <= *param_len) break; - if (!cli_receive_smb(cli)) + if (!cli_receive_smb(cli)) { + cli_signing_trans_stop(cli); return False; + } show_msg(cli->inbuf); @@ -541,13 +600,15 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (CVAL(cli->inbuf,smb_com) != SMBnttrans) { DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n", CVAL(cli->inbuf,smb_com))); + cli_signing_trans_stop(cli); return(False); } if (cli_is_dos_error(cli)) { cli_dos_error(cli, &eclass, &ecode); - if(cli->nt_pipe_fnum == 0 || - !(eclass == ERRDOS && ecode == ERRmoredata)) + if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) { + cli_signing_trans_stop(cli); return(False); + } } /* parse out the total lengths again - they can shrink! */ if (SVAL(cli->inbuf,smb_ntr_TotalDataCount) < total_data) @@ -559,5 +620,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, break; } + cli_signing_trans_stop(cli); return(True); } diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 8ee5ee3d31..3d99e3d5e5 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -1498,6 +1498,7 @@ const struct unix_error_map unix_dos_nt_errmap[] = { { ENFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES }, { EMFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES }, { ENOSPC, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, + { ENOMEM, ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY }, #ifdef EDQUOT { EDQUOT, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, #endif diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 157a2bb43c..6ee05f0104 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1129,12 +1129,14 @@ char *dns_to_netbios_name(char *dns_name) /**************************************************************************** -interpret the weird netbios "name". Return the name type +interpret the weird netbios "name" into a unix fstring. Return the name type ****************************************************************************/ -static int name_interpret(char *in,char *out) +static int name_interpret(char *in, fstring name) { int ret; int len = (*in++) / 2; + fstring out_string; + char *out = out_string; *out=0; @@ -1150,8 +1152,8 @@ static int name_interpret(char *in,char *out) in += 2; out++; } - *out = 0; ret = out[-1]; + out[-1] = 0; #ifdef NETBIOS_SCOPE /* Handle any scope names */ @@ -1165,6 +1167,8 @@ static int name_interpret(char *in,char *out) in += len; } #endif + pull_ascii(name, out_string, sizeof(fstring), sizeof(out_string), STR_TERMINATE); + return(ret); } @@ -1245,9 +1249,9 @@ static char *name_ptr(char *buf,int ofs) } /**************************************************************************** -extract a netbios name from a buf +extract a netbios name from a buf (into a unix string) return name type ****************************************************************************/ -int name_extract(char *buf,int ofs,char *name) +int name_extract(char *buf,int ofs, fstring name) { char *p = name_ptr(buf,ofs); int d = PTR_DIFF(p,buf+ofs); diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 66dc6e08eb..a50ae9b70f 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -279,8 +279,8 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, data_blob_free(&sess_key); - DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%d len2=%d\n", - ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, ntlmssp_state->lm_resp.length, ntlmssp_state->nt_resp.length)); + DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n", + ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length)); #if 0 file_save("nthash1.dat", &ntlmssp_state->nt_resp.data, &ntlmssp_state->nt_resp.length); diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c index f53afcdcd0..3c6da349e4 100644 --- a/source3/libsmb/ntlmssp_parse.c +++ b/source3/libsmb/ntlmssp_parse.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. simple kerberos5/SPNEGO routines Copyright (C) Andrew Tridgell 2001 - Copyright (C) Jim McDonough 2002 + Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002 Copyright (C) Andrew Bartlett 2002-2003 This program is free software; you can redistribute it and/or modify diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index 748c008963..ecaef808c9 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -102,7 +102,7 @@ enum ntlmssp_direction { NTLMSSP_RECEIVE }; -static NTSTATUS ntlmssp_make_packet_signiture(NTLMSSP_CLIENT_STATE *ntlmssp_state, +static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_CLIENT_STATE *ntlmssp_state, const uchar *data, size_t length, enum ntlmssp_direction direction, DATA_BLOB *sig) @@ -148,7 +148,7 @@ NTSTATUS ntlmssp_client_sign_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, const uchar *data, size_t length, DATA_BLOB *sig) { - NTSTATUS nt_status = ntlmssp_make_packet_signiture(ntlmssp_state, data, length, NTLMSSP_SEND, sig); + NTSTATUS nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, length, NTLMSSP_SEND, sig); /* increment counter on send */ ntlmssp_state->ntlmssp_seq_num++; @@ -169,11 +169,11 @@ NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, NTSTATUS nt_status; if (sig->length < 8) { - DEBUG(0, ("NTLMSSP packet check failed due to short signiture (%u bytes)!\n", + DEBUG(0, ("NTLMSSP packet check failed due to short signature (%u bytes)!\n", sig->length)); } - nt_status = ntlmssp_make_packet_signiture(ntlmssp_state, data, + nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, length, NTLMSSP_RECEIVE, &local_sig); if (!NT_STATUS_IS_OK(nt_status)) { @@ -188,7 +188,7 @@ NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, DEBUG(5, ("BAD SIG: got signature of\n")); dump_data(5, sig->data, sig->length); - DEBUG(0, ("NTLMSSP packet check failed due to invalid signiture!\n")); + DEBUG(0, ("NTLMSSP packet check failed due to invalid signature!\n")); return NT_STATUS_ACCESS_DENIED; } @@ -328,7 +328,7 @@ NTSTATUS ntlmssp_client_sign_init(NTLMSSP_CLIENT_STATE *ntlmssp_state) } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { if (!ntlmssp_state->session_key.data || ntlmssp_state->session_key.length < 8) { - /* can't sign or check signitures yet */ + /* can't sign or check signatures yet */ DEBUG(5, ("NTLMSSP Sign/Seal - cannot use LM KEY yet\n")); return NT_STATUS_UNSUCCESSFUL; } @@ -340,7 +340,7 @@ NTSTATUS ntlmssp_client_sign_init(NTLMSSP_CLIENT_STATE *ntlmssp_state) sizeof(ntlmssp_state->ntlmssp_hash)); } else { if (!ntlmssp_state->session_key.data || ntlmssp_state->session_key.length < 16) { - /* can't sign or check signitures yet */ + /* can't sign or check signatures yet */ DEBUG(5, ("NTLMSSP Sign/Seal - cannot use NT KEY yet\n")); return NT_STATUS_UNSUCCESSFUL; } diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index d4f77bf07c..4167452953 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. SMB Signing Code - Copyright (C) Jeremy Allison 2002. + Copyright (C) Jeremy Allison 2003. Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003 This program is free software; you can redistribute it and/or modify @@ -28,9 +28,17 @@ struct outstanding_packet_lookup { struct outstanding_packet_lookup *prev, *next; }; +/* Store the data for an ongoing trans/trans2/nttrans operation. */ +struct trans_info_context { + uint16 mid; + uint32 send_seq_num; + uint32 reply_seq_num; +}; + struct smb_basic_signing_context { DATA_BLOB mac_key; uint32 send_seq_num; + struct trans_info_context *trans_info; struct outstanding_packet_lookup *outstanding_packet_list; }; @@ -46,6 +54,8 @@ static void store_sequence_for_reply(struct outstanding_packet_lookup **list, DLIST_ADD_END(*list, t, tmp); t->mid = mid; t->reply_seq_num = reply_seq_num; + DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n", + (unsigned int)reply_seq_num, (unsigned int)mid )); } static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, @@ -56,12 +66,13 @@ static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, for (t = *list; t; t = t->next) { if (t->mid == mid) { *reply_seq_num = t->reply_seq_num; + DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n", + (unsigned int)t->reply_seq_num, (unsigned int)t->mid )); DLIST_REMOVE(*list, t); + SAFE_FREE(t); return True; } } - DEBUG(0, ("Unexpected incoming packet, it's MID (%u) does not match" - " a MID in our outstanding list!\n", mid)); return False; } @@ -81,7 +92,7 @@ static BOOL cli_set_smb_signing_common(struct cli_state *cli) } if (cli->sign_info.free_signing_context) - cli->sign_info.free_signing_context(cli); + cli->sign_info.free_signing_context(&cli->sign_info); /* These calls are INCOMPATIBLE with SMB signing */ cli->readbraw_supported = False; @@ -94,42 +105,107 @@ static BOOL cli_set_smb_signing_common(struct cli_state *cli) SMB signing - Common code for 'real' implementations ************************************************************/ -static BOOL cli_set_smb_signing_real_common(struct cli_state *cli) +static BOOL set_smb_signing_real_common(struct smb_sign_info *si) { - if (cli->sign_info.mandatory_signing) { + if (si->mandatory_signing) { DEBUG(5, ("Mandatory SMB signing enabled!\n")); - cli->sign_info.doing_signing = True; } + si->doing_signing = True; DEBUG(5, ("SMB signing enabled!\n")); return True; } -static void cli_mark_packet_signed(struct cli_state *cli) +static void mark_packet_signed(char *outbuf) { uint16 flags2; - flags2 = SVAL(cli->outbuf,smb_flg2); + flags2 = SVAL(outbuf,smb_flg2); flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; - SSVAL(cli->outbuf,smb_flg2, flags2); + SSVAL(outbuf,smb_flg2, flags2); +} + +/*********************************************************** + SMB signing - NULL implementation - calculate a MAC to send. +************************************************************/ + +static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) +{ + /* we can't zero out the sig, as we might be trying to send a + session request - which is NBT-level, not SMB level and doesn't + have the field */ + return; +} + +/*********************************************************** + SMB signing - NULL implementation - check a MAC sent by server. +************************************************************/ + +static BOOL null_check_incoming_message(char *inbuf, struct smb_sign_info *si) +{ + return True; } -static BOOL cli_signing_good(struct cli_state *cli, BOOL good) +/*********************************************************** + SMB signing - NULL implementation - free signing context +************************************************************/ + +static void null_free_signing_context(struct smb_sign_info *si) { - DEBUG(10, ("got SMB signature of\n")); - dump_data(10,&cli->inbuf[smb_ss_field] , 8); + return; +} - if (good && !cli->sign_info.doing_signing) { - cli->sign_info.doing_signing = True; +/** + SMB signing - NULL implementation - setup the MAC key. + + @note Used as an initialisation only - it will not correctly + shut down a real signing mechanism +*/ + +static BOOL null_set_signing(struct smb_sign_info *si) +{ + si->signing_context = NULL; + + si->sign_outgoing_message = null_sign_outgoing_message; + si->check_incoming_message = null_check_incoming_message; + si->free_signing_context = null_free_signing_context; + + return True; +} + +/** + * Free the signing context + */ + +static void free_signing_context(struct smb_sign_info *si) +{ + if (si->free_signing_context) { + si->free_signing_context(si); + si->signing_context = NULL; + } + + null_set_signing(si); +} + + +static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good) +{ + if (good && !si->doing_signing) { + si->doing_signing = True; } if (!good) { - if (cli->sign_info.doing_signing) { - DEBUG(1, ("SMB signature check failed!\n")); + if (si->doing_signing) { + struct smb_basic_signing_context *data = si->signing_context; + + /* W2K sends a bad first signature but the sign engine is on.... JRA. */ + if (data->send_seq_num > 1) + DEBUG(1, ("signing_good: SMB signature check failed!\n")); + return False; } else { - DEBUG(3, ("Server did not sign reply correctly\n")); - cli_free_signing_context(cli); + DEBUG(3, ("signing_good: Peer did not sign reply correctly\n")); + free_signing_context(si); return False; } } @@ -155,13 +231,15 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, * We do this here, to avoid modifying the packet. */ + DEBUG(10,("simple_packet_signature: sequence number %u\n", seq_number )); + SIVAL(sequence_buf, 0, seq_number); SIVAL(sequence_buf, 4, 0); /* Calculate the 16 byte MAC - but don't alter the data in the incoming packet. - This makes for a bit for fussing about, but it's not too bad. + This makes for a bit of fussing about, but it's not too bad. */ MD5Init(&md5_ctx); @@ -179,82 +257,130 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, MD5Update(&md5_ctx, buf + offset_end_of_sig, smb_len(buf) - (offset_end_of_sig - 4)); - /* caclulate the MD5 sig */ + /* calculate the MD5 sig */ MD5Final(calc_md5_mac, &md5_ctx); } /*********************************************************** - SMB signing - Simple implementation - send the MAC. + SMB signing - Client implementation - send the MAC. ************************************************************/ -static void cli_simple_sign_outgoing_message(struct cli_state *cli) +static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) { unsigned char calc_md5_mac[16]; - struct smb_basic_signing_context *data = cli->sign_info.signing_context; + struct smb_basic_signing_context *data = si->signing_context; + uint32 send_seq_num; + + if (!si->doing_signing) + return; + + /* JRA Paranioa test - we should be able to get rid of this... */ + if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(1, ("client_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n", + smb_len(outbuf) )); + abort(); + } /* mark the packet as signed - BEFORE we sign it...*/ - cli_mark_packet_signed(cli); + mark_packet_signed(outbuf); - simple_packet_signature(data, cli->outbuf, data->send_seq_num, - calc_md5_mac); + if (data->trans_info) + send_seq_num = data->trans_info->send_seq_num; + else + send_seq_num = data->send_seq_num; - DEBUG(10, ("sent SMB signature of\n")); + simple_packet_signature(data, outbuf, send_seq_num, calc_md5_mac); + + DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n")); dump_data(10, calc_md5_mac, 8); - memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8); + memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); /* cli->outbuf[smb_ss_field+2]=0; Uncomment this to test if the remote server actually verifies signatures...*/ + if (data->trans_info) + return; + data->send_seq_num++; store_sequence_for_reply(&data->outstanding_packet_list, - cli->mid, + SVAL(outbuf,smb_mid), data->send_seq_num); data->send_seq_num++; } /*********************************************************** - SMB signing - Simple implementation - check a MAC sent by server. + SMB signing - Client implementation - check a MAC sent by server. ************************************************************/ -static BOOL cli_simple_check_incoming_message(struct cli_state *cli) +static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) { BOOL good; uint32 reply_seq_number; unsigned char calc_md5_mac[16]; unsigned char *server_sent_mac; - struct smb_basic_signing_context *data = cli->sign_info.signing_context; + struct smb_basic_signing_context *data = si->signing_context; + + if (!si->doing_signing) + return True; - if (!get_sequence_for_reply(&data->outstanding_packet_list, - SVAL(cli->inbuf, smb_mid), + if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(1, ("client_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf))); + return False; + } + + if (data->trans_info) { + reply_seq_number = data->trans_info->reply_seq_num; + } else if (!get_sequence_for_reply(&data->outstanding_packet_list, + SVAL(inbuf, smb_mid), &reply_seq_number)) { + DEBUG(1, ("client_check_incoming_message: failed to get sequence number %u for reply.\n", + (unsigned int) SVAL(inbuf, smb_mid) )); return False; } - simple_packet_signature(data, cli->inbuf, reply_seq_number, calc_md5_mac); + simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); - server_sent_mac = &cli->inbuf[smb_ss_field]; + server_sent_mac = &inbuf[smb_ss_field]; good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); if (!good) { - DEBUG(5, ("BAD SIG: wanted SMB signature of\n")); + DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n")); dump_data(5, calc_md5_mac, 8); - DEBUG(5, ("BAD SIG: got SMB signature of\n")); + DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n")); dump_data(5, server_sent_mac, 8); +#if 1 /* JRATEST */ + { + int i; + reply_seq_number -= 5; + for (i = 0; i < 10; i++, reply_seq_number++) { + simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); + if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { + DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches.\n", + reply_seq_number )); + break; + } + } + } +#endif /* JRATEST */ + + } else { + DEBUG(10, ("client_check_incoming_message:: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); + dump_data(10, server_sent_mac, 8); } - return cli_signing_good(cli, good); + return signing_good(inbuf, si, good); } /*********************************************************** SMB signing - Simple implementation - free signing context ************************************************************/ -static void cli_simple_free_signing_context(struct cli_state *cli) +static void simple_free_signing_context(struct smb_sign_info *si) { - struct smb_basic_signing_context *data = cli->sign_info.signing_context; + struct smb_basic_signing_context *data = si->signing_context; struct outstanding_packet_lookup *list = data->outstanding_packet_list; while (list) { @@ -264,7 +390,11 @@ static void cli_simple_free_signing_context(struct cli_state *cli) } data_blob_free(&data->mac_key); - SAFE_FREE(cli->sign_info.signing_context); + + if (data->trans_info) + SAFE_FREE(data->trans_info); + + SAFE_FREE(si->signing_context); return; } @@ -284,18 +414,29 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ return False; } - if (!cli_set_smb_signing_real_common(cli)) { + if (!set_smb_signing_real_common(&cli->sign_info)) { return False; } data = smb_xmalloc(sizeof(*data)); + memset(data, '\0', sizeof(*data)); cli->sign_info.signing_context = data; data->mac_key = data_blob(NULL, response.length + 16); memcpy(&data->mac_key.data[0], user_session_key, 16); - memcpy(&data->mac_key.data[16],response.data, response.length); + + DEBUG(10, ("cli_simple_set_signing: user_session_key\n")); + dump_data(10, user_session_key, 16); + + if (response.length) { + memcpy(&data->mac_key.data[16],response.data, response.length); + DEBUG(10, ("cli_simple_set_signing: response_data\n")); + dump_data(10, response.data, response.length); + } else { + DEBUG(10, ("cli_simple_set_signing: NULL response_data\n")); + } /* Initialise the sequence number */ data->send_seq_num = 0; @@ -303,73 +444,68 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ /* Initialise the list of outstanding packets */ data->outstanding_packet_list = NULL; - cli->sign_info.sign_outgoing_message = cli_simple_sign_outgoing_message; - cli->sign_info.check_incoming_message = cli_simple_check_incoming_message; - cli->sign_info.free_signing_context = cli_simple_free_signing_context; + cli->sign_info.sign_outgoing_message = client_sign_outgoing_message; + cli->sign_info.check_incoming_message = client_check_incoming_message; + cli->sign_info.free_signing_context = simple_free_signing_context; return True; } /*********************************************************** - SMB signing - NULL implementation - calculate a MAC to send. + Tell client code we are in a multiple trans reply state. ************************************************************/ -static void cli_null_sign_outgoing_message(struct cli_state *cli) +void cli_signing_trans_start(struct cli_state *cli) { - /* we can't zero out the sig, as we might be trying to send a - session request - which is NBT-level, not SMB level and doesn't - have the field */ - return; -} + struct smb_basic_signing_context *data = cli->sign_info.signing_context; -/*********************************************************** - SMB signing - NULL implementation - check a MAC sent by server. -************************************************************/ + if (!cli->sign_info.doing_signing || !data) + return; -static BOOL cli_null_check_incoming_message(struct cli_state *cli) -{ - return True; + data->trans_info = smb_xmalloc(sizeof(struct trans_info_context)); + ZERO_STRUCTP(data->trans_info); + + data->trans_info->send_seq_num = data->send_seq_num; + data->trans_info->mid = SVAL(cli->outbuf,smb_mid); + data->trans_info->reply_seq_num = data->send_seq_num+1; + + DEBUG(10,("cli_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \ +data->send_seq_num = %u\n", + (unsigned int)data->trans_info->mid, + (unsigned int)data->trans_info->reply_seq_num, + (unsigned int)data->trans_info->send_seq_num, + (unsigned int)data->send_seq_num )); } /*********************************************************** - SMB signing - NULL implementation - free signing context + Tell client code we are out of a multiple trans reply state. ************************************************************/ -static void cli_null_free_signing_context(struct cli_state *cli) +void cli_signing_trans_stop(struct cli_state *cli) { - return; -} + struct smb_basic_signing_context *data = cli->sign_info.signing_context; -/** - SMB signing - NULL implementation - setup the MAC key. + if (!cli->sign_info.doing_signing || !data) + return; - @note Used as an initialisation only - it will not correctly - shut down a real signing mechanism -*/ + SAFE_FREE(data->trans_info); + data->trans_info = NULL; -BOOL cli_null_set_signing(struct cli_state *cli) -{ - cli->sign_info.signing_context = NULL; - - cli->sign_info.sign_outgoing_message = cli_null_sign_outgoing_message; - cli->sign_info.check_incoming_message = cli_null_check_incoming_message; - cli->sign_info.free_signing_context = cli_null_free_signing_context; - - return True; + data->send_seq_num += 2; } /*********************************************************** SMB signing - TEMP implementation - calculate a MAC to send. ************************************************************/ -static void cli_temp_sign_outgoing_message(struct cli_state *cli) +static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) { /* mark the packet as signed - BEFORE we sign it...*/ - cli_mark_packet_signed(cli); + mark_packet_signed(outbuf); /* I wonder what BSRSPYL stands for - but this is what MS actually sends! */ - memcpy(&cli->outbuf[smb_ss_field], "BSRSPYL ", 8); + memcpy(&outbuf[smb_ss_field], "BSRSPYL ", 8); return; } @@ -377,7 +513,7 @@ static void cli_temp_sign_outgoing_message(struct cli_state *cli) SMB signing - TEMP implementation - check a MAC sent by server. ************************************************************/ -static BOOL cli_temp_check_incoming_message(struct cli_state *cli) +static BOOL temp_check_incoming_message(char *inbuf, struct smb_sign_info *si) { return True; } @@ -386,7 +522,7 @@ static BOOL cli_temp_check_incoming_message(struct cli_state *cli) SMB signing - TEMP implementation - free signing context ************************************************************/ -static void cli_temp_free_signing_context(struct cli_state *cli) +static void temp_free_signing_context(struct smb_sign_info *si) { return; } @@ -395,6 +531,15 @@ static void cli_temp_free_signing_context(struct cli_state *cli) SMB signing - NULL implementation - setup the MAC key. ************************************************************/ +BOOL cli_null_set_signing(struct cli_state *cli) +{ + return null_set_signing(&cli->sign_info); +} + +/*********************************************************** + SMB signing - temp implementation - setup the MAC key. +************************************************************/ + BOOL cli_temp_set_signing(struct cli_state *cli) { if (!cli_set_smb_signing_common(cli)) { @@ -403,58 +548,427 @@ BOOL cli_temp_set_signing(struct cli_state *cli) cli->sign_info.signing_context = NULL; - cli->sign_info.sign_outgoing_message = cli_temp_sign_outgoing_message; - cli->sign_info.check_incoming_message = cli_temp_check_incoming_message; - cli->sign_info.free_signing_context = cli_temp_free_signing_context; + cli->sign_info.sign_outgoing_message = temp_sign_outgoing_message; + cli->sign_info.check_incoming_message = temp_check_incoming_message; + cli->sign_info.free_signing_context = temp_free_signing_context; return True; } -/** - * Free the signing context - */ - -void cli_free_signing_context(struct cli_state *cli) +void cli_free_signing_context(struct cli_state *cli) { - if (cli->sign_info.free_signing_context) - cli->sign_info.free_signing_context(cli); - - cli_null_set_signing(cli); + free_signing_context(&cli->sign_info); } /** * Sign a packet with the current mechanism */ -void cli_caclulate_sign_mac(struct cli_state *cli) +void cli_calculate_sign_mac(struct cli_state *cli) { - cli->sign_info.sign_outgoing_message(cli); + cli->sign_info.sign_outgoing_message(cli->outbuf, &cli->sign_info); } /** * Check a packet with the current mechanism * @return False if we had an established signing connection - * which had a back checksum, True otherwise + * which had a bad checksum, True otherwise. */ BOOL cli_check_sign_mac(struct cli_state *cli) { + if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info)) { + free_signing_context(&cli->sign_info); + return False; + } + return True; +} + +static BOOL packet_is_oplock_break(char *buf) +{ + if (CVAL(buf,smb_com) != SMBlockingX) + return False; + + if (CVAL(buf,smb_vwv3) != LOCKING_ANDX_OPLOCK_RELEASE) + return False; + + return True; +} + +/*********************************************************** + SMB signing - Server implementation - send the MAC. +************************************************************/ + +static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) +{ + unsigned char calc_md5_mac[16]; + struct smb_basic_signing_context *data = si->signing_context; + uint32 send_seq_number = data->send_seq_num; + BOOL was_deferred_packet = False; + uint16 mid; + + if (!si->doing_signing) { + if (si->allow_smb_signing && si->negotiated_smb_signing) { + mid = SVAL(outbuf, smb_mid); + + was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, + mid, &send_seq_number); + if (!was_deferred_packet) { + /* + * Is this an outgoing oplock break ? If so, store the + * mid in the outstanding list. + */ + + if (packet_is_oplock_break(outbuf)) { + store_sequence_for_reply(&data->outstanding_packet_list, + mid, data->send_seq_num); + } + + data->send_seq_num++; + } + } + return; + } + + /* JRA Paranioa test - we should be able to get rid of this... */ + if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(1, ("srv_sign_outgoing_message: Logic error. Can't send signature on short packet! smb_len = %u\n", + smb_len(outbuf) )); + abort(); + } + + /* mark the packet as signed - BEFORE we sign it...*/ + mark_packet_signed(outbuf); + + mid = SVAL(outbuf, smb_mid); + + /* See if this is a reply for a deferred packet. */ + was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number); + + if (data->trans_info && (data->trans_info->mid == mid)) { + /* This is a reply in a trans stream. Use the sequence + * number associated with the stream mid. */ + send_seq_number = data->trans_info->send_seq_num; + } + + simple_packet_signature(data, outbuf, send_seq_number, calc_md5_mac); + + DEBUG(10, ("srv_sign_outgoing_message: seq %u: sent SMB signature of\n", (unsigned int)send_seq_number)); + dump_data(10, calc_md5_mac, 8); + + memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); + +/* cli->outbuf[smb_ss_field+2]=0; + Uncomment this to test if the remote server actually verifies signatures...*/ + + if (!was_deferred_packet) { + if (!data->trans_info) { + /* Always increment if not in a trans stream. */ + data->send_seq_num++; + } else if ((data->trans_info->send_seq_num == data->send_seq_num) || (data->trans_info->mid != mid)) { + /* Increment if this is the first reply in a trans stream or a + * packet that doesn't belong to this stream (different mid). */ + data->send_seq_num++; + } + } +} + +/*********************************************************** + SMB signing - Server implementation - check a MAC sent by server. +************************************************************/ + +static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) +{ BOOL good; + struct smb_basic_signing_context *data = si->signing_context; + uint32 reply_seq_number = data->send_seq_num; + unsigned char calc_md5_mac[16]; + unsigned char *server_sent_mac; + uint mid; + + if (!si->doing_signing) + return True; - if (smb_len(cli->inbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(cli->sign_info.doing_signing ? 1 : 10, ("Can't check signature on short packet! smb_len = %u\n", smb_len(cli->inbuf))); - good = False; + if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(1, ("srv_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf))); + return False; + } + + mid = SVAL(inbuf, smb_mid); + + /* Is this part of a trans stream ? */ + if (data->trans_info && (data->trans_info->mid == mid)) { + /* If so we don't increment the sequence. */ + reply_seq_number = data->trans_info->reply_seq_num; } else { - good = cli->sign_info.check_incoming_message(cli); + /* We always increment the sequence number. */ + data->send_seq_num++; + /* Oplock break requests store an outgoing mid in the packet list. */ + if (packet_is_oplock_break(inbuf)) + get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_number); } + simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); + + server_sent_mac = &inbuf[smb_ss_field]; + good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); + if (!good) { - if (cli->sign_info.doing_signing) { - return False; - } else { - cli_free_signing_context(cli); + + DEBUG(5, ("srv_check_incoming_message: BAD SIG: wanted SMB signature of\n")); + dump_data(5, calc_md5_mac, 8); + + DEBUG(5, ("srv_check_incoming_message: BAD SIG: got SMB signature of\n")); + dump_data(5, server_sent_mac, 8); + +#if 1 /* JRATEST */ + { + int i; + reply_seq_number -= 5; + for (i = 0; i < 10; i++, reply_seq_number++) { + simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); + if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { + DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches.\n", + reply_seq_number )); + break; + } + } } +#endif /* JRATEST */ + + } else { + DEBUG(10, ("srv_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); + dump_data(10, server_sent_mac, 8); } + return signing_good(inbuf, si, good); +} - return True; +/*********************************************************** + SMB signing - server API's. +************************************************************/ + +static struct smb_sign_info srv_sign_info = { + null_sign_outgoing_message, + null_check_incoming_message, + null_free_signing_context, + NULL, + False, + False, + False, + False +}; + +/*********************************************************** + Turn signing off or on for oplock break code. +************************************************************/ + +BOOL srv_oplock_set_signing(BOOL onoff) +{ + BOOL ret = srv_sign_info.doing_signing; + srv_sign_info.doing_signing = onoff; + return ret; +} + +/*********************************************************** + Called to validate an incoming packet from the client. +************************************************************/ + +BOOL srv_check_sign_mac(char *inbuf) +{ + /* Check if it's a session keepalive. */ + if(CVAL(inbuf,0) == SMBkeepalive) + return True; + + return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info); +} + +/*********************************************************** + Called to sign an outgoing packet to the client. +************************************************************/ + +void srv_calculate_sign_mac(char *outbuf) +{ + /* Check if it's a session keepalive. */ + /* JRA Paranioa test - do we ever generate these in the server ? */ + if(CVAL(outbuf,0) == SMBkeepalive) + return; + + srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info); +} + +/*********************************************************** + Called by server to defer an outgoing packet. +************************************************************/ + +void srv_defer_sign_response(uint16 mid) +{ + struct smb_basic_signing_context *data; + + if (!srv_sign_info.doing_signing) + return; + + data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + + if (!data) + return; + + store_sequence_for_reply(&data->outstanding_packet_list, + mid, data->send_seq_num); + data->send_seq_num++; +} + +/*********************************************************** + Called to remove sequence records when a deferred packet is + cancelled by mid. This should never find one.... +************************************************************/ + +void srv_cancel_sign_response(uint16 mid) +{ + struct smb_basic_signing_context *data; + uint32 dummy_seq; + + if (!srv_sign_info.doing_signing) + return; + + data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + + if (!data) + return; + + DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid )); + + while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq)) + ; +} + +/*********************************************************** + Called by server negprot when signing has been negotiated. +************************************************************/ + +void srv_set_signing_negotiated(void) +{ + srv_sign_info.allow_smb_signing = True; + srv_sign_info.negotiated_smb_signing = True; + if (lp_server_signing() == Required) + srv_sign_info.mandatory_signing = True; + + srv_sign_info.sign_outgoing_message = temp_sign_outgoing_message; + srv_sign_info.check_incoming_message = temp_check_incoming_message; + srv_sign_info.free_signing_context = temp_free_signing_context; +} + +/*********************************************************** + Returns whether signing is active. We can't use sendfile or raw + reads/writes if it is. +************************************************************/ + +BOOL srv_is_signing_active(void) +{ + return srv_sign_info.doing_signing; +} + +/*********************************************************** + Tell server code we are in a multiple trans reply state. +************************************************************/ + +void srv_signing_trans_start(uint16 mid) +{ + struct smb_basic_signing_context *data; + + if (!srv_sign_info.doing_signing) + return; + + data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + if (!data) + return; + + data->trans_info = smb_xmalloc(sizeof(struct trans_info_context)); + ZERO_STRUCTP(data->trans_info); + + data->trans_info->reply_seq_num = data->send_seq_num-1; + data->trans_info->mid = mid; + data->trans_info->send_seq_num = data->send_seq_num; + + DEBUG(10,("srv_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \ +data->send_seq_num = %u\n", + (unsigned int)mid, + (unsigned int)data->trans_info->reply_seq_num, + (unsigned int)data->trans_info->send_seq_num, + (unsigned int)data->send_seq_num )); +} + +/*********************************************************** + Tell server code we are out of a multiple trans reply state. +************************************************************/ + +void srv_signing_trans_stop(void) +{ + struct smb_basic_signing_context *data; + + if (!srv_sign_info.doing_signing) + return; + + data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + if (!data || !data->trans_info) + return; + + DEBUG(10,("srv_signing_trans_stop: removing mid = %u, reply_seq_num = %u, send_seq_num = %u \ +data->send_seq_num = %u\n", + (unsigned int)data->trans_info->mid, + (unsigned int)data->trans_info->reply_seq_num, + (unsigned int)data->trans_info->send_seq_num, + (unsigned int)data->send_seq_num )); + + SAFE_FREE(data->trans_info); + data->trans_info = NULL; +} + +/*********************************************************** + Turn on signing from this packet onwards. +************************************************************/ + +void srv_set_signing(const uchar user_session_key[16], const DATA_BLOB response) +{ + struct smb_basic_signing_context *data; + + if (!user_session_key) + return; + + if (!srv_sign_info.negotiated_smb_signing && !srv_sign_info.mandatory_signing) { + DEBUG(5,("srv_set_signing: signing negotiated = %u, mandatory_signing = %u. Not allowing smb signing.\n", + (unsigned int)srv_sign_info.negotiated_smb_signing, + (unsigned int)srv_sign_info.mandatory_signing )); + return; + } + + /* Once we've turned on, ignore any more sessionsetups. */ + if (srv_sign_info.doing_signing) { + return; + } + + if (srv_sign_info.free_signing_context) + srv_sign_info.free_signing_context(&srv_sign_info); + + srv_sign_info.doing_signing = True; + + data = smb_xmalloc(sizeof(*data)); + memset(data, '\0', sizeof(*data)); + + srv_sign_info.signing_context = data; + + data->mac_key = data_blob(NULL, response.length + 16); + + memcpy(&data->mac_key.data[0], user_session_key, 16); + if (response.length) + memcpy(&data->mac_key.data[16],response.data, response.length); + + /* Initialise the sequence number */ + data->send_seq_num = 0; + + /* Initialise the list of outstanding packets */ + data->outstanding_packet_list = NULL; + + srv_sign_info.sign_outgoing_message = srv_sign_outgoing_message; + srv_sign_info.check_incoming_message = srv_check_incoming_message; + srv_sign_info.free_signing_context = simple_free_signing_context; } diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c index 8378125088..0128d08006 100644 --- a/source3/libsmb/trustdom_cache.c +++ b/source3/libsmb/trustdom_cache.c @@ -223,7 +223,7 @@ BOOL trustdom_cache_store_timestamp( uint32 t, time_t timeout ) if (!gencache_init()) return False; - snprintf(value, sizeof(value), "%d", t ); + fstr_sprintf(value, "%d", t ); if (!gencache_set(TDOMTSKEY, value, timeout)) { DEBUG(5, ("failed to set timestamp for trustdom_cache\n")); diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 77e63709aa..610f4b3c03 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -154,7 +154,7 @@ BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, /* setup the anonymous connection */ result = cli_full_connection( &cli, global_myname(), dc_name, &dc_ip, 0, "IPC$", "IPC", - "", "", "", 0, &retry); + "", "", "", 0, Undefined, &retry); if ( !NT_STATUS_IS_OK(result) ) goto done; diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 1a5757f817..4475f1446f 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -125,7 +125,11 @@ static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_p */ if (!set_posix_lock(fsp, offset, count, lock_type)) { - status = NT_STATUS_LOCK_NOT_GRANTED; + if (errno == EACCES || errno == EAGAIN) + status = NT_STATUS_FILE_LOCK_CONFLICT; + else + status = map_nt_error_from_unix(errno); + /* * We failed to map - we must now remove the brl * lock entry. @@ -380,8 +384,8 @@ char *share_mode_str(int num, share_mode_entry *e) static pstring share_str; slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: \ -pid = %u, share_mode = 0x%x, desired_access = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, dev = 0x%x, inode = %.0f", - num, e->pid, e->share_mode, (unsigned int)e->desired_access, e->op_port, e->op_type, e->share_file_id, +pid = %lu, share_mode = 0x%x, desired_access = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, dev = 0x%x, inode = %.0f", + num, (unsigned long)e->pid, e->share_mode, (unsigned int)e->desired_access, e->op_port, e->op_type, e->share_file_id, (unsigned int)e->dev, (double)e->inode ); return share_str; diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c index 42edcc871f..bc3540af70 100644 --- a/source3/nmbd/nmbd_processlogon.c +++ b/source3/nmbd/nmbd_processlogon.c @@ -4,8 +4,7 @@ Copyright (C) Andrew Tridgell 1994-1998 Copyright (C) Luke Kenneth Casson Leighton 1994-1998 Copyright (C) Jeremy Allison 1994-1998 - Copyright (C) Jim McDonough 2002 - Copyright (C) Anthony Liguori 2002 + Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/source3/nsswitch/wb_common.c b/source3/nsswitch/wb_common.c index acaf0ed17c..79553e9e4f 100644 --- a/source3/nsswitch/wb_common.c +++ b/source3/nsswitch/wb_common.c @@ -239,6 +239,8 @@ int winbind_open_pipe_sock(void) } } + SAFE_FREE(response.extra_data); + return winbindd_fd; #else return -1; diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c index f533799370..fcd7d2d508 100644 --- a/source3/nsswitch/wbinfo.c +++ b/source3/nsswitch/wbinfo.c @@ -1074,7 +1074,7 @@ int main(int argc, char **argv) goto done; } break; - case 'P': + case 'p': if (!wbinfo_ping()) { d_printf("could not ping winbindd!\n"); goto done; diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c index 0860d701d8..8345fa11d0 100644 --- a/source3/nsswitch/winbindd.c +++ b/source3/nsswitch/winbindd.c @@ -27,20 +27,6 @@ BOOL opt_nocache = False; BOOL opt_dual_daemon = True; -/***************************************************************************** - stubb functions -****************************************************************************/ - -void become_root( void ) -{ - return; -} - -void unbecome_root( void ) -{ - return; -} - /* Reload configuration */ static BOOL reload_services_file(BOOL test) @@ -131,8 +117,8 @@ static void winbindd_status(void) if (DEBUGLEVEL >= 2 && winbindd_num_clients()) { DEBUG(2, ("\tclient list:\n")); for(tmp = winbindd_client_list(); tmp; tmp = tmp->next) { - DEBUG(2, ("\t\tpid %d, sock %d, rbl %d, wbl %d\n", - tmp->pid, tmp->sock, tmp->read_buf_len, + DEBUG(2, ("\t\tpid %lu, sock %d, rbl %d, wbl %d\n", + (unsigned long)tmp->pid, tmp->sock, tmp->read_buf_len, tmp->write_buf_len)); } } @@ -172,7 +158,7 @@ static void terminate(void) idmap_close(); /* Remove socket file */ - snprintf(path, sizeof(path), "%s/%s", + pstr_sprintf(path, "%s/%s", WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME); unlink(path); exit(0); @@ -471,8 +457,8 @@ void winbind_client_read(struct winbindd_cli_state *state) /* Read failed, kill client */ if (n == -1 || n == 0) { - DEBUG(5,("read failed on sock %d, pid %d: %s\n", - state->sock, state->pid, + DEBUG(5,("read failed on sock %d, pid %lu: %s\n", + state->sock, (unsigned long)state->pid, (n == -1) ? strerror(errno) : "EOF")); state->finished = True; @@ -519,8 +505,8 @@ static void client_write(struct winbindd_cli_state *state) if (num_written == -1 || num_written == 0) { - DEBUG(3,("write failed on sock %d, pid %d: %s\n", - state->sock, state->pid, + DEBUG(3,("write failed on sock %d, pid %lu: %s\n", + state->sock, (unsigned long)state->pid, (num_written == -1) ? strerror(errno) : "EOF")); state->finished = True; @@ -726,8 +712,8 @@ static void process_loop(void) if (state->read_buf_len >= sizeof(uint32) && *(uint32 *) &state->request != sizeof(state->request)) { - DEBUG(0,("process_loop: Invalid request size from pid %d: %d bytes sent, should be %d\n", - state->request.pid, *(uint32 *) &state->request, sizeof(state->request))); + DEBUG(0,("process_loop: Invalid request size from pid %lu: %d bytes sent, should be %d\n", + (unsigned long)state->request.pid, *(uint32 *) &state->request, sizeof(state->request))); remove_client(state); break; @@ -838,7 +824,7 @@ int main(int argc, char **argv) exit(1); } - snprintf(logfile, sizeof(logfile), "%s/log.winbindd", dyn_LOGFILEBASE); + pstr_sprintf(logfile, "%s/log.winbindd", dyn_LOGFILEBASE); lp_set_logfile(logfile); setup_logging("winbindd", log_stdout); reopen_logs(); diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h index 2acb89b24b..677afa1849 100644 --- a/source3/nsswitch/winbindd.h +++ b/source3/nsswitch/winbindd.h @@ -4,7 +4,7 @@ Winbind daemon for ntdom nss module Copyright (C) Tim Potter 2000 - Copyright (C) Anthony Liguori 2003 + Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public diff --git a/source3/nsswitch/winbindd_acct.c b/source3/nsswitch/winbindd_acct.c index a1cd1d5f19..8abfd17110 100644 --- a/source3/nsswitch/winbindd_acct.c +++ b/source3/nsswitch/winbindd_acct.c @@ -136,8 +136,8 @@ static WINBINDD_PW* string2passwd( char *string ) /* last minute sanity checks */ if ( pw.pw_uid==0 || pw.pw_gid==0 ) { - DEBUG(0,("string2passwd: Failure! uid==%d, gid==%d\n", - pw.pw_uid, pw.pw_gid)); + DEBUG(0,("string2passwd: Failure! uid==%lu, gid==%lu\n", + (unsigned long)pw.pw_uid, (unsigned long)pw.pw_gid)); return NULL; } @@ -161,17 +161,17 @@ static char* passwd2string( const WINBINDD_PW *pw ) DEBUG(10,("passwd2string: converting passwd struct for %s\n", pw->pw_name)); - ret = snprintf( string, sizeof(string), "%s:%s:%d:%d:%s:%s:%s", + ret = pstr_sprintf( string, "%s:%s:%lu:%lu:%s:%s:%s", pw->pw_name, pw->pw_passwd ? pw->pw_passwd : "x", - pw->pw_uid, - pw->pw_gid, + (unsigned long)pw->pw_uid, + (unsigned long)pw->pw_gid, pw->pw_gecos, pw->pw_dir, pw->pw_shell ); if ( ret < 0 ) { - DEBUG(0,("passwd2string: snprintf() failed!\n")); + DEBUG(0,("passwd2string: pstr_sprintf() failed!\n")); return NULL; } @@ -247,7 +247,7 @@ static WINBINDD_GR* string2group( char *string ) /* last minute sanity checks */ if ( grp.gr_gid == 0 ) { - DEBUG(0,("string2group: Failure! gid==%d\n", grp.gr_gid)); + DEBUG(0,("string2group: Failure! gid==%lu\n", (unsigned long)grp.gr_gid)); SAFE_FREE( gr_members ); return NULL; } @@ -303,16 +303,16 @@ static char* group2string( const WINBINDD_GR *grp ) fstrcpy( gr_mem_str, "" ); } - ret = snprintf( string, sizeof(string)-1, "%s:%s:%d:%s", + ret = pstr_sprintf( string, "%s:%s:%lu:%s", grp->gr_name, grp->gr_passwd ? grp->gr_passwd : "*", - grp->gr_gid, + (unsigned long)grp->gr_gid, gr_mem_str ); SAFE_FREE( gr_mem_str ); if ( ret < 0 ) { - DEBUG(0,("group2string: snprintf() failed!\n")); + DEBUG(0,("group2string: pstr_sprintf() failed!\n")); return NULL; } @@ -326,7 +326,7 @@ static char* acct_userkey_byname( const char *name ) { static fstring key; - snprintf( key, sizeof(key), "%s/NAME/%s", WBKEY_PASSWD, name ); + fstr_sprintf( key, "%s/NAME/%s", WBKEY_PASSWD, name ); return key; } @@ -338,7 +338,7 @@ static char* acct_userkey_byuid( uid_t uid ) { static fstring key; - snprintf( key, sizeof(key), "%s/UID/%d", WBKEY_PASSWD, uid ); + fstr_sprintf( key, "%s/UID/%lu", WBKEY_PASSWD, (unsigned long)uid ); return key; } @@ -350,7 +350,7 @@ static char* acct_groupkey_byname( const char *name ) { static fstring key; - snprintf( key, sizeof(key), "%s/NAME/%s", WBKEY_GROUP, name ); + fstr_sprintf( key, "%s/NAME/%s", WBKEY_GROUP, name ); return key; } @@ -362,7 +362,7 @@ static char* acct_groupkey_bygid( gid_t gid ) { static fstring key; - snprintf( key, sizeof(key), "%s/GID/%d", WBKEY_GROUP, gid ); + fstr_sprintf( key, "%s/GID/%lu", WBKEY_GROUP, (unsigned long)gid ); return key; } @@ -415,7 +415,7 @@ WINBINDD_PW* wb_getpwuid( const uid_t uid ) data = tdb_fetch_bystring( account_tdb, acct_userkey_byuid(uid) ); if ( !data.dptr ) { - DEBUG(4,("wb_getpwuid: failed to locate uid == %d\n", uid)); + DEBUG(4,("wb_getpwuid: failed to locate uid == %lu\n", (unsigned long)uid)); return NULL; } keystr = acct_userkey_byname( data.dptr ); @@ -431,8 +431,8 @@ WINBINDD_PW* wb_getpwuid( const uid_t uid ) SAFE_FREE( data.dptr ); } - DEBUG(5,("wb_getpwuid: %s user (uid == %d)\n", - (pw ? "Found" : "Did not find"), uid )); + DEBUG(5,("wb_getpwuid: %s user (uid == %lu)\n", + (pw ? "Found" : "Did not find"), (unsigned long)uid )); return pw; } @@ -544,7 +544,8 @@ WINBINDD_GR* wb_getgrgid( gid_t gid ) data = tdb_fetch_bystring( account_tdb, acct_groupkey_bygid(gid) ); if ( !data.dptr ) { - DEBUG(4,("wb_getgrgid: failed to locate gid == %d\n", gid)); + DEBUG(4,("wb_getgrgid: failed to locate gid == %lu\n", + (unsigned long)gid)); return NULL; } keystr = acct_groupkey_byname( data.dptr ); @@ -560,8 +561,8 @@ WINBINDD_GR* wb_getgrgid( gid_t gid ) SAFE_FREE( data.dptr ); } - DEBUG(5,("wb_getgrgid: %s group (gid == %d)\n", - (grp ? "Found" : "Did not find"), gid )); + DEBUG(5,("wb_getgrgid: %s group (gid == %lu)\n", + (grp ? "Found" : "Did not find"), (unsigned long)gid )); return grp; } @@ -697,7 +698,7 @@ static int cleangroups_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA fstring key; char *name = (char*)state; - snprintf( key, sizeof(key), "%s/NAME", WBKEY_GROUP ); + fstr_sprintf( key, "%s/NAME", WBKEY_GROUP ); len = strlen(key); /* if this is a group entry then, check the members */ @@ -776,7 +777,7 @@ static int isprimarygroup_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, fstring key; struct _check_primary_grp *check = (struct _check_primary_grp*)params; - snprintf( key, sizeof(key), "%s/NAME", WBKEY_PASSWD ); + fstr_sprintf( key, "%s/NAME", WBKEY_PASSWD ); len = strlen(key); /* if this is a group entry then, check the members */ @@ -875,8 +876,8 @@ enum winbindd_result winbindd_create_user(struct winbindd_cli_state *state) user = state->request.data.acct_mgt.username; group = state->request.data.acct_mgt.groupname; - DEBUG(3, ("[%5d]: create_user: user=>(%s), group=>(%s)\n", - state->pid, user, group)); + DEBUG(3, ("[%5lu]: create_user: user=>(%s), group=>(%s)\n", + (unsigned long)state->pid, user, group)); if ( !*group ) group = lp_template_primary_group(); @@ -965,7 +966,7 @@ enum winbindd_result winbindd_create_group(struct winbindd_cli_state *state) state->request.data.acct_mgt.groupname[sizeof(state->request.data.acct_mgt.groupname)-1]='\0'; group = state->request.data.acct_mgt.groupname; - DEBUG(3, ("[%5d]: create_group: (%s)\n", state->pid, group)); + DEBUG(3, ("[%5lu]: create_group: (%s)\n", (unsigned long)state->pid, group)); /* get a new uid */ @@ -1025,7 +1026,7 @@ enum winbindd_result winbindd_add_user_to_group(struct winbindd_cli_state *state group = state->request.data.acct_mgt.groupname; user = state->request.data.acct_mgt.username; - DEBUG(3, ("[%5d]: add_user_to_group: add %s to %s\n", state->pid, + DEBUG(3, ("[%5lu]: add_user_to_group: add %s to %s\n", (unsigned long)state->pid, user, group)); /* make sure it is a valid user */ @@ -1073,7 +1074,7 @@ enum winbindd_result winbindd_remove_user_from_group(struct winbindd_cli_state * group = state->request.data.acct_mgt.groupname; user = state->request.data.acct_mgt.username; - DEBUG(3, ("[%5d]: remove_user_to_group: delete %s from %s\n", state->pid, + DEBUG(3, ("[%5lu]: remove_user_to_group: delete %s from %s\n", (unsigned long)state->pid, user, group)); /* don't worry about checking the username since we're removing it anyways */ @@ -1116,8 +1117,8 @@ enum winbindd_result winbindd_set_user_primary_group(struct winbindd_cli_state * group = state->request.data.acct_mgt.groupname; user = state->request.data.acct_mgt.username; - DEBUG(3, ("[%5d]: set_user_primary_grou:p group %s for user %s\n", state->pid, - group, user)); + DEBUG(3, ("[%5lu]: set_user_primary_group: group %s for user %s\n", + (unsigned long)state->pid, group, user)); /* make sure it is a valid user */ @@ -1158,7 +1159,7 @@ enum winbindd_result winbindd_delete_user(struct winbindd_cli_state *state) state->request.data.acct_mgt.username[sizeof(state->request.data.acct_mgt.username)-1]='\0'; user = state->request.data.acct_mgt.username; - DEBUG(3, ("[%5d]: delete_user: %s\n", state->pid, user)); + DEBUG(3, ("[%5lu]: delete_user: %s\n", (unsigned long)state->pid, user)); /* make sure it is a valid user */ @@ -1189,7 +1190,7 @@ enum winbindd_result winbindd_delete_group(struct winbindd_cli_state *state) state->request.data.acct_mgt.username[sizeof(state->request.data.acct_mgt.groupname)-1]='\0'; group = state->request.data.acct_mgt.groupname; - DEBUG(3, ("[%5d]: delete_group: %s\n", state->pid, group)); + DEBUG(3, ("[%5lu]: delete_group: %s\n", (unsigned long)state->pid, group)); /* make sure it is a valid group */ diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c index 462dd21531..7140dc35a0 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -801,24 +801,91 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, char ***alt_names, DOM_SID **dom_sids) { - ADS_STRUCT *ads; - ADS_STATUS rc; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + DS_DOMAIN_TRUSTS *domains = NULL; + int count = 0; + int i; + struct cli_state *cli = NULL; + /* i think we only need our forest and downlevel trusted domains */ + uint32 flags = DS_DOMAIN_IN_FOREST | DS_DOMAIN_DIRECT_OUTBOUND; DEBUG(3,("ads: trusted_domains\n")); *num_domains = 0; - *names = NULL; + *alt_names = NULL; + *names = NULL; + *dom_sids = NULL; + + if ( !NT_STATUS_IS_OK(result = cm_fresh_connection(domain->name, PI_NETLOGON, &cli)) ) { + DEBUG(5, ("trusted_domains: Could not open a connection to %s for PIPE_NETLOGON (%s)\n", + domain->name, nt_errstr(result))); + return NT_STATUS_UNSUCCESSFUL; + } + + if ( NT_STATUS_IS_OK(result) ) + result = cli_ds_enum_domain_trusts( cli, mem_ctx, cli->desthost, flags, &domains, &count ); + + if ( NT_STATUS_IS_OK(result) && count) { + + /* Allocate memory for trusted domain names and sids */ - ads = ads_cached_connection(domain); + if ( !(*names = (char **)talloc(mem_ctx, sizeof(char *) * count)) ) { + DEBUG(0, ("trusted_domains: out of memory\n")); + result = NT_STATUS_NO_MEMORY; + goto done; + } - if (!ads) { - domain->last_status = NT_STATUS_SERVER_DISABLED; - return NT_STATUS_UNSUCCESSFUL; + if ( !(*alt_names = (char **)talloc(mem_ctx, sizeof(char *) * count)) ) { + DEBUG(0, ("trusted_domains: out of memory\n")); + result = NT_STATUS_NO_MEMORY; + goto done; + } + + if ( !(*dom_sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * count)) ) { + DEBUG(0, ("trusted_domains: out of memory\n")); + result = NT_STATUS_NO_MEMORY; + goto done; + } + + /* Copy across names and sids */ + + for (i = 0; i < count; i++) { + fstring tmp; + fstring tmp2; + + (*names)[i] = NULL; + (*alt_names)[i] = NULL; + ZERO_STRUCT( (*dom_sids)[i] ); + + if ( domains[i].netbios_ptr ) { + unistr2_to_ascii(tmp, &domains[i].netbios_domain, sizeof(tmp) - 1); + (*names)[i] = talloc_strdup(mem_ctx, tmp); + } + + if ( domains[i].dns_ptr ) { + unistr2_to_ascii(tmp2, &domains[i].dns_domain, sizeof(tmp2) - 1); + (*alt_names)[i] = talloc_strdup(mem_ctx, tmp2); + } + + /* sometimes we will get back a NULL SID from this call */ + + if ( domains[i].sid_ptr ) + sid_copy(&(*dom_sids)[i], &domains[i].sid.sid); + } + + *num_domains = count; } - rc = ads_trusted_domains(ads, mem_ctx, num_domains, names, alt_names, dom_sids); +done: + + SAFE_FREE( domains ); + + /* remove connection; This is a special case to the \NETLOGON pipe */ + + if ( cli ) + cli_shutdown( cli ); - return ads_ntstatus(rc); + return result; } /* find the domain sid for a domain */ diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c index 2da2a9e641..2891a4fa68 100644 --- a/source3/nsswitch/winbindd_cache.c +++ b/source3/nsswitch/winbindd_cache.c @@ -106,7 +106,7 @@ static struct winbind_cache *get_cache(struct winbindd_domain *domain) case SEC_ADS: { extern struct winbindd_methods ads_methods; /* always obey the lp_security parameter for our domain */ - if ( strequal(lp_realm(), domain->alt_name) ) { + if ( strequal(lp_realm(), domain->alt_name) || strequal(lp_workgroup(), domain->name) ) { domain->backend = &ads_methods; break; } @@ -256,7 +256,7 @@ static NTSTATUS fetch_cache_seqnum( struct winbindd_domain *domain, time_t now ) return NT_STATUS_UNSUCCESSFUL; } - snprintf( key, sizeof(key), "SEQNUM/%s", domain->name ); + fstr_sprintf( key, "SEQNUM/%s", domain->name ); data = tdb_fetch_bystring( wcache->tdb, key ); if ( !data.dptr || data.dsize!=8 ) { @@ -295,7 +295,7 @@ static NTSTATUS store_cache_seqnum( struct winbindd_domain *domain ) return NT_STATUS_UNSUCCESSFUL; } - snprintf( key_str, sizeof(key_str), "SEQNUM/%s", domain->name ); + fstr_sprintf( key_str, "SEQNUM/%s", domain->name ); key.dptr = key_str; key.dsize = strlen(key_str)+1; @@ -328,6 +328,8 @@ static void refresh_sequence_number(struct winbindd_domain *domain, BOOL force) time_t t = time(NULL); unsigned cache_time = lp_winbind_cache_time(); + get_cache( domain ); + /* trying to reconnect is expensive, don't do it too often */ if (domain->sequence_number == DOM_SEQUENCE_NONE) { cache_time *= 8; diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c index 7f35167778..f07117b5ab 100644 --- a/source3/nsswitch/winbindd_cm.c +++ b/source3/nsswitch/winbindd_cm.c @@ -152,7 +152,8 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index, result = cli_full_connection(&new_conn->cli, global_myname(), new_conn->controller, &dc_ip, 0, "IPC$", "IPC", ipc_username, ipc_domain, - ipc_password, CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK, &retry); + ipc_password, CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK, + Undefined, &retry); secrets_named_mutex_release(new_conn->controller); @@ -169,6 +170,11 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index, return result; } + /* set the domain if empty; needed for schannel connections */ + if ( !*new_conn->cli->domain ) + fstrcpy( new_conn->cli->domain, domain ); + + if ( !cli_nt_session_open (new_conn->cli, pipe_index) ) { result = NT_STATUS_PIPE_NOT_AVAILABLE; /* @@ -188,6 +194,25 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index, return NT_STATUS_OK; } +/************************************************************************ + Wrapper around statuc cm_open_connection to retreive a freshly + setup cli_state struct +************************************************************************/ + +NTSTATUS cm_fresh_connection(const char *domain, const int pipe_index, + struct cli_state **cli) +{ + NTSTATUS result; + struct winbindd_cm_conn conn; + + result = cm_open_connection( domain, pipe_index, &conn ); + + if ( NT_STATUS_IS_OK(result) ) + *cli = conn.cli; + + return result; +} + /* Return true if a connection is still alive */ static BOOL connection_ok(struct winbindd_cm_conn *conn) @@ -320,13 +345,11 @@ BOOL cm_check_for_native_mode_win2k( const char *domain ) done: -#if 0 - /* - * I don't think we need to shutdown here ? JRA. - */ + /* close the connection; no other cals use this pipe and it is called only + on reestablishing the domain list --jerry */ + if ( conn.cli ) cli_shutdown( conn.cli ); -#endif return ret; } @@ -488,14 +511,14 @@ NTSTATUS cm_get_netlogon_cli(const char *domain, if (!NT_STATUS_IS_OK(result)) return result; - snprintf(lock_name, sizeof(lock_name), "NETLOGON\\%s", conn->controller); + fstr_sprintf(lock_name, "NETLOGON\\%s", conn->controller); if (!(got_mutex = secrets_named_mutex(lock_name, WINBIND_SERVER_MUTEX_WAIT_TIME))) { DEBUG(0,("cm_get_netlogon_cli: mutex grab failed for %s\n", conn->controller)); } if ( sec_channel_type == SEC_CHAN_DOMAIN ) - snprintf(conn->cli->mach_acct, sizeof(conn->cli->mach_acct) - 1, "%s$", lp_workgroup()); + fstr_sprintf(conn->cli->mach_acct, "%s$", lp_workgroup()); result = cli_nt_establish_netlogon(conn->cli, sec_channel_type, trust_passwd); diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index d67d48d506..96c121685a 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -232,7 +232,7 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) /* Ensure null termination */ state->request.data.groupname[sizeof(state->request.data.groupname)-1]='\0'; - DEBUG(3, ("[%5d]: getgrnam %s\n", state->pid, + DEBUG(3, ("[%5lu]: getgrnam %s\n", (unsigned long)state->pid, state->request.data.groupname)); /* Parse domain and groupname */ @@ -334,8 +334,8 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state) int gr_mem_len; char *gr_mem; - DEBUG(3, ("[%5d]: getgrgid %d\n", state->pid, - state->request.data.gid)); + DEBUG(3, ("[%5lu]: getgrgid %lu\n", (unsigned long)state->pid, + (unsigned long)state->request.data.gid)); /* Bug out if the gid isn't in the winbind range */ @@ -360,8 +360,8 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state) /* Get rid from gid */ if (!NT_STATUS_IS_OK(idmap_gid_to_sid(&group_sid, state->request.data.gid))) { - DEBUG(1, ("could not convert gid %d to rid\n", - state->request.data.gid)); + DEBUG(1, ("could not convert gid %lu to rid\n", + (unsigned long)state->request.data.gid)); return WINBINDD_ERROR; } @@ -416,7 +416,7 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state) { struct winbindd_domain *domain; - DEBUG(3, ("[%5d]: setgrent\n", state->pid)); + DEBUG(3, ("[%5lu]: setgrent\n", (unsigned long)state->pid)); /* Check user has enabled this */ @@ -469,7 +469,7 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state) enum winbindd_result winbindd_endgrent(struct winbindd_cli_state *state) { - DEBUG(3, ("[%5d]: endgrent\n", state->pid)); + DEBUG(3, ("[%5lu]: endgrent\n", (unsigned long)state->pid)); free_getent_state(state->getgrent_state); state->getgrent_state = NULL; @@ -605,7 +605,7 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state) int num_groups, group_list_ndx = 0, i, gr_mem_list_len = 0; char *new_extra_data, *gr_mem_list = NULL; - DEBUG(3, ("[%5d]: getgrent\n", state->pid)); + DEBUG(3, ("[%5lu]: getgrent\n", (unsigned long)state->pid)); /* Check user has enabled this */ @@ -691,7 +691,7 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state) goto tryagain; } - DEBUG(10, ("got gid %d for group %x\n", group_gid, + DEBUG(10, ("got gid %lu for group %x\n", (unsigned long)group_gid, name_list[ent->sam_entry_index].rid)); /* Fill in group entry */ @@ -825,7 +825,7 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state) char *ted = NULL; unsigned int extra_data_len = 0, i; - DEBUG(3, ("[%5d]: list groups\n", state->pid)); + DEBUG(3, ("[%5lu]: list groups\n", (unsigned long)state->pid)); /* Enumerate over trusted domains */ @@ -915,7 +915,7 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) /* Ensure null termination */ state->request.data.username[sizeof(state->request.data.username)-1]='\0'; - DEBUG(3, ("[%5d]: getgroups %s\n", state->pid, + DEBUG(3, ("[%5lu]: getgroups %s\n", (unsigned long)state->pid, state->request.data.username)); if (!(mem_ctx = talloc_init("winbindd_getgroups(%s)", @@ -1009,9 +1009,9 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) /* We've jumped through a lot of hoops to get here */ DEBUG(10, ("winbindd_getgroups: mapped other sid %s to " - "gid %d\n", sid_string_static( + "gid %lu\n", sid_string_static( &info3->other_sids[i].sid), - gid_list[num_gids])); + (unsigned long)gid_list[num_gids])); num_gids++; } diff --git a/source3/nsswitch/winbindd_misc.c b/source3/nsswitch/winbindd_misc.c index 8d7cdc4731..740b760b93 100644 --- a/source3/nsswitch/winbindd_misc.c +++ b/source3/nsswitch/winbindd_misc.c @@ -35,7 +35,7 @@ enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *stat int num_retries = 0; struct cli_state *cli; uint32 sec_channel_type; - DEBUG(3, ("[%5d]: check machine account\n", state->pid)); + DEBUG(3, ("[%5lu]: check machine account\n", (unsigned long)state->pid)); /* Get trust account password */ @@ -95,7 +95,7 @@ enum winbindd_result winbindd_list_trusted_domains(struct winbindd_cli_state int total_entries = 0, extra_data_len = 0; char *ted, *extra_data = NULL; - DEBUG(3, ("[%5d]: list trusted domains\n", state->pid)); + DEBUG(3, ("[%5lu]: list trusted domains\n", (unsigned long)state->pid)); /* We need to refresh the trusted domain list as the domains may have changed since we last looked. There may be a sequence @@ -149,7 +149,7 @@ enum winbindd_result winbindd_show_sequence(struct winbindd_cli_state *state) struct winbindd_domain *domain; char *extra_data = NULL; - DEBUG(3, ("[%5d]: show sequence\n", state->pid)); + DEBUG(3, ("[%5lu]: show sequence\n", (unsigned long)state->pid)); extra_data = strdup(""); @@ -181,7 +181,7 @@ enum winbindd_result winbindd_show_sequence(struct winbindd_cli_state *state) enum winbindd_result winbindd_ping(struct winbindd_cli_state *state) { - DEBUG(3, ("[%5d]: ping\n", state->pid)); + DEBUG(3, ("[%5lu]: ping\n", (unsigned long)state->pid)); return WINBINDD_OK; } @@ -191,7 +191,7 @@ enum winbindd_result winbindd_ping(struct winbindd_cli_state enum winbindd_result winbindd_info(struct winbindd_cli_state *state) { - DEBUG(3, ("[%5d]: request misc info\n", state->pid)); + DEBUG(3, ("[%5lu]: request misc info\n", (unsigned long)state->pid)); state->response.data.info.winbind_separator = *lp_winbind_separator(); fstrcpy(state->response.data.info.samba_version, VERSION); @@ -204,7 +204,7 @@ enum winbindd_result winbindd_info(struct winbindd_cli_state *state) enum winbindd_result winbindd_interface_version(struct winbindd_cli_state *state) { - DEBUG(3, ("[%5d]: request interface version\n", state->pid)); + DEBUG(3, ("[%5lu]: request interface version\n", (unsigned long)state->pid)); state->response.data.interface_version = WINBIND_INTERFACE_VERSION; @@ -216,7 +216,7 @@ enum winbindd_result winbindd_interface_version(struct winbindd_cli_state *state enum winbindd_result winbindd_domain_name(struct winbindd_cli_state *state) { - DEBUG(3, ("[%5d]: request domain name\n", state->pid)); + DEBUG(3, ("[%5lu]: request domain name\n", (unsigned long)state->pid)); fstrcpy(state->response.data.domain_name, lp_workgroup()); @@ -228,7 +228,7 @@ enum winbindd_result winbindd_domain_name(struct winbindd_cli_state *state) enum winbindd_result winbindd_netbios_name(struct winbindd_cli_state *state) { - DEBUG(3, ("[%5d]: request netbios name\n", state->pid)); + DEBUG(3, ("[%5lu]: request netbios name\n", (unsigned long)state->pid)); fstrcpy(state->response.data.netbios_name, global_myname()); @@ -240,7 +240,7 @@ enum winbindd_result winbindd_netbios_name(struct winbindd_cli_state *state) enum winbindd_result winbindd_priv_pipe_dir(struct winbindd_cli_state *state) { - DEBUG(3, ("[%5d]: request location of privileged pipe\n", state->pid)); + DEBUG(3, ("[%5lu]: request location of privileged pipe\n", (unsigned long)state->pid)); state->response.extra_data = strdup(get_winbind_priv_pipe_dir()); if (!state->response.extra_data) diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index 8df0f621c0..a8908487c1 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -53,55 +53,6 @@ static NTSTATUS append_info3_as_ndr(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } -/******************************************************************* - wrapper around retreiving the trsut account password -*******************************************************************/ - -static BOOL get_trust_pw(const char *domain, uint8 ret_pwd[16], - time_t *pass_last_set_time, uint32 *channel) -{ - DOM_SID sid; - char *pwd; - - /* if we are a DC and this is not our domain, then lookup an account - for the domain trust */ - - if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains() ) - { - if ( !secrets_fetch_trusted_domain_password(domain, &pwd, &sid, - pass_last_set_time) ) - { - DEBUG(0, ("get_trust_pw: could not fetch trust account " - "password for trusted domain %s\n", domain)); - return False; - } - - *channel = SEC_CHAN_DOMAIN; - E_md4hash(pwd, ret_pwd); - SAFE_FREE(pwd); - - return True; - } - else /* just get the account for our domain (covers - ROLE_DOMAIN_MEMBER as well */ - { - /* get the machine trust account for our domain */ - - if ( !secrets_fetch_trust_account_password (lp_workgroup(), ret_pwd, - pass_last_set_time, channel) ) - { - DEBUG(0, ("get_trust_pw: could not fetch trust account " - "password for my domain %s\n", domain)); - return False; - } - - return True; - } - - /* Failure */ - return False; -} - /********************************************************************** Authenticate a user with a clear test password **********************************************************************/ @@ -131,7 +82,7 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) /* Ensure null termination */ state->request.data.auth.pass[sizeof(state->request.data.auth.pass)-1]='\0'; - DEBUG(3, ("[%5d]: pam auth %s\n", state->pid, + DEBUG(3, ("[%5lu]: pam auth %s\n", (unsigned long)state->pid, state->request.data.auth.user)); if (!(mem_ctx = talloc_init("winbind pam auth for %s", state->request.data.auth.user))) { @@ -305,7 +256,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) goto done; } - DEBUG(3, ("[%5d]: pam auth crap domain: %s user: %s\n", state->pid, + DEBUG(3, ("[%5lu]: pam auth crap domain: %s user: %s\n", (unsigned long)state->pid, domain, user)); if ( !get_trust_pw(domain, trust_passwd, &last_change_time, &sec_channel_type) ) { @@ -436,7 +387,7 @@ enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state) fstring domain, user; CLI_POLICY_HND *hnd; - DEBUG(3, ("[%5d]: pam chauthtok %s\n", state->pid, + DEBUG(3, ("[%5lu]: pam chauthtok %s\n", (unsigned long)state->pid, state->request.data.chauthtok.user)); /* Setup crap */ diff --git a/source3/nsswitch/winbindd_sid.c b/source3/nsswitch/winbindd_sid.c index 676beae3aa..98a6fce24b 100644 --- a/source3/nsswitch/winbindd_sid.c +++ b/source3/nsswitch/winbindd_sid.c @@ -39,7 +39,7 @@ enum winbindd_result winbindd_lookupsid(struct winbindd_cli_state *state) /* Ensure null termination */ state->request.data.sid[sizeof(state->request.data.sid)-1]='\0'; - DEBUG(3, ("[%5d]: lookupsid %s\n", state->pid, + DEBUG(3, ("[%5lu]: lookupsid %s\n", (unsigned long)state->pid, state->request.data.sid)); /* Lookup sid from PDC using lsa_lookup_sids() */ @@ -90,7 +90,7 @@ enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state) /* Ensure null termination */ state->request.data.sid[sizeof(state->request.data.name.name)-1]='\0'; - DEBUG(3, ("[%5d]: lookupname %s%s%s\n", state->pid, + DEBUG(3, ("[%5lu]: lookupname %s%s%s\n", (unsigned long)state->pid, state->request.data.name.dom_name, lp_winbind_separator(), state->request.data.name.name)); @@ -127,7 +127,7 @@ enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state) /* Ensure null termination */ state->request.data.sid[sizeof(state->request.data.sid)-1]='\0'; - DEBUG(3, ("[%5d]: sid to uid %s\n", state->pid, + DEBUG(3, ("[%5lu]: sid to uid %s\n", (unsigned long)state->pid, state->request.data.sid)); /* Split sid into domain sid and user rid */ @@ -159,7 +159,7 @@ enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state) /* Ensure null termination */ state->request.data.sid[sizeof(state->request.data.sid)-1]='\0'; - DEBUG(3, ("[%5d]: sid to gid %s\n", state->pid, + DEBUG(3, ("[%5lu]: sid to gid %s\n", (unsigned long)state->pid, state->request.data.sid)); if (!string_to_sid(&sid, state->request.data.sid)) { @@ -192,13 +192,13 @@ enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state) return WINBINDD_ERROR; } - DEBUG(3, ("[%5d]: uid to sid %d\n", state->pid, - state->request.data.uid)); + DEBUG(3, ("[%5lu]: uid to sid %lu\n", (unsigned long)state->pid, + (unsigned long)state->request.data.uid)); /* Lookup rid for this uid */ if (!NT_STATUS_IS_OK(idmap_uid_to_sid(&sid, state->request.data.uid))) { - DEBUG(1, ("Could not convert uid %d to rid\n", - state->request.data.uid)); + DEBUG(1, ("Could not convert uid %lu to rid\n", + (unsigned long)state->request.data.uid)); return WINBINDD_ERROR; } @@ -221,13 +221,13 @@ enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state) return WINBINDD_ERROR; } - DEBUG(3, ("[%5d]: gid to sid %d\n", state->pid, - state->request.data.gid)); + DEBUG(3, ("[%5lu]: gid to sid %lu\n", (unsigned long)state->pid, + (unsigned long)state->request.data.gid)); /* Lookup sid for this uid */ if (!NT_STATUS_IS_OK(idmap_gid_to_sid(&sid, state->request.data.gid))) { - DEBUG(1, ("Could not convert gid %d to sid\n", - state->request.data.gid)); + DEBUG(1, ("Could not convert gid %lu to sid\n", + (unsigned long)state->request.data.gid)); return WINBINDD_ERROR; } diff --git a/source3/nsswitch/winbindd_user.c b/source3/nsswitch/winbindd_user.c index c49c41687b..c0b0d94167 100644 --- a/source3/nsswitch/winbindd_user.c +++ b/source3/nsswitch/winbindd_user.c @@ -108,7 +108,7 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state) /* Ensure null termination */ state->request.data.username[sizeof(state->request.data.username)-1]='\0'; - DEBUG(3, ("[%5d]: getpwnam %s\n", state->pid, + DEBUG(3, ("[%5lu]: getpwnam %s\n", (unsigned long)state->pid, state->request.data.username)); /* Parse domain and username */ @@ -131,7 +131,7 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state) /* should we deal with users for our domain? */ if ( lp_winbind_trusted_domains_only() && strequal(name_domain, lp_workgroup())) { - DEBUG(7,("winbindd_getpenam: My domain -- rejecting getpwnam() for %s\\%s.\n", + DEBUG(7,("winbindd_getpwnam: My domain -- rejecting getpwnam() for %s\\%s.\n", name_domain, name_user)); return WINBINDD_ERROR; } @@ -209,8 +209,8 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state) (state->request.data.uid > server_state.uid_high)) return WINBINDD_ERROR; - DEBUG(3, ("[%5d]: getpwuid %d\n", state->pid, - state->request.data.uid)); + DEBUG(3, ("[%5lu]: getpwuid %lu\n", (unsigned long)state->pid, + (unsigned long)state->request.data.uid)); /* always try local tdb first */ @@ -222,8 +222,8 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state) /* Get rid from uid */ if (!NT_STATUS_IS_OK(idmap_uid_to_sid(&user_sid, state->request.data.uid))) { - DEBUG(1, ("could not convert uid %d to SID\n", - state->request.data.uid)); + DEBUG(1, ("could not convert uid %lu to SID\n", + (unsigned long)state->request.data.uid)); return WINBINDD_ERROR; } @@ -246,8 +246,8 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state) /* Get some user info */ - if (!(mem_ctx = talloc_init("winbind_getpwuid(%d)", - state->request.data.uid))) { + if (!(mem_ctx = talloc_init("winbind_getpwuid(%lu)", + (unsigned long)state->request.data.uid))) { DEBUG(1, ("out of memory\n")); return WINBINDD_ERROR; @@ -295,7 +295,7 @@ enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state) { struct winbindd_domain *domain; - DEBUG(3, ("[%5d]: setpwent\n", state->pid)); + DEBUG(3, ("[%5lu]: setpwent\n", (unsigned long)state->pid)); /* Check user has enabled this */ @@ -359,7 +359,7 @@ enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state) enum winbindd_result winbindd_endpwent(struct winbindd_cli_state *state) { - DEBUG(3, ("[%5d]: endpwent\n", state->pid)); + DEBUG(3, ("[%5lu]: endpwent\n", (unsigned long)state->pid)); free_getent_state(state->getpwent_state); state->getpwent_state = NULL; @@ -474,7 +474,7 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state) struct winbindd_pw *user_list; int num_users, user_list_ndx = 0, i; - DEBUG(3, ("[%5d]: getpwent\n", state->pid)); + DEBUG(3, ("[%5lu]: getpwent\n", (unsigned long)state->pid)); /* Check user has enabled this */ @@ -581,7 +581,7 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state) TALLOC_CTX *mem_ctx; enum winbindd_result rv = WINBINDD_ERROR; - DEBUG(3, ("[%5d]: list users\n", state->pid)); + DEBUG(3, ("[%5lu]: list users\n", (unsigned long)state->pid)); if (!(mem_ctx = talloc_init("winbindd_list_users"))) return WINBINDD_ERROR; diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c index 6177c46aef..a810e503a0 100644 --- a/source3/nsswitch/winbindd_util.c +++ b/source3/nsswitch/winbindd_util.c @@ -111,7 +111,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const fstrcpy(domain->name, alt_name); fstrcpy(domain->alt_name, domain_name); } else { - fstrcpy(domain->name, domain_name); + fstrcpy(domain->name, domain_name); if (alt_name) { fstrcpy(domain->alt_name, alt_name); } @@ -174,8 +174,11 @@ void rescan_trusted_domains(BOOL force) char **names; char **alt_names; int num_domains = 0; - DOM_SID *dom_sids; + DOM_SID *dom_sids, null_sid; int i; + struct winbindd_domain *new_domain; + + ZERO_STRUCTP(&null_sid); result = domain->methods->trusted_domains(domain, mem_ctx, &num_domains, &names, &alt_names, &dom_sids); @@ -183,12 +186,34 @@ void rescan_trusted_domains(BOOL force) continue; } - /* Add each domain to the trusted domain list. Each domain inherits - the access methods of its parent */ + /* Add each domain to the trusted domain list */ + for(i = 0; i < num_domains; i++) { DEBUG(10,("Found domain %s\n", names[i])); add_trusted_domain(names[i], alt_names?alt_names[i]:NULL, domain->methods, &dom_sids[i]); + + /* if the SID was empty, we better set it now */ + + if ( sid_equal(&dom_sids[i], &null_sid) ) { + + new_domain = find_domain_from_name(names[i]); + + /* this should never happen */ + if ( !new_domain ) { + DEBUG(0,("rescan_trust_domains: can't find the domain I just added! [%s]\n", + names[i])); + break; + } + + /* call the cache method; which will operate on the winbindd_domain \ + passed in and choose either rpc or ads as appropriate */ + + result = domain->methods->domain_sid( new_domain, &new_domain->sid ); + + if ( NT_STATUS_IS_OK(result) ) + sid_copy( &dom_sids[i], &domain->sid ); + } /* store trusted domain in the cache */ trustdom_cache_store(names[i], alt_names ? alt_names[i] : NULL, @@ -209,7 +234,7 @@ BOOL init_domain_list(void) free_domain_list(); /* Add ourselves as the first entry */ - domain = add_trusted_domain(lp_workgroup(), NULL, &cache_methods, NULL); + domain = add_trusted_domain( lp_workgroup(), NULL, &cache_methods, NULL); if (!secrets_fetch_domain_sid(domain->name, &domain->sid)) { DEBUG(1, ("Could not fetch sid for our domain %s\n", domain->name)); @@ -782,3 +807,53 @@ BOOL winbindd_upgrade_idmap(void) return idmap_convert(idmap_name); } + +/******************************************************************* + wrapper around retrieving the trust account password +*******************************************************************/ + +BOOL get_trust_pw(const char *domain, uint8 ret_pwd[16], + time_t *pass_last_set_time, uint32 *channel) +{ + DOM_SID sid; + char *pwd; + + /* if we are a DC and this is not our domain, then lookup an account + for the domain trust */ + + if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains() ) + { + if ( !secrets_fetch_trusted_domain_password(domain, &pwd, &sid, + pass_last_set_time) ) + { + DEBUG(0, ("get_trust_pw: could not fetch trust account " + "password for trusted domain %s\n", domain)); + return False; + } + + *channel = SEC_CHAN_DOMAIN; + E_md4hash(pwd, ret_pwd); + SAFE_FREE(pwd); + + return True; + } + else /* just get the account for our domain (covers + ROLE_DOMAIN_MEMBER as well */ + { + /* get the machine trust account for our domain */ + + if ( !secrets_fetch_trust_account_password (lp_workgroup(), ret_pwd, + pass_last_set_time, channel) ) + { + DEBUG(0, ("get_trust_pw: could not fetch trust account " + "password for my domain %s\n", domain)); + return False; + } + + return True; + } + + /* Failure */ + return False; +} + diff --git a/source3/nsswitch/winbindd_wins.c b/source3/nsswitch/winbindd_wins.c index 66903e250d..49bee2dc9f 100644 --- a/source3/nsswitch/winbindd_wins.c +++ b/source3/nsswitch/winbindd_wins.c @@ -137,7 +137,7 @@ enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state) /* Ensure null termination */ state->request.data.winsreq[sizeof(state->request.data.winsreq)-1]='\0'; - DEBUG(3, ("[%5d]: wins_byip %s\n", state->pid, + DEBUG(3, ("[%5lu]: wins_byip %s\n", (unsigned long)state->pid, state->request.data.winsreq)); *response = '\0'; @@ -184,7 +184,7 @@ enum winbindd_result winbindd_wins_byname(struct winbindd_cli_state *state) /* Ensure null termination */ state->request.data.winsreq[sizeof(state->request.data.winsreq)-1]='\0'; - DEBUG(3, ("[%5d]: wins_byname %s\n", state->pid, + DEBUG(3, ("[%5lu]: wins_byname %s\n", (unsigned long)state->pid, state->request.data.winsreq)); *response = '\0'; diff --git a/source3/nsswitch/wins.c b/source3/nsswitch/wins.c index 62493ef0a9..87dac60192 100644 --- a/source3/nsswitch/wins.c +++ b/source3/nsswitch/wins.c @@ -86,29 +86,6 @@ static void nss_wins_init(void) load_interfaces(); } -static struct node_status *lookup_byaddr_backend(char *addr, int *count) -{ - int fd; - struct in_addr ip; - struct nmb_name nname; - struct node_status *status; - - if (!initialised) { - nss_wins_init(); - } - - fd = wins_lookup_open_socket_in(); - if (fd == -1) - return NULL; - - make_nmb_name(&nname, "*", 0); - ip = *interpret_addr2(addr); - status = node_status_query(fd,&nname,ip, count); - - close(fd); - return status; -} - static struct in_addr *lookup_byname_backend(const char *name, int *count) { int fd = -1; @@ -149,8 +126,31 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count) return ret; } - #ifdef HAVE_NS_API_H + +static struct node_status *lookup_byaddr_backend(char *addr, int *count) +{ + int fd; + struct in_addr ip; + struct nmb_name nname; + struct node_status *status; + + if (!initialised) { + nss_wins_init(); + } + + fd = wins_lookup_open_socket_in(); + if (fd == -1) + return NULL; + + make_nmb_name(&nname, "*", 0); + ip = *interpret_addr2(addr); + status = node_status_query(fd,&nname,ip, count); + + close(fd); + return status; +} + /* IRIX version */ int init(void) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index dd429fa688..8bd50f35de 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -8,7 +8,7 @@ Copyright (C) Simo Sorce 2001 Copyright (C) Alexander Bokovoy 2002 Copyright (C) Stefan (metze) Metzmacher 2002 - Copyright (C) Anthony Liguori 2003 + Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -292,6 +292,7 @@ typedef struct int restrict_anonymous; int name_cache_timeout; int client_signing; + int server_signing; param_opt_struct *param_opt; } global; @@ -693,15 +694,17 @@ static const struct enum_list enum_smb_signing_vals[] = { {False, "False"}, {False, "0"}, {False, "Off"}, + {False, "disabled"}, {True, "Yes"}, {True, "True"}, {True, "1"}, {True, "On"}, - {Required, "Required"}, - {Required, "Mandatory"}, - {Required, "Force"}, - {Required, "Forced"}, - {Required, "Enforced"}, + {True, "enabled"}, + {Required, "required"}, + {Required, "mandatory"}, + {Required, "force"}, + {Required, "forced"}, + {Required, "enforced"}, {-1, NULL} }; @@ -736,426 +739,431 @@ static const struct enum_list enum_map_to_guest[] = { /* Note: We do not initialise the defaults union - it is not allowed in ANSI C * - * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it - * is implied in current control logic. This may change at some later time. A - * flag value of 0 means - show as development option only. - * * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit * screen in SWAT. This is used to exclude parameters as well as to squash all * parameters that have been duplicated by pseudonyms. + * + * NOTE: To display a parameter in BASIC view set FLAG_BASIC + * Any parameter that does NOT have FLAG_ADVANCED will not disply at all + * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in + * respective views. */ + static struct parm_struct parm_table[] = { - {"Base Options", P_SEP, P_SEPARATOR}, - - {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER}, - {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER}, - {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE}, - {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, handle_workgroup, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, - {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, - {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, - {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, - {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER}, - {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, - {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, - - {"Security Options", P_SEP, P_SEPARATOR}, - - {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, - {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, - {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, - {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER}, - {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER}, - {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER}, - {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, - {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"passdb backend", P_LIST, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, - {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER}, - {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER}, - - {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - - {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, - {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE}, - {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE}, - - {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, - {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, - {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, - {"read list", P_LIST, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, - {"write list", P_LIST, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, - {"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_GLOBAL | FLAG_PRINT}, - {"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, FLAG_ADVANCED | FLAG_DEVELOPER}, - - {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE}, - {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE}, - {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE}, - {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE}, - - {"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 | 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 | 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}, - {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, 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, FLAG_HIDE}, - - {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER}, - {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE}, - - {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE}, - {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER}, - {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_HIDE}, - {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER}, - {"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_HIDE}, - {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL}, - - {"Logging Options", P_SEP, P_SEPARATOR}, - - {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_HIDE}, - {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - - {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_DEVELOPER}, - {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, FLAG_DEVELOPER}, - {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, FLAG_DEVELOPER}, - {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, FLAG_DEVELOPER}, - - {"Protocol Options", P_SEP, P_SEPARATOR}, - - {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER}, - {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER}, - {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER}, - {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER}, - {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, FLAG_DEVELOPER}, - {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER}, - {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER}, - {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - - {"acl compatibility", P_STRING, P_GLOBAL, &Globals.szAclCompat, handle_acl_compatibility, NULL, FLAG_SHARE | FLAG_GLOBAL | FLAG_ADVANCED | FLAG_DEVELOPER}, - {"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE | FLAG_ADVANCED | FLAG_DEVELOPER}, - {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"profile acls", P_BOOL, P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE | FLAG_ADVANCED}, - - {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER}, - {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER}, - {"map acl inherit", P_BOOL, P_LOCAL, &sDefault.bMap_acl_inherit, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, - {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - - {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, - {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER}, - {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_DEVELOPER}, - - {"Tuning Options", P_SEP, P_SEPARATOR}, - - {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, - {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, FLAG_DEVELOPER}, - {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_DEVELOPER}, - {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_DEVELOPER}, - {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"kernel change notify", P_BOOL, P_GLOBAL, &Globals.bKernelChangeNotify, NULL, NULL, FLAG_DEVELOPER}, - - {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER}, - {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_DEVELOPER}, - {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE}, - {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER}, - {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_DEVELOPER}, - {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT}, - {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, FLAG_DEVELOPER}, - - {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, FLAG_DEVELOPER}, - {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_SHARE}, - {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_SHARE}, - {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_SHARE}, - {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER}, - {"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_SHARE}, - {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_SHARE}, - - {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - - {"Printing Options", P_SEP, P_SEPARATOR}, - - {"max reported print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxReportedPrintJobs, NULL, NULL, FLAG_PRINT}, - {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT}, - {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT}, - {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER}, - {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE}, - {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT}, - {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE}, - {"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}, - {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, 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_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}, - - {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - - {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT}, - {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE}, - {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_PRINT}, - {"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_PRINT}, - - {"Filename Handling", P_SEP, P_SEPARATOR}, - {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - - {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"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, FLAG_HIDE}, - {"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}, - {"hide special files", P_BOOL, P_LOCAL, &sDefault.bHideSpecialFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, - {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, - {"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, 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 }, - {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL }, - {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL }, - {"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, FLAG_DEVELOPER}, - - {"Domain Options", P_SEP, P_SEPARATOR}, - - {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, - - {"Logon Options", P_SEP, P_SEPARATOR}, - - {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"set primary group script", P_STRING, P_GLOBAL, &Globals.szSetPrimaryGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - - {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - - {"Browse Options", P_SEP, P_SEPARATOR}, - - {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER}, - {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER}, - {"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 | FLAG_ADVANCED | FLAG_DEVELOPER}, - {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER}, - {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER}, - {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE}, - {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED}, - - {"WINS Options", P_SEP, P_SEPARATOR}, - - {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - - {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, - {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, - {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, + {"Base Options", P_SEP, P_SEPARATOR}, + + {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED}, + {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED}, + {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED}, + {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, + {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, + {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE}, + {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, handle_workgroup, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, +#ifdef WITH_ADS + {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, +#endif + {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, + {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases, NULL, FLAG_ADVANCED}, + {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope, NULL, FLAG_ADVANCED}, + {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED }, + {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, + {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD}, + + {"Security Options", P_SEP, P_SEPARATOR}, + + {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, + {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_ADVANCED}, + {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, + {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_ADVANCED}, + {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED}, + {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED}, + {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED}, + {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED}, + {"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED}, + {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED}, + {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED}, + {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED}, + {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED}, + {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD}, + {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED}, + {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED}, + {"passdb backend", P_LIST, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD}, + {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED}, + {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED}, + {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE}, + {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE}, + {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED}, + + {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED}, + {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED}, + {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED}, + {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED}, + {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED}, + {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED}, + {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED}, + {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED}, + {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED}, + {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED}, + {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED}, + {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED}, + {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED}, + {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED}, + + {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, + {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE}, + {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE}, + + {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, + {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, + {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, + {"read list", P_LIST, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, + {"write list", P_LIST, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, + {"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT}, + {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, + {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, + {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED}, + + {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE}, + {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE}, + {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE}, + {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE}, + + {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, + {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_HIDE}, + {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, + {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, + {"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, + {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, + {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, + {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, + {"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, + {"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, + {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, + {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, + {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, + {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE}, + + {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, + {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE}, + + {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, + {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, + {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_HIDE}, + {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, + {"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_HIDE}, + {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, + + {"Logging Options", P_SEP, P_SEPARATOR}, + + {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_ADVANCED}, + {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_HIDE}, + {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, FLAG_ADVANCED}, + {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, FLAG_ADVANCED}, + {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED}, + + {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, FLAG_ADVANCED}, + {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED}, + {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED}, + {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, FLAG_ADVANCED}, + {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, FLAG_ADVANCED}, + {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, FLAG_ADVANCED}, + + {"Protocol Options", P_SEP, P_SEPARATOR}, + + {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED}, + {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED}, + {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_ADVANCED}, + {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED}, + {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_ADVANCED}, + {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_ADVANCED}, + {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, FLAG_ADVANCED}, + {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_ADVANCED}, + {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_ADVANCED}, + {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED}, + + {"acl compatibility", P_STRING, P_GLOBAL, &Globals.szAclCompat, handle_acl_compatibility, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, FLAG_ADVANCED}, + {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED}, + {"profile acls", P_BOOL, P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, + + {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_ADVANCED}, + {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_ADVANCED}, + {"map acl inherit", P_BOOL, P_LOCAL, &sDefault.bMap_acl_inherit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED}, + {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED}, + + {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD}, + {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED}, + {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED}, + {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED}, + {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED}, + {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED}, + {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_ADVANCED}, + {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED}, + {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED}, + {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_ADVANCED}, + + {"Tuning Options", P_SEP, P_SEPARATOR}, + + {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, FLAG_ADVANCED}, + {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_ADVANCED}, + {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_ADVANCED}, + {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, FLAG_ADVANCED}, + {"kernel change notify", P_BOOL, P_GLOBAL, &Globals.bKernelChangeNotify, NULL, NULL, FLAG_ADVANCED}, + + {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_ADVANCED}, + {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_ADVANCED}, + {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, + {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_ADVANCED}, + {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_ADVANCED}, + {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED}, + {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, + {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, FLAG_ADVANCED}, + + {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, FLAG_ADVANCED}, + {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, + {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, + {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, + {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_ADVANCED}, + {"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, + {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED}, + {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, + + {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED}, + + {"Printing Options", P_SEP, P_SEPARATOR}, + + {"max reported print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxReportedPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, + {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, + {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, + {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, + {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE}, + {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, + {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE}, + {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, + {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, + {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, + {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, + {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, + {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, + {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, + {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, + {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, + + {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED}, + {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED}, + {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED}, + {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, FLAG_ADVANCED}, + {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, FLAG_ADVANCED}, + + {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, + {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE}, + {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, + {"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, + + {"Filename Handling", P_SEP, P_SEPARATOR}, + {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, FLAG_ADVANCED}, + {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED}, + {"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED}, + + {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, FLAG_ADVANCED}, + {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_ADVANCED | FLAG_SHARE}, + {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_HIDE}, + {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"hide special files", P_BOOL, P_LOCAL, &sDefault.bHideSpecialFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL }, + {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL }, + {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL }, + {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_ADVANCED}, + + {"Domain Options", P_SEP, P_SEPARATOR}, + + {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD}, + + {"Logon Options", P_SEP, P_SEPARATOR}, + + {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED}, + {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED}, + {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED}, + {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED}, + {"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, FLAG_ADVANCED}, + {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, FLAG_ADVANCED}, + {"set primary group script", P_STRING, P_GLOBAL, &Globals.szSetPrimaryGroupScript, NULL, NULL, FLAG_ADVANCED}, + {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED}, + {"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, FLAG_ADVANCED}, + {"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, FLAG_ADVANCED}, + + {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED}, + {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED}, + {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED}, + {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED}, + {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED}, + + {"Browse Options", P_SEP, P_SEPARATOR}, + + {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED}, + {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED}, + {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED}, + {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED}, + {"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 | FLAG_ADVANCED}, + {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED}, + {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, FLAG_ADVANCED}, + {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, + {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE}, + {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_ADVANCED}, + + {"WINS Options", P_SEP, P_SEPARATOR}, + + {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED}, + {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED}, + + {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, + {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, + {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED}, + {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD}, + + {"Locking Options", P_SEP, P_SEPARATOR}, + + {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, + {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, + {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, + {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, + + {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, + {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + + {"Ldap Options", P_SEP, P_SEPARATOR}, - {"Locking Options", P_SEP, P_SEPARATOR}, - - {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, - {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, 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_SHARE | FLAG_GLOBAL}, - {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL}, - {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, 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}, - {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, 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}, - - {"Ldap Options", P_SEP, P_SEPARATOR}, - #ifdef WITH_LDAP_SAMCONFIG - {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, 0}, - {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, 0}, + {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, FLAG_ADVANCED}, + {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, FLAG_ADVANCED}, #endif - {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, handle_ldap_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"ldap trust ids", P_BOOL, P_GLOBAL, &Globals.ldap_trust_ids, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - - {"Miscellaneous Options", P_SEP, P_SEPARATOR}, - {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - - {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE}, - {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, handle_ldap_suffix, NULL, FLAG_ADVANCED}, + {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED}, + {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED}, + {"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED}, + {"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED}, + {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, FLAG_ADVANCED}, + {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED}, + {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED}, + {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED}, + {"ldap trust ids", P_BOOL, P_GLOBAL, &Globals.ldap_trust_ids, NULL, NULL, FLAG_ADVANCED}, + {"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED}, + + {"Miscellaneous Options", P_SEP, P_SEPARATOR}, + {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED}, + {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED}, + {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED}, + + {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE}, + {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED}, + {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED}, + {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED}, {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE}, - {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED}, #ifdef WITH_UTMP - {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"utmp", P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, FLAG_ADVANCED}, + {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, FLAG_ADVANCED}, + {"utmp", P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, FLAG_ADVANCED}, #endif - - {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DEVELOPER}, - {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"get quota command", P_STRING, P_GLOBAL, &Globals.szGetQuota, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"set quota command", P_STRING, P_GLOBAL, &Globals.szSetQuota, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER}, - {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"-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, FLAG_SHARE | FLAG_PRINT}, - {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - - {"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_ADVANCED | 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, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"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 filemode", P_BOOL, P_LOCAL, &sDefault.bDosFilemode, 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_SHARE | FLAG_GLOBAL}, - {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - - {"VFS module options", P_SEP, P_SEPARATOR}, - - {"vfs objects", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_SHARE}, - {"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_SHARE | FLAG_HIDE}, - - {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE}, - {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE}, - {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - - {"Winbind options", P_SEP, P_SEPARATOR}, - - {"enable rid algorithm", P_BOOL, P_GLOBAL, &Globals.bEnableRidAlgorithm, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER | FLAG_DEPRECATED}, - {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER }, - {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER }, - {"template primary group", P_STRING, P_GLOBAL, &Globals.szTemplatePrimaryGroup, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"winbind enable local accounts", P_BOOL, P_GLOBAL, &Globals.bWinbindEnableLocalAccounts, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"winbind trusted domains only", P_BOOL, P_GLOBAL, &Globals.bWinbindTrustedDomainsOnly, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - - {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0} + {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED}, + {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED}, + {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, FLAG_ADVANCED}, + {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, FLAG_ADVANCED}, + {"get quota command", P_STRING, P_GLOBAL, &Globals.szGetQuota, NULL, NULL, FLAG_ADVANCED}, + {"set quota command", P_STRING, P_GLOBAL, &Globals.szSetQuota, NULL, NULL, FLAG_ADVANCED}, + {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED}, + {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED}, + {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_ADVANCED}, + {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED}, + {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED}, + {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED}, + {"-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, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, + {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED}, + + {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, + {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, + {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, + {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, + {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, + {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, + {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE }, + {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, + {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, + {"source environment", P_STRING, P_GLOBAL, &Globals.szSourceEnv, handle_source_env, NULL, FLAG_ADVANCED}, + {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, + {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, + {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, + {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"dos filemode", P_BOOL, P_LOCAL, &sDefault.bDosFilemode, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + + {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED}, + {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED}, + + {"VFS module options", P_SEP, P_SEPARATOR}, + + {"vfs objects", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, + {"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_HIDE}, + + + {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, + {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, + {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED}, + + {"Winbind options", P_SEP, P_SEPARATOR}, + + {"enable rid algorithm", P_BOOL, P_GLOBAL, &Globals.bEnableRidAlgorithm, NULL, NULL, FLAG_DEPRECATED}, + {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED}, + {"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED}, + {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED}, + {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED}, + {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED}, + {"template primary group", P_STRING, P_GLOBAL, &Globals.szTemplatePrimaryGroup, NULL, NULL, FLAG_ADVANCED}, + {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED}, + {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED}, + {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED}, + {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED}, + {"winbind enable local accounts", P_BOOL, P_GLOBAL, &Globals.bWinbindEnableLocalAccounts, NULL, NULL, FLAG_ADVANCED}, + {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED}, + {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED}, + {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED}, + {"winbind trusted domains only", P_BOOL, P_GLOBAL, &Globals.bWinbindTrustedDomainsOnly, NULL, NULL, FLAG_ADVANCED}, + + {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0} }; /*************************************************************************** @@ -1860,7 +1868,7 @@ FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS) FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver) FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode) FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport) -FN_LOCAL_BOOL(lp_use_sendfile, bUseSendfile) +FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile) FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls) FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit) FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask) @@ -1885,7 +1893,8 @@ FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time) FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers) FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase) FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout) -FN_GLOBAL_BOOL(lp_client_signing, &Globals.client_signing) +FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing) +FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing) /* local prototypes */ @@ -4286,3 +4295,12 @@ int lp_maxprintjobs(int snum) return maxjobs; } + +/******************************************************************* + Ensure we don't use sendfile if server smb signing is active. +********************************************************************/ + +BOOL lp_use_sendfile(int snum) +{ + return (_lp_use_sendfile(snum) && !srv_is_signing_active()); +} diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 9a99e07d82..e440e064ef 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -1056,7 +1056,7 @@ DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid) unix_pw = sys_getpwuid( uid ); if ( !unix_pw ) { - DEBUG(4,("local_uid_to_sid: host has know idea of uid %d\n", uid)); + DEBUG(4,("local_uid_to_sid: host has know idea of uid %lu\n", (unsigned long)uid)); return NULL; } @@ -1072,8 +1072,8 @@ DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid) if ( ret ) sid_copy( psid, pdb_get_user_sid(sampw) ); else { - DEBUG(4,("local_uid_to_sid: User %s [uid == %d] has no samba account\n", - unix_pw->pw_name, uid)); + DEBUG(4,("local_uid_to_sid: User %s [uid == %lu] has no samba account\n", + unix_pw->pw_name, (unsigned long)uid)); if ( !lp_enable_rid_algorithm() ) return NULL; @@ -1667,8 +1667,8 @@ uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_ /* check to make sure we got it correct */ if (buflen != len) { - DEBUG(0, ("init_buffer_from_sam: somthing odd is going on here: bufflen (%d) != len (%d) in tdb_pack operations!\n", - buflen, len)); + DEBUG(0, ("init_buffer_from_sam: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n", + (unsigned long)buflen, (unsigned long)len)); /* error */ SAFE_FREE (*buf); return (-1); diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c index ba07a4e01c..1505458551 100644 --- a/source3/passdb/pdb_get_set.c +++ b/source3/passdb/pdb_get_set.c @@ -1027,9 +1027,18 @@ BOOL pdb_set_backend_private_data (SAM_ACCOUNT *sampass, void *private_data, if (!sampass) return False; +#if 0 + /* With this check backend_private_data_free_fn is *never* set + as the methods are never set anywhere. What is this + supposed to do ???? + + Volker + */ + /* does this backend 'own' this SAM_ACCOUNT? */ if (my_methods != sampass->private.backend_private_methods) return False; +#endif if (sampass->private.backend_private_data && sampass->private.backend_private_data_free_fn) { sampass->private.backend_private_data_free_fn(&sampass->private.backend_private_data); diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index a4ee4dbd4b..aee6495759 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -104,7 +104,7 @@ struct ldapsam_privates { static void private_data_free_fn(void **result) { - ldap_memfree(*result); + ldap_msgfree(*result); *result = NULL; } @@ -161,10 +161,10 @@ static const char* get_objclass_filter( int schema_ver ) switch( schema_ver ) { case SCHEMAVER_SAMBAACCOUNT: - snprintf( objclass_filter, sizeof(objclass_filter)-1, "(objectclass=%s)", LDAP_OBJ_SAMBAACCOUNT ); + fstr_sprintf( objclass_filter, "(objectclass=%s)", LDAP_OBJ_SAMBAACCOUNT ); break; case SCHEMAVER_SAMBASAMACCOUNT: - snprintf( objclass_filter, sizeof(objclass_filter)-1, "(objectclass=%s)", LDAP_OBJ_SAMBASAMACCOUNT ); + fstr_sprintf( objclass_filter, "(objectclass=%s)", LDAP_OBJ_SAMBASAMACCOUNT ); break; default: DEBUG(0,("pdb_ldapsam: get_objclass_filter(): Invalid schema version specified!\n")); @@ -192,7 +192,7 @@ static int ldapsam_search_suffix_by_name (struct ldapsam_privates *ldap_state, * in the filter expression, replace %u with the real name * so in ldap filter, %u MUST exist :-) */ - snprintf(filter, sizeof(filter)-1, "(&%s%s)", lp_ldap_filter(), + pstr_sprintf(filter, "(&%s%s)", lp_ldap_filter(), get_objclass_filter(ldap_state->schema_ver)); /* @@ -217,7 +217,7 @@ static int ldapsam_search_suffix_by_rid (struct ldapsam_privates *ldap_state, pstring filter; int rc; - snprintf(filter, sizeof(filter)-1, "(&(rid=%i)%s)", rid, + pstr_sprintf(filter, "(&(rid=%i)%s)", rid, get_objclass_filter(ldap_state->schema_ver)); rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result); @@ -236,7 +236,7 @@ static int ldapsam_search_suffix_by_sid (struct ldapsam_privates *ldap_state, int rc; fstring sid_string; - snprintf(filter, sizeof(filter)-1, "(&(%s=%s)%s)", + pstr_sprintf(filter, "(&(%s=%s)%s)", get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID), sid_to_string(sid_string, sid), get_objclass_filter(ldap_state->schema_ver)); @@ -956,7 +956,7 @@ static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update) pstring filter; char **attr_list; - snprintf( filter, sizeof(filter)-1, "(&%s%s)", lp_ldap_filter(), + pstr_sprintf( filter, "(&%s%s)", lp_ldap_filter(), get_objclass_filter(ldap_state->schema_ver)); all_string_sub(filter, "%u", "*", sizeof(pstring)); @@ -1162,7 +1162,7 @@ static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT } /******************************************************************** -Do the actual modification - also change a plaittext passord if +Do the actual modification - also change a plaintext passord if it it set. **********************************************************************/ @@ -1377,6 +1377,7 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_A if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd, element_is_changed)) { DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n")); + ldap_memfree(dn); return NT_STATUS_UNSUCCESSFUL; } @@ -1384,11 +1385,13 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_A DEBUG(4,("mods is empty: nothing to update for user: %s\n", pdb_get_username(newpwd))); ldap_mods_free(mods, True); + ldap_memfree(dn); return NT_STATUS_OK; } ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, element_is_changed); ldap_mods_free(mods,True); + ldap_memfree(dn); if (!NT_STATUS_IS_OK(ret)) { char *ld_error = NULL; @@ -1516,7 +1519,7 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO /* There might be a SID for this account already - say an idmap entry */ - snprintf(filter, sizeof(filter)-1, "(&(%s=%s)(|(objectClass=%s)(objectClass=%s)))", + pstr_sprintf(filter, "(&(%s=%s)(|(objectClass=%s)(objectClass=%s)))", get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID), sid_to_string(sid_string, sid), LDAP_OBJ_IDMAP_ENTRY, @@ -1698,7 +1701,7 @@ static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state, get_attr_key2string( groupmap_attr_list, LDAP_ATTR_CN), temp)) { DEBUG(0, ("Attributes cn not found either " - "for gidNumber(%i)\n",map->gid)); + "for gidNumber(%lu)\n",(unsigned long)map->gid)); return False; } } @@ -1734,7 +1737,7 @@ static BOOL init_ldap_from_group(LDAP *ldap_struct, sid_to_string(tmp, &map->sid); smbldap_make_mod(ldap_struct, existing, mods, get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID), tmp); - snprintf(tmp, sizeof(tmp)-1, "%i", map->sid_name_use); + pstr_sprintf(tmp, "%i", map->sid_name_use); smbldap_make_mod(ldap_struct, existing, mods, get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_TYPE), tmp); @@ -1805,7 +1808,7 @@ static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map, { pstring filter; - snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(%s=%s))", + pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))", LDAP_OBJ_GROUPMAP, get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID), sid_string_static(&sid)); @@ -1821,10 +1824,10 @@ static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map, { pstring filter; - snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(%s=%d))", + pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))", LDAP_OBJ_GROUPMAP, get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER), - gid); + (unsigned long)gid); return ldapsam_getgroup(methods, filter, map); } @@ -1842,7 +1845,7 @@ static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map, return NT_STATUS_NO_MEMORY; } - snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))", + pstr_sprintf(filter, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))", LDAP_OBJ_GROUPMAP, get_attr_key2string(groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), escape_name, get_attr_key2string(groupmap_attr_list, LDAP_ATTR_CN), escape_name); @@ -1861,10 +1864,10 @@ static int ldapsam_search_one_group_by_gid(struct ldapsam_privates *ldap_state, { pstring filter; - snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(%s=%i))", + pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))", LDAP_OBJ_POSIXGROUP, get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER), - gid); + (unsigned long)gid); return ldapsam_search_one_group(ldap_state, filter, result); } @@ -1891,23 +1894,26 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods, if (NT_STATUS_IS_OK(ldapsam_getgrgid(methods, &dummy, map->gid))) { - DEBUG(0, ("Group %i already exists in LDAP\n", map->gid)); + DEBUG(0, ("Group %ld already exists in LDAP\n", (unsigned long)map->gid)); return NT_STATUS_UNSUCCESSFUL; } rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result); if (rc != LDAP_SUCCESS) { + ldap_msgfree(result); return NT_STATUS_UNSUCCESSFUL; } count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result); - if ( count == 0 ) + if ( count == 0 ) { + ldap_msgfree(result); return NT_STATUS_UNSUCCESSFUL; + } if (count > 1) { - DEBUG(2, ("Group %i must exist exactly once in LDAP\n", - map->gid)); + DEBUG(2, ("Group %lu must exist exactly once in LDAP\n", + (unsigned long)map->gid)); ldap_msgfree(result); return NT_STATUS_UNSUCCESSFUL; } @@ -1941,13 +1947,13 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods, char *ld_error = NULL; ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); - DEBUG(0, ("failed to add group %i error: %s (%s)\n", map->gid, + DEBUG(0, ("failed to add group %lu error: %s (%s)\n", (unsigned long)map->gid, ld_error ? ld_error : "(unknown)", ldap_err2string(rc))); SAFE_FREE(ld_error); return NT_STATUS_UNSUCCESSFUL; } - DEBUG(2, ("successfully modified group %i in LDAP\n", map->gid)); + DEBUG(2, ("successfully modified group %lu in LDAP\n", (unsigned long)map->gid)); return NT_STATUS_OK; } @@ -2002,12 +2008,12 @@ static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods, char *ld_error = NULL; ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); - DEBUG(0, ("failed to modify group %i error: %s (%s)\n", map->gid, + DEBUG(0, ("failed to modify group %lu error: %s (%s)\n", (unsigned long)map->gid, ld_error ? ld_error : "(unknown)", ldap_err2string(rc))); SAFE_FREE(ld_error); } - DEBUG(2, ("successfully modified group %i in LDAP\n", map->gid)); + DEBUG(2, ("successfully modified group %lu in LDAP\n", (unsigned long)map->gid)); return NT_STATUS_OK; } @@ -2026,7 +2032,7 @@ static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods, sid_to_string(sidstring, &sid); - snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(%s=%s))", + pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))", LDAP_OBJ_GROUPMAP, LDAP_ATTRIBUTE_SID, sidstring); rc = ldapsam_search_one_group(ldap_state, filter, &result); @@ -2054,7 +2060,7 @@ static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods, BOOL update) int rc; char **attr_list; - snprintf( filter, sizeof(filter)-1, "(objectclass=%s)", LDAP_OBJ_GROUPMAP); + pstr_sprintf( filter, "(objectclass=%s)", LDAP_OBJ_GROUPMAP); attr_list = get_attr_list( groupmap_attr_list ); rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_group_suffix(), LDAP_SCOPE_SUBTREE, filter, diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c index 055e8e71ba..8171b65adc 100644 --- a/source3/passdb/pdb_smbpasswd.c +++ b/source3/passdb/pdb_smbpasswd.c @@ -179,8 +179,25 @@ static FILE *startsmbfilepwent(const char *pfile, enum pwf_access_type type, int DEBUG(10, ("startsmbfilepwent_internal: opening file %s\n", pfile)); if((fp = sys_fopen(pfile, open_mode)) == NULL) { - DEBUG(0, ("startsmbfilepwent_internal: unable to open file %s. Error was %s\n", pfile, strerror(errno) )); - return NULL; + + /* + * If smbpasswd file doesn't exist, then create new one. This helps to avoid + * confusing error msg when adding user account first time. + */ + if (errno == ENOENT) { + if ((fp = sys_fopen(pfile, "a+")) != NULL) { + DEBUG(0, ("startsmbfilepwent_internal: file %s did not exist. File successfully created.\n", pfile)); + + } else { + DEBUG(0, ("startsmbfilepwent_internal: file %s did not exist. Couldn't create new one. Error was: %s", + pfile, strerror(errno))); + return NULL; + } + + } else { + DEBUG(0, ("startsmbfilepwent_internal: unable to open file %s. Error was: %s\n", pfile, strerror(errno))); + return NULL; + } } if (!pw_file_lock(fileno(fp), lock_type, 5, lock_depth)) { diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c index 1078a5bd26..7c2156455a 100644 --- a/source3/passdb/pdb_tdb.c +++ b/source3/passdb/pdb_tdb.c @@ -180,6 +180,24 @@ static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods, SAM_ACCOUNT /* open the accounts TDB */ if (!(pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDONLY, 0600))) { + + if (errno == ENOENT) { + /* + * TDB file doesn't exist, so try to create new one. This is useful to avoid + * confusing error msg when adding user account first time + */ + if (!(pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_CREAT, 0600))) { + DEBUG(0, ("pdb_getsampwnam: TDB passwd (%s) did not exist. File successfully created.\n", + tdb_state->tdbsam_location)); + } else { + DEBUG(0, ("pdb_getsampwnam: TDB passwd (%s) does not exist. Couldn't create new one. Error was: %s\n", + tdb_state->tdbsam_location, strerror(errno))); + } + + /* requested user isn't there anyway */ + nt_status = NT_STATUS_NO_SUCH_USER; + return nt_status; + } DEBUG(0, ("pdb_getsampwnam: Unable to open TDB passwd (%s)!\n", tdb_state->tdbsam_location)); return nt_status; } @@ -419,49 +437,6 @@ done: return (ret); } -#if 0 -/*************************************************************************** - Allocates a new RID and returns it to the caller as a domain sid - - NOTE: Use carefullt, do not waste RIDs they are a limited resource! - - SSS - ***************************************************************************/ - -static NTSTATUS tdbsam_get_next_sid (struct pdb_methods *my_methods, DOM_SID *sid) -{ - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; - TDB_CONTEXT *pwd_tdb; - uint32 rid; - - if (sid == NULL) { - return NT_STATUS_INVALID_PARAMETER; - } - - pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0600); - if (!pwd_tdb) - { - DEBUG(0, ("tdbsam_get_next_sid: Unable to open TDB passwd (%s)!\n", tdb_state->tdbsam_location)); - return NT_STATUS_UNSUCCESSFUL; - } - - rid = BASE_RID; - if (tdb_change_uint32_atomic(pwd_tdb, "RID_COUNTER", &rid, 1)) { - - sid_copy(sid, get_global_sam_sid()); - if (!sid_append_rid(sid, rid)) { - goto done; - } - - ret = NT_STATUS_OK; - } - -done: - tdb_close (pwd_tdb); - return ret; -} -#endif - /*************************************************************************** Modifies an existing SAM_ACCOUNT ****************************************************************************/ diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c index bad8e96865..23413e4026 100644 --- a/source3/passdb/secrets.c +++ b/source3/passdb/secrets.c @@ -195,11 +195,11 @@ const char *trust_keystr(const char *domain) * * @return stored password's key **/ -char *trustdom_keystr(const char *domain) +static char *trustdom_keystr(const char *domain) { - static char* keystr; + static pstring keystr; - asprintf(&keystr, "%s/%s", SECRETS_DOMTRUST_ACCT_PASS, domain); + pstr_sprintf(keystr, "%s/%s", SECRETS_DOMTRUST_ACCT_PASS, domain); strupper_m(keystr); return keystr; diff --git a/source3/printing/notify.c b/source3/printing/notify.c index 479d883134..e2146d5018 100644 --- a/source3/printing/notify.c +++ b/source3/printing/notify.c @@ -164,8 +164,8 @@ static void print_notify_send_messages_to_printer(const char *printer, unsigned } } - DEBUG(5, ("print_notify_send_messages_to_printer: sending %d print notify message%s to printer %s\n", - msg_count, msg_count != 1 ? "s" : "", printer)); + DEBUG(5, ("print_notify_send_messages_to_printer: sending %lu print notify message%s to printer %s\n", + (unsigned long)msg_count, msg_count != 1 ? "s" : "", printer)); /* * Get the list of PID's to send to. @@ -272,8 +272,8 @@ in notify_queue\n", msg->type, msg->field, msg->printer)); /* allocate a new msg structure and copy the fields */ if ( !(pnqueue->msg = (SPOOLSS_NOTIFY_MSG*)talloc(send_ctx, sizeof(SPOOLSS_NOTIFY_MSG))) ) { - DEBUG(0,("send_spoolss_notify2_msg: talloc() of size [%d] failed!\n", - sizeof(SPOOLSS_NOTIFY_MSG))); + DEBUG(0,("send_spoolss_notify2_msg: talloc() of size [%lu] failed!\n", + (unsigned long)sizeof(SPOOLSS_NOTIFY_MSG))); return; } copy_notify2_msg(pnqueue->msg, msg); diff --git a/source3/printing/pcap.c b/source3/printing/pcap.c index 1bdbf4a789..a5fb53a320 100644 --- a/source3/printing/pcap.c +++ b/source3/printing/pcap.c @@ -208,7 +208,7 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername) /* probably a good printer ??? */ free (line); SAFE_FREE(pName); - fclose(pfile); + x_fclose(pfile); return(True); } @@ -222,7 +222,7 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername) /* it's a good virtual printer */ free (line); SAFE_FREE(pName); - fclose(pfile); + x_fclose(pfile); return(True); } break; diff --git a/source3/python/py_common.c b/source3/python/py_common.c index ea092d9370..02d22bbdab 100644 --- a/source3/python/py_common.c +++ b/source3/python/py_common.c @@ -223,7 +223,7 @@ struct cli_state *open_pipe_creds(char *server, PyObject *creds, result = cli_full_connection( &cli, NULL, server, NULL, 0, "IPC$", "IPC", - username, domain, password, 0, NULL); + username, domain, password, 0, Undefined, NULL); if (!NT_STATUS_IS_OK(result)) { *errstr = strdup("error connecting to IPC$ pipe"); diff --git a/source3/python/py_lsa.c b/source3/python/py_lsa.c index c063dcba81..4204f43f7b 100644 --- a/source3/python/py_lsa.c +++ b/source3/python/py_lsa.c @@ -213,6 +213,7 @@ static PyObject *lsa_lookup_sids(PyObject *self, PyObject *args, char **domains, **names; uint32 *types; lsa_policy_hnd_object *hnd = (lsa_policy_hnd_object *)self; + TALLOC_CTX *mem_ctx = NULL; DOM_SID *sids; if (!PyArg_ParseTuple(args, "O", &py_sids)) @@ -223,12 +224,17 @@ static PyObject *lsa_lookup_sids(PyObject *self, PyObject *args, return NULL; } + if (!(mem_ctx = talloc_init("lsa_open_policy"))) { + PyErr_SetString(lsa_error, "unable to init talloc context\n"); + goto done; + } + if (PyList_Check(py_sids)) { /* Convert dictionary to char ** array */ num_sids = PyList_Size(py_sids); - sids = (DOM_SID *)talloc(hnd->mem_ctx, num_sids * sizeof(DOM_SID)); + sids = (DOM_SID *)talloc(mem_ctx, num_sids * sizeof(DOM_SID)); memset(sids, 0, num_sids * sizeof(DOM_SID)); @@ -237,7 +243,8 @@ static PyObject *lsa_lookup_sids(PyObject *self, PyObject *args, if (!string_to_sid(&sids[i], PyString_AsString(obj))) { PyErr_SetString(PyExc_ValueError, "string_to_sid failed"); - return NULL; + result = NULL; + goto done; } } @@ -246,21 +253,23 @@ static PyObject *lsa_lookup_sids(PyObject *self, PyObject *args, /* Just a single element */ num_sids = 1; - sids = (DOM_SID *)talloc(hnd->mem_ctx, sizeof(DOM_SID)); + sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID)); if (!string_to_sid(&sids[0], PyString_AsString(py_sids))) { PyErr_SetString(PyExc_ValueError, "string_to_sid failed"); - return NULL; + result = NULL; + goto done; } } - ntstatus = cli_lsa_lookup_sids(hnd->cli, hnd->mem_ctx, &hnd->pol, + ntstatus = cli_lsa_lookup_sids(hnd->cli, mem_ctx, &hnd->pol, num_sids, sids, &domains, &names, &types); if (!NT_STATUS_IS_OK(ntstatus)) { PyErr_SetObject(lsa_ntstatus, py_ntstatus_tuple(ntstatus)); - return NULL; + result = NULL; + goto done; } result = PyList_New(num_sids); @@ -274,7 +283,11 @@ static PyObject *lsa_lookup_sids(PyObject *self, PyObject *args, PyList_SetItem(result, i, obj); } - + + done: + if (mem_ctx) + talloc_destroy(mem_ctx); + return result; } diff --git a/source3/python/py_ntsec.c b/source3/python/py_ntsec.c index 47524d8e19..3d408e0bda 100644 --- a/source3/python/py_ntsec.c +++ b/source3/python/py_ntsec.c @@ -58,14 +58,14 @@ BOOL py_from_ACE(PyObject **dict, SEC_ACE *ace) return True; } - *dict = PyDict_New(); - - PyDict_SetItemString(*dict, "type", PyInt_FromLong(ace->type)); - PyDict_SetItemString(*dict, "flags", PyInt_FromLong(ace->flags)); - PyDict_SetItemString(*dict, "mask", PyInt_FromLong(ace->info.mask)); + *dict = Py_BuildValue("{sisisi}", "type", ace->type, + "flags", ace->flags, + "mask", ace->info.mask); - if (py_from_SID(&obj, &ace->trustee)) + if (py_from_SID(&obj, &ace->trustee)) { PyDict_SetItemString(*dict, "trustee", obj); + Py_DECREF(obj); + } return True; } @@ -125,10 +125,6 @@ BOOL py_from_ACL(PyObject **dict, SEC_ACL *acl) return True; } - *dict = PyDict_New(); - - PyDict_SetItemString(*dict, "revision", PyInt_FromLong(acl->revision)); - ace_list = PyList_New(acl->num_aces); for (i = 0; i < acl->num_aces; i++) { @@ -138,7 +134,8 @@ BOOL py_from_ACL(PyObject **dict, SEC_ACL *acl) PyList_SetItem(ace_list, i, obj); } - PyDict_SetItemString(*dict, "ace_list", ace_list); + *dict = Py_BuildValue("{sisN}", "revision", acl->revision, + "ace_list", ace_list); return True; } @@ -181,19 +178,29 @@ BOOL py_from_SECDESC(PyObject **dict, SEC_DESC *sd) *dict = PyDict_New(); - PyDict_SetItemString(*dict, "revision", PyInt_FromLong(sd->revision)); + obj = PyInt_FromLong(sd->revision); + PyDict_SetItemString(*dict, "revision", obj); + Py_DECREF(obj); - if (py_from_SID(&obj, sd->owner_sid)) + if (py_from_SID(&obj, sd->owner_sid)) { PyDict_SetItemString(*dict, "owner_sid", obj); + Py_DECREF(obj); + } - if (py_from_SID(&obj, sd->grp_sid)) + if (py_from_SID(&obj, sd->grp_sid)) { PyDict_SetItemString(*dict, "group_sid", obj); + Py_DECREF(obj); + } - if (py_from_ACL(&obj, sd->dacl)) + if (py_from_ACL(&obj, sd->dacl)) { PyDict_SetItemString(*dict, "dacl", obj); + Py_DECREF(obj); + } - if (py_from_ACL(&obj, sd->sacl)) + if (py_from_ACL(&obj, sd->sacl)) { PyDict_SetItemString(*dict, "sacl", obj); + Py_DECREF(obj); + } return True; } diff --git a/source3/python/py_smb.c b/source3/python/py_smb.c index d37b73cceb..bb84a337c9 100644 --- a/source3/python/py_smb.c +++ b/source3/python/py_smb.c @@ -238,7 +238,8 @@ static PyObject *py_smb_query_secdesc(PyObject *self, PyObject *args, if (cli_is_error(cli->cli)) { PyErr_SetString(PyExc_RuntimeError, "query_secdesc failed"); - return NULL; + result = NULL; + goto done; } if (!secdesc) { @@ -342,11 +343,48 @@ static PyMethodDef smb_methods[] = { { "connect", (PyCFunction)py_smb_connect, METH_VARARGS | METH_KEYWORDS, "Connect to a host" }, + /* Other stuff - this should really go into a samba config module + but for the moment let's leave it here. */ + + { "setup_logging", (PyCFunction)py_setup_logging, + METH_VARARGS | METH_KEYWORDS, + "Set up debug logging.\n" +"\n" +"Initialises Samba's debug logging system. One argument is expected which\n" +"is a boolean specifying whether debugging is interactive and sent to stdout\n" +"or logged to a file.\n" +"\n" +"Example:\n" +"\n" +">>> smb.setup_logging(interactive = 1)" }, + + { "get_debuglevel", (PyCFunction)get_debuglevel, + METH_VARARGS, + "Set the current debug level.\n" +"\n" +"Example:\n" +"\n" +">>> smb.get_debuglevel()\n" +"0" }, + + { "set_debuglevel", (PyCFunction)set_debuglevel, + METH_VARARGS, + "Get the current debug level.\n" +"\n" +"Example:\n" +"\n" +">>> smb.set_debuglevel(10)" }, + { NULL } }; static void py_cli_state_dealloc(PyObject* self) { + cli_state_object *cli = (cli_state_object *)self; + + if (cli->cli) + cli_shutdown(cli->cli); + PyObject_Del(self); } @@ -395,5 +433,5 @@ void initsmb(void) py_samba_init(); setup_logging("smb", True); - DEBUGLEVEL = 10; + DEBUGLEVEL = 3; } diff --git a/source3/python/py_winbind.c b/source3/python/py_winbind.c index db66be2321..ebceb95d71 100644 --- a/source3/python/py_winbind.c +++ b/source3/python/py_winbind.c @@ -259,14 +259,14 @@ static PyObject *py_config_dict(void) PyDict_SetItemString(result, "template_shell", PyString_FromString(lp_template_shell())); - /* Winbind uid/gid range */ + /* idmap uid/gid range */ - if (lp_winbind_uid(&ulow, &uhi)) { + if (lp_idmap_uid(&ulow, &uhi)) { PyDict_SetItemString(result, "uid_low", PyInt_FromLong(ulow)); PyDict_SetItemString(result, "uid_high", PyInt_FromLong(uhi)); } - if (lp_winbind_gid(&glow, &ghi)) { + if (lp_idmap_gid(&glow, &ghi)) { PyDict_SetItemString(result, "gid_low", PyInt_FromLong(glow)); PyDict_SetItemString(result, "gid_high", PyInt_FromLong(ghi)); } diff --git a/source3/rpc_client/cli_ds.c b/source3/rpc_client/cli_ds.c index f0edeca000..a7a093328c 100644 --- a/source3/rpc_client/cli_ds.c +++ b/source3/rpc_client/cli_ds.c @@ -22,6 +22,10 @@ /* implementations of client side DsXXX() functions */ +/******************************************************************** + Get information about the server and directory services +********************************************************************/ + NTSTATUS cli_ds_getprimarydominfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, uint16 level, DS_DOMINFO_CTR *ctr) { @@ -40,7 +44,7 @@ NTSTATUS cli_ds_getprimarydominfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, q.level = level; - if (!ds_io_q_getprimdominfo("", &q, &qbuf, 0) + if (!ds_io_q_getprimdominfo("", &qbuf, 0, &q) || !rpc_api_pipe_req(cli, DS_GETPRIMDOMINFO, &qbuf, &rbuf)) { result = NT_STATUS_UNSUCCESSFUL; goto done; @@ -48,7 +52,7 @@ NTSTATUS cli_ds_getprimarydominfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Unmarshall response */ - if (!ds_io_r_getprimdominfo("", &r, &rbuf, 0)) { + if (!ds_io_r_getprimdominfo("", &rbuf, 0, &r)) { result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -71,3 +75,63 @@ done: return result; } + +/******************************************************************** + Enumerate trusted domains in an AD forest +********************************************************************/ + +NTSTATUS cli_ds_enum_domain_trusts(struct cli_state *cli, TALLOC_CTX *mem_ctx, + const char *server, uint32 flags, + DS_DOMAIN_TRUSTS **trusts, uint32 *num_domains) +{ + prs_struct qbuf, rbuf; + DS_Q_ENUM_DOM_TRUSTS q; + DS_R_ENUM_DOM_TRUSTS r; + NTSTATUS result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + init_q_ds_enum_domain_trusts( &q, server, flags ); + + if (!ds_io_q_enum_domain_trusts("", &qbuf, 0, &q) + || !rpc_api_pipe_req(cli, DS_ENUM_DOM_TRUSTS, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!ds_io_r_enum_domain_trusts("", &rbuf, 0, &r)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + result = r.status; + + if ( NT_STATUS_IS_OK(result) ) { + int i; + + *num_domains = r.num_domains; + *trusts = (DS_DOMAIN_TRUSTS*)smb_xmalloc(r.num_domains*sizeof(DS_DOMAIN_TRUSTS)); + + memcpy( *trusts, r.domains.trusts, r.num_domains*sizeof(DS_DOMAIN_TRUSTS) ); + for ( i=0; i<r.num_domains; i++ ) { + copy_unistr2( &(*trusts)[i].netbios_domain, &r.domains.trusts[i].netbios_domain ); + copy_unistr2( &(*trusts)[i].dns_domain, &r.domains.trusts[i].dns_domain ); + } + } + +done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + + diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c index b01cf8ed4a..db873236e4 100644 --- a/source3/rpc_client/cli_lsarpc.c +++ b/source3/rpc_client/cli_lsarpc.c @@ -1257,7 +1257,6 @@ NTSTATUS cli_lsa_remove_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ct POLICY_HND *pol, DOM_SID sid, BOOL removeall, uint32 count, const char **privs_name) { -#if 0 prs_struct qbuf, rbuf; LSA_Q_REMOVE_ACCT_RIGHTS q; LSA_R_REMOVE_ACCT_RIGHTS r; @@ -1291,8 +1290,6 @@ NTSTATUS cli_lsa_remove_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ct done: return result; -#endif - return NT_STATUS_UNSUCCESSFUL; } diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index 831101ed81..7b8cd19174 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -332,8 +332,7 @@ NTSTATUS cli_netlogon_logon_ctrl2(struct cli_state *cli, TALLOC_CTX *mem_ctx, } /**************************************************************************** -Generate the next creds to use. Yuck - this is a cut&paste from another -file. They should be combined at some stage. )-: +Generate the next creds to use. ****************************************************************************/ static void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index d6307ddb46..ebe54c2c06 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -5,6 +5,7 @@ * Copyright (C) Luke Kenneth Casson Leighton 1996-1998, * Copyright (C) Paul Ashton 1998. * Copyright (C) Jeremy Allison 1999. + * Copyright (C) Andrew Bartlett 2003. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -637,7 +638,7 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out, RPC_HDR_AUTH hdr_auth; int auth_len = 0; int auth_type, auth_level; - size_t saved_hdr_offset; + size_t saved_hdr_offset = 0; prs_struct auth_info; prs_init(&auth_info, RPC_HDR_AUTH_LEN, /* we will need at least this much */ @@ -690,14 +691,15 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out, data_blob_free(&request); - } - else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { + } else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { RPC_AUTH_NETSEC_NEG netsec_neg; /* Use lp_workgroup() if domain not specified */ - if (!domain || !domain[0]) + if (!domain || !domain[0]) { + DEBUG(10,("create_rpc_bind_req: no domain; assuming my own\n")); domain = lp_workgroup(); + } init_rpc_auth_netsec_neg(&netsec_neg, domain, my_name); @@ -715,7 +717,8 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out, /* Auth len in the rpc header doesn't include auth_header. */ auth_len = prs_offset(&auth_info) - saved_hdr_offset; } - /* create the request RPC_HDR */ + + /* Create the request RPC_HDR */ init_rpc_hdr(&hdr, RPC_BIND, 0x3, rpc_call_id, RPC_HEADER_LEN + RPC_HDR_RB_LEN + prs_offset(&auth_info), auth_len); @@ -1021,11 +1024,6 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, static const uchar netsec_sig[8] = NETSEC_SIGNATURE; static const uchar nullbytes[8] = { 0,0,0,0,0,0,0,0 }; size_t parse_offset_marker; - if ((cli->auth_info.seq_num & 1) != 0) { - DEBUG(0,("SCHANNEL ERROR: seq_num must be even in client (seq_num=%d)\n", - cli->auth_info.seq_num)); - } - DEBUG(10,("SCHANNEL seq_num=%d\n", cli->auth_info.seq_num)); init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes, @@ -1573,9 +1571,6 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan, } } - /* doing schannel, not per-user auth */ - cli->pipe_auth_flags = AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN | AUTH_PIPE_SEAL; - if (!rpc_pipe_bind(cli, PI_NETLOGON, global_myname())) { DEBUG(2,("rpc bind to %s failed\n", PIPE_NETLOGON)); cli_close(cli, cli->nt_pipe_fnum); @@ -1586,6 +1581,57 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan, } +NTSTATUS cli_nt_setup_netsec(struct cli_state *cli, int sec_chan, + const uchar trust_password[16]) +{ + NTSTATUS result; + uint32 neg_flags = 0x000001ff; + cli->pipe_auth_flags = 0; + + if (lp_client_schannel() == False) { + return NT_STATUS_OK; + } + + if (!cli_nt_session_open(cli, PI_NETLOGON)) { + DEBUG(0, ("Could not initialise %s\n", + get_pipe_name_from_index(PI_NETLOGON))); + return NT_STATUS_UNSUCCESSFUL; + } + + if (lp_client_schannel() != False) + neg_flags |= NETLOGON_NEG_SCHANNEL; + + neg_flags |= NETLOGON_NEG_SCHANNEL; + + result = cli_nt_setup_creds(cli, sec_chan, trust_password, + &neg_flags, 2); + + if (!(neg_flags & NETLOGON_NEG_SCHANNEL) + && lp_client_schannel() == True) { + DEBUG(1, ("Could not negotiate SCHANNEL with the DC!\n")); + result = NT_STATUS_UNSUCCESSFUL; + } + + if (!NT_STATUS_IS_OK(result)) { + ZERO_STRUCT(cli->auth_info.sess_key); + ZERO_STRUCT(cli->sess_key); + cli->pipe_auth_flags = 0; + cli_nt_session_close(cli); + return result; + } + + memcpy(cli->auth_info.sess_key, cli->sess_key, + sizeof(cli->auth_info.sess_key)); + + cli->saved_netlogon_pipe_fnum = cli->nt_pipe_fnum; + cli->nt_pipe_fnum = 0; + + /* doing schannel, not per-user auth */ + cli->pipe_auth_flags = AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN | AUTH_PIPE_SEAL; + + return NT_STATUS_OK; +} + const char *cli_pipe_get_name(struct cli_state *cli) { return cli->pipe_name; diff --git a/source3/rpc_client/cli_srvsvc.c b/source3/rpc_client/cli_srvsvc.c index 6cd18f2e43..27349b7295 100644 --- a/source3/rpc_client/cli_srvsvc.c +++ b/source3/rpc_client/cli_srvsvc.c @@ -4,7 +4,7 @@ Copyright (C) Andrew Tridgell 1994-2000 Copyright (C) Luke Kenneth Casson Leighton 1996-2000 Copyright (C) Tim Potter 2001 - Copyright (C) Jim McDonough 2002 + Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/source3/rpc_parse/parse_ds.c b/source3/rpc_parse/parse_ds.c index ab07631831..f954806036 100644 --- a/source3/rpc_parse/parse_ds.c +++ b/source3/rpc_parse/parse_ds.c @@ -1,7 +1,8 @@ /* * Unix SMB/CIFS implementation. * RPC Pipe client / server routines - * Copyright (C) Gerald Carter 2002 + + * Copyright (C) Gerald Carter 2002-2003 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,6 +21,9 @@ #include "includes.h" +/************************************************************************ +************************************************************************/ + static BOOL ds_io_dominfobasic( const char *desc, prs_struct *ps, int depth, DSROLE_PRIMARY_DOMAIN_INFO_BASIC **basic) { DSROLE_PRIMARY_DOMAIN_INFO_BASIC *p = *basic; @@ -68,7 +72,10 @@ static BOOL ds_io_dominfobasic( const char *desc, prs_struct *ps, int depth, DSR } -BOOL ds_io_q_getprimdominfo( const char *desc, DS_Q_GETPRIMDOMINFO *q_u, prs_struct *ps, int depth) +/************************************************************************ +************************************************************************/ + +BOOL ds_io_q_getprimdominfo( const char *desc, prs_struct *ps, int depth, DS_Q_GETPRIMDOMINFO *q_u) { prs_debug(ps, depth, desc, "ds_io_q_getprimdominfo"); depth++; @@ -82,7 +89,10 @@ BOOL ds_io_q_getprimdominfo( const char *desc, DS_Q_GETPRIMDOMINFO *q_u, prs_str return True; } -BOOL ds_io_r_getprimdominfo( const char *desc, DS_R_GETPRIMDOMINFO *r_u, prs_struct *ps, int depth) +/************************************************************************ +************************************************************************/ + +BOOL ds_io_r_getprimdominfo( const char *desc, prs_struct *ps, int depth, DS_R_GETPRIMDOMINFO *r_u) { prs_debug(ps, depth, desc, "ds_io_r_getprimdominfo"); depth++; @@ -120,3 +130,177 @@ BOOL ds_io_r_getprimdominfo( const char *desc, DS_R_GETPRIMDOMINFO *r_u, prs_str return True; } + +/************************************************************************ + initialize a DS_ENUM_DOM_TRUSTS structure +************************************************************************/ + +BOOL init_q_ds_enum_domain_trusts( DS_Q_ENUM_DOM_TRUSTS *q, const char *server, + uint32 flags ) +{ + int len; + + q->flags = flags; + + if ( server && *server ) + q->server_ptr = 1; + else + q->server_ptr = 0; + + len = q->server_ptr ? strlen(server)+1 : 0; + + init_unistr2( &q->server, server, len ); + + return True; +} + +/************************************************************************ +************************************************************************/ + +static BOOL ds_io_domain_trusts( const char *desc, prs_struct *ps, int depth, DS_DOMAIN_TRUSTS *trust) +{ + prs_debug(ps, depth, desc, "ds_io_dom_trusts_ctr"); + depth++; + + if ( !prs_uint32( "netbios_ptr", ps, depth, &trust->netbios_ptr ) ) + return False; + + if ( !prs_uint32( "dns_ptr", ps, depth, &trust->dns_ptr ) ) + return False; + + if ( !prs_uint32( "flags", ps, depth, &trust->flags ) ) + return False; + + if ( !prs_uint32( "parent_index", ps, depth, &trust->parent_index ) ) + return False; + + if ( !prs_uint32( "trust_type", ps, depth, &trust->trust_type ) ) + return False; + + if ( !prs_uint32( "trust_attributes", ps, depth, &trust->trust_attributes ) ) + return False; + + if ( !prs_uint32( "sid_ptr", ps, depth, &trust->sid_ptr ) ) + return False; + + if ( !prs_uint8s(False, "guid", ps, depth, trust->guid.info, GUID_SIZE) ) + return False; + + return True; +} + +/************************************************************************ +************************************************************************/ + +static BOOL ds_io_dom_trusts_ctr( const char *desc, prs_struct *ps, int depth, DS_DOMAIN_TRUSTS_CTR *ctr) +{ + int i; + + prs_debug(ps, depth, desc, "ds_io_dom_trusts_ctr"); + depth++; + + if ( !prs_uint32( "ptr", ps, depth, &ctr->ptr ) ) + return False; + + if ( !prs_uint32( "max_count", ps, depth, &ctr->max_count ) ) + return False; + + /* are we done? */ + + if ( ctr->max_count == 0 ) + return True; + + /* allocate the domain trusts array are parse it */ + + ctr->trusts = (DS_DOMAIN_TRUSTS*)talloc(ps->mem_ctx, sizeof(DS_DOMAIN_TRUSTS)*ctr->max_count); + + if ( !ctr->trusts ) + return False; + + /* this stinks; the static portion o fthe structure is read here and then + we need another loop to read the UNISTR2's and SID's */ + + for ( i=0; i<ctr->max_count;i++ ) { + if ( !ds_io_domain_trusts("domain_trusts", ps, depth, &ctr->trusts[i] ) ) + return False; + } + + for ( i=0; i<ctr->max_count; i++ ) { + + if ( !smb_io_unistr2("netbios_domain", &ctr->trusts[i].netbios_domain, ctr->trusts[i].netbios_ptr, ps, depth) ) + return False; + + if(!prs_align(ps)) + return False; + + if ( !smb_io_unistr2("dns_domain", &ctr->trusts[i].dns_domain, ctr->trusts[i].dns_ptr, ps, depth) ) + return False; + + if(!prs_align(ps)) + return False; + + if ( ctr->trusts[i].sid_ptr ) { + if ( !smb_io_dom_sid2("sid", &ctr->trusts[i].sid, ps, depth ) ) + return False; + } + } + + return True; +} + +/************************************************************************ + initialize a DS_ENUM_DOM_TRUSTS request +************************************************************************/ + +BOOL ds_io_q_enum_domain_trusts( const char *desc, prs_struct *ps, int depth, DS_Q_ENUM_DOM_TRUSTS *q_u) +{ + prs_debug(ps, depth, desc, "ds_io_q_enum_domain_trusts"); + depth++; + + if ( !prs_align(ps) ) + return False; + + if ( !prs_uint32( "server_ptr", ps, depth, &q_u->server_ptr ) ) + return False; + + if ( !smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth) ) + return False; + + if ( !prs_align(ps) ) + return False; + + if ( !prs_uint32( "flags", ps, depth, &q_u->flags ) ) + return False; + + return True; +} + +/************************************************************************ +************************************************************************/ + +BOOL ds_io_r_enum_domain_trusts( const char *desc, prs_struct *ps, int depth, DS_R_ENUM_DOM_TRUSTS *r_u) +{ + prs_debug(ps, depth, desc, "ds_io_r_enum_domain_trusts"); + depth++; + + if(!prs_align(ps)) + return False; + + if ( !prs_uint32( "num_domains", ps, depth, &r_u->num_domains ) ) + return False; + + if ( r_u->num_domains ) { + if ( !ds_io_dom_trusts_ctr("domains", ps, depth, &r_u->domains ) ) + return False; + } + + if(!prs_align(ps)) + return False; + + if ( !prs_ntstatus("status", ps, depth, &r_u->status ) ) + return False; + + return True; +} + + diff --git a/source3/rpc_parse/parse_lsa.c b/source3/rpc_parse/parse_lsa.c index d8c3b4e3c3..07b0da7e9c 100644 --- a/source3/rpc_parse/parse_lsa.c +++ b/source3/rpc_parse/parse_lsa.c @@ -5,7 +5,7 @@ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, * Copyright (C) Paul Ashton 1997, * Copyright (C) Andrew Bartlett 2002, - * Copyright (C) Jim McDonough 2002. + * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -2219,21 +2219,18 @@ BOOL lsa_io_r_query_info2(const char *desc, LSA_R_QUERY_INFO2 *r_c, if(!prs_uint32("ptr", ps, depth, &r_c->ptr)) return False; - - if (r_c->ptr != 0) { - if(!prs_uint16("info_class", ps, depth, &r_c->info_class)) + if(!prs_uint16("info_class", ps, depth, &r_c->info_class)) + return False; + switch(r_c->info_class) { + case 0x000c: + if (!lsa_io_dns_dom_info("info12", &r_c->info.dns_dom_info, + ps, depth)) return False; - switch(r_c->info_class) { - case 0x000c: - if (!lsa_io_dns_dom_info("info12", &r_c->info.dns_dom_info, - ps, depth)) - return False; break; - default: - DEBUG(0,("lsa_io_r_query_info2: unknown info class %d\n", - r_c->info_class)); - return False; - } + default: + DEBUG(0,("lsa_io_r_query_info2: unknown info class %d\n", + r_c->info_class)); + return False; } if(!prs_align(ps)) @@ -2304,19 +2301,6 @@ BOOL lsa_io_r_enum_acct_rights(const char *desc, LSA_R_ENUM_ACCT_RIGHTS *r_c, pr return True; } -/******************************************************************* - Inits an LSA_R_ENUM_ACCT_RIGHTS structure. -********************************************************************/ -void init_r_enum_acct_rights(LSA_R_ENUM_ACCT_RIGHTS *q_r, - uint32 count, - const char **rights) -{ - DEBUG(5, ("init_r_enum_acct_rights\n")); - - q_r->count = count; - init_unistr2_array(&q_r->rights, count, rights); -} - /******************************************************************* Inits an LSA_Q_ADD_ACCT_RIGHTS structure. @@ -2332,6 +2316,7 @@ void init_q_add_acct_rights(LSA_Q_ADD_ACCT_RIGHTS *q_q, q_q->pol = *hnd; init_dom_sid2(&q_q->sid, sid); init_unistr2_array(&q_q->rights, count, rights); + q_q->count = 5; } @@ -2372,21 +2357,11 @@ BOOL lsa_io_r_add_acct_rights(const char *desc, LSA_R_ADD_ACCT_RIGHTS *r_c, prs_ return True; } -/******************************************************************* - Inits an LSA_R_ADD_ACCT_RIGHTS structure. -********************************************************************/ -void init_r_add_acct_rights(LSA_R_ADD_ACCT_RIGHTS *q_r) -{ - DEBUG(5, ("init_r_add_acct_rights\n")); - /* oh what a silly function! */ -} - -#if 0 /******************************************************************* Inits an LSA_Q_REMOVE_ACCT_RIGHTS structure. ********************************************************************/ - void init_q_remove_acct_rights(LSA_Q_REMOVE_ACCT_RIGHTS *q_q, +void init_q_remove_acct_rights(LSA_Q_REMOVE_ACCT_RIGHTS *q_q, POLICY_HND *hnd, DOM_SID *sid, uint32 removeall, @@ -2399,13 +2374,14 @@ void init_r_add_acct_rights(LSA_R_ADD_ACCT_RIGHTS *q_r) init_dom_sid2(&q_q->sid, sid); q_q->removeall = removeall; init_unistr2_array(&q_q->rights, count, rights); + q_q->count = 5; } /******************************************************************* reads or writes a LSA_Q_REMOVE_ACCT_RIGHTS structure. ********************************************************************/ - BOOL lsa_io_q_remove_acct_rights(const char *desc, LSA_Q_REMOVE_ACCT_RIGHTS *q_q, prs_struct *ps, int depth) +BOOL lsa_io_q_remove_acct_rights(const char *desc, LSA_Q_REMOVE_ACCT_RIGHTS *q_q, prs_struct *ps, int depth) { prs_debug(ps, depth, desc, "lsa_io_q_remove_acct_rights"); depth++; @@ -2429,9 +2405,9 @@ reads or writes a LSA_Q_REMOVE_ACCT_RIGHTS structure. } /******************************************************************* -reads or writes a LSA_R_REMOVE_ACCT_RIGHTS structure. +reads or writes a LSA_R_ENUM_ACCT_RIGHTS structure. ********************************************************************/ - BOOL lsa_io_r_remove_acct_rights(const char *desc, LSA_R_REMOVE_ACCT_RIGHTS *r_c, prs_struct *ps, int depth) +BOOL lsa_io_r_remove_acct_rights(const char *desc, LSA_R_REMOVE_ACCT_RIGHTS *r_c, prs_struct *ps, int depth) { prs_debug(ps, depth, desc, "lsa_io_r_remove_acct_rights"); depth++; @@ -2441,90 +2417,3 @@ reads or writes a LSA_R_REMOVE_ACCT_RIGHTS structure. return True; } - -/******************************************************************* - Inits an LSA_R_REMOVE_ACCT_RIGHTS structure. -********************************************************************/ - void init_r_remove_acct_rights(LSA_R_REMOVE_ACCT_RIGHTS *q_r) -{ - DEBUG(5, ("init_r_remove_acct_rights\n")); -} - -/******************************************************************* - Inits an LSA_Q_ENUM_ACCT_WITH_RIGHT structure. -********************************************************************/ - void init_q_enum_acct_with_right(LSA_Q_ENUM_ACCT_WITH_RIGHT *q_q, - POLICY_HND *hnd, - const char *right) -{ - DEBUG(5, ("init_q_enum_acct_with_right\n")); - - q_q->pol = *hnd; - init_unistr2(&q_q->right, right, strlen(right)); - init_str_hdr(&q_q->right_hdr, - q_q->right.uni_max_len*2, - q_q->right.uni_max_len*2, right?1:0); -} - - -/******************************************************************* -reads or writes a LSA_Q_ENUM_ACCT_WITH_RIGHT structure. -********************************************************************/ - BOOL lsa_io_q_enum_acct_with_right(const char *desc, LSA_Q_ENUM_ACCT_WITH_RIGHT *q_q, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_q_enum_acct_with_right"); - depth++; - - if (!smb_io_pol_hnd("", &q_q->pol, ps, depth)) - return False; - - if (!prs_uint32("ref_id ", ps, depth, &q_q->right_hdr.buffer)) - return False; - - if (UNMARSHALLING(ps) && q_q->right_hdr.buffer == 0) { - return True; - } - - if (!smb_io_strhdr("", &q_q->right_hdr, ps, depth)) - return False; - - if (!smb_io_unistr2("", &q_q->right, q_q->right_hdr.buffer, ps, depth)) - return False; - - return True; -} - - -/******************************************************************* -reads or writes a LSA_R_ENUM_ACCT_WITH_RIGHT structure. -********************************************************************/ - BOOL lsa_io_r_enum_acct_with_right(const char *desc, LSA_R_ENUM_ACCT_WITH_RIGHT *r_c, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_r_enum_acct_with_right"); - depth++; - - if (!prs_uint32("count ", ps, depth, &r_c->count)) - return False; - - if (!smb_io_sid_array("sids ", &r_c->sids, ps, depth)) - return False; - - if(!prs_ntstatus("status", ps, depth, &r_c->status)) - return False; - - return True; -} - -/******************************************************************* - Inits an LSA_R_ENUM_ACCT_WITH_RIGHT structure. -********************************************************************/ - void init_r_enum_acct_with_right(LSA_R_ENUM_ACCT_WITH_RIGHT *r_c, - uint32 count, - DOM_SID *sids) -{ - DEBUG(5, ("init_r_enum_acct_with_right\n")); - - r_c->count = count; - init_sid_array(&r_c->sids, count, sids); -} -#endif diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c index efd4914c66..11d8658b15 100644 --- a/source3/rpc_parse/parse_prs.c +++ b/source3/rpc_parse/parse_prs.c @@ -1473,7 +1473,7 @@ void netsec_encode(struct netsec_auth_struct *a, int auth_flags, { uchar digest_final[16]; - DEBUG(10,("SCHANNEL: netsec_encode seq_num=%d data_len=%d\n", a->seq_num, data_len)); + DEBUG(10,("SCHANNEL: netsec_encode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len)); dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key)); RSIVAL(verf->seq_num, 0, a->seq_num); @@ -1544,7 +1544,7 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags, break; } - DEBUG(10,("SCHANNEL: netsec_decode seq_num=%d data_len=%d\n", a->seq_num, data_len)); + DEBUG(10,("SCHANNEL: netsec_decode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len)); dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key)); dump_data_pw("seq_num:\n", seq_num, sizeof(seq_num)); diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index 45c81deb89..fce3195225 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -7,8 +7,7 @@ * Copyright (C) Elrond 2000, * Copyright (C) Jeremy Allison 2001, * Copyright (C) Jean François Micouleau 1998-2001, - * Copyright (C) Anthony Liguori 2002, - * Copyright (C) Jim McDonough 2002. + * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/source3/rpc_server/srv_dfs.c b/source3/rpc_server/srv_dfs.c index 75a24174ea..27bb0732b4 100644 --- a/source3/rpc_server/srv_dfs.c +++ b/source3/rpc_server/srv_dfs.c @@ -5,7 +5,7 @@ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, * Copyright (C) Shirish Kalele 2000, * Copyright (C) Jeremy Allison 2001, - * Copyright (C) Anthony Liguori 2003. + * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/source3/rpc_server/srv_lsa.c b/source3/rpc_server/srv_lsa.c index 679cfb73bb..34812b15d9 100644 --- a/source3/rpc_server/srv_lsa.c +++ b/source3/rpc_server/srv_lsa.c @@ -5,8 +5,7 @@ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, * Copyright (C) Paul Ashton 1997, * Copyright (C) Jeremy Allison 2001, - * Copyright (C) Jim McDonough 2002, - * Copyright (C) Anthony Liguori 2003. + * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002-2003. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index ca3021a876..9eafcb8dc3 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -6,7 +6,7 @@ * Copyright (C) Paul Ashton 1997, * Copyright (C) Jeremy Allison 2001, * Copyright (C) Rafal Szczesniak 2002, - * Copyright (C) Jim McDonough 2002. + * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/source3/rpc_server/srv_netlog.c b/source3/rpc_server/srv_netlog.c index 0cd4073177..d1be2f3723 100644 --- a/source3/rpc_server/srv_netlog.c +++ b/source3/rpc_server/srv_netlog.c @@ -5,7 +5,7 @@ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, * Copyright (C) Paul Ashton 1997, * Copyright (C) Jeremy Allison 1998-2001, - * Copyright (C) Anthony Liguori 2003. + * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c index c4a87d2e26..602cd7d2d5 100644 --- a/source3/rpc_server/srv_netlog_nt.c +++ b/source3/rpc_server/srv_netlog_nt.c @@ -5,7 +5,7 @@ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, * Copyright (C) Paul Ashton 1997. * Copyright (C) Jeremy Allison 1998-2001. - * Copyirht (C) Andrew Bartlett 2001. + * Copyright (C) Andrew Bartlett 2001. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 9a63ebc7a3..594cb3a9ae 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -5,7 +5,7 @@ * Copyright (C) Luke Kenneth Casson Leighton 1996-1998, * Copyright (C) Paul Ashton 1997-1998, * Copyright (C) Jeremy Allison 1999, - * Copyright (C) Anthony Liguori 2003. + * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -277,11 +277,6 @@ BOOL create_next_pdu(pipes_struct *p) prs_init(&rverf, 0, p->mem_ctx, MARSHALL); prs_init(&rauth, 0, p->mem_ctx, MARSHALL); - if ((p->netsec_auth.seq_num & 1) == 0) { - DEBUG(0,("SCHANNEL ERROR: seq_num must be odd in server! (seq_num=%d)\n", - p->netsec_auth.seq_num)); - } - init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes, nullbytes, nullbytes); netsec_encode(&p->netsec_auth, diff --git a/source3/rpc_server/srv_reg.c b/source3/rpc_server/srv_reg.c index 43bb1ad86a..e1a02103f7 100644 --- a/source3/rpc_server/srv_reg.c +++ b/source3/rpc_server/srv_reg.c @@ -7,7 +7,7 @@ * Copyright (C) Marc Jacobsen 2000, * Copyright (C) Jeremy Allison 2001, * Copyright (C) Gerald Carter 2002, - * Copyright (C) Anthony Liguori 2003. + * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/source3/rpc_server/srv_reg_nt.c b/source3/rpc_server/srv_reg_nt.c index 5632544909..a4e3638be6 100644 --- a/source3/rpc_server/srv_reg_nt.c +++ b/source3/rpc_server/srv_reg_nt.c @@ -596,11 +596,11 @@ NTSTATUS _reg_shutdown(pipes_struct *p, REG_Q_SHUTDOWN *q_u, REG_R_SHUTDOWN *r_u /* security check */ alpha_strcpy (chkmsg, message, NULL, sizeof(message)); /* timeout */ - snprintf(timeout, sizeof(timeout), "%d", q_u->timeout); + fstr_sprintf(timeout, "%d", q_u->timeout); /* reboot */ - snprintf(r, sizeof(r), (q_u->reboot) ? SHUTDOWN_R_STRING : ""); + fstr_sprintf(r, (q_u->reboot) ? SHUTDOWN_R_STRING : ""); /* force */ - snprintf(f, sizeof(f), (q_u->force) ? SHUTDOWN_F_STRING : ""); + fstr_sprintf(f, (q_u->force) ? SHUTDOWN_F_STRING : ""); pstrcpy(shutdown_script, lp_shutdown_script()); diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c index 9250b023d3..86ff039683 100644 --- a/source3/rpc_server/srv_samr.c +++ b/source3/rpc_server/srv_samr.c @@ -6,8 +6,7 @@ * Copyright (C) Paul Ashton 1997, * Copyright (C) Marc Jacobsen 1999, * Copyright (C) Jean François Micouleau 1998-2001, - * Copyright (C) Anthony Liguori 2002-2003, - * Copyright (C) Jim McDonough 2002. + * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002-2003. * * Split into interface and implementation modules by, * diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 9324fd4765..14aad5d6f8 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -7,8 +7,7 @@ * Copyright (C) Marc Jacobsen 1999, * Copyright (C) Jeremy Allison 2001-2002, * Copyright (C) Jean François Micouleau 1998-2001, - * Copyright (C) Anthony Liguori 2002, - * Copyright (C) Jim McDonough 2002. + * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1517,17 +1516,17 @@ NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LO NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u) { - fstring user_name; - fstring wks; + fstring user_name; + fstring wks; - DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__)); + DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__)); - r_u->status = NT_STATUS_OK; + r_u->status = NT_STATUS_OK; - rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0); - rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0); + rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0); + rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0); - DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks)); + DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks)); /* * Pass the user through the NT -> unix user mapping @@ -1541,14 +1540,14 @@ NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_ * is case insensitive. */ - r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash, - q_u->nt_newpass.pass, q_u->nt_oldhash.hash); + r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash, + q_u->nt_newpass.pass, q_u->nt_oldhash.hash); - init_samr_r_chgpasswd_user(r_u, r_u->status); + init_samr_r_chgpasswd_user(r_u, r_u->status); - DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__)); + DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__)); - return r_u->status; + return r_u->status; } /******************************************************************* @@ -2259,7 +2258,7 @@ NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_ * now have some sainity-checking to match. */ - DEBUG(10,("checking account %s at pos %d for $ termination\n",account, strlen(account)-1)); + DEBUG(10,("checking account %s at pos %lu for $ termination\n",account, (unsigned long)strlen(account)-1)); /* * we used to have code here that made sure the acb_info flags @@ -2761,8 +2760,9 @@ static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass) grp = getgrgid(gid); if (grp == NULL) { - DEBUG(2,("Could not find primary group %d for " - "user %s\n", gid, pdb_get_username(sampass))); + DEBUG(2,("Could not find primary group %lu for " + "user %s\n", (unsigned long)gid, + pdb_get_username(sampass))); return False; } diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c index 3e9ed9e39f..fa0ca8478c 100755 --- a/source3/rpc_server/srv_spoolss.c +++ b/source3/rpc_server/srv_spoolss.c @@ -6,7 +6,7 @@ * Copyright (C) Jean François Micouleau 1998-2000, * Copyright (C) Jeremy Allison 2001, * Copyright (C) Gerald Carter 2001-2002, - * Copyright (C) Anthony Liguori 2003. + * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 2d316051af..8237298ebb 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -478,7 +478,7 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename) fstring sname; BOOL found=False; - DEBUG(4,("Setting printer name=%s (len=%d)\n", handlename, strlen(handlename))); + DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename, (unsigned long)strlen(handlename))); if (Printer->printer_type==PRINTER_HANDLE_IS_PRINTSERVER) { ZERO_STRUCT(Printer->dev.printerservername); @@ -497,7 +497,7 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename) aprinter=handlename; } - DEBUGADD(5,("searching for [%s] (len=%d)\n", aprinter, strlen(aprinter))); + DEBUGADD(5,("searching for [%s] (len=%lu)\n", aprinter, (unsigned long)strlen(aprinter))); /* * The original code allowed smbd to store a printer name that @@ -563,7 +563,7 @@ static BOOL open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint3 new_printer->notify.option=NULL; - if ( !(new_printer->ctx = talloc_init("Printer Entry [0x%x]", (uint32)hnd)) ) { + if ( !(new_printer->ctx = talloc_init("Printer Entry [%p]", hnd)) ) { DEBUG(0,("open_printer_hnd: talloc_init() failed!\n")); close_printer_handle(p, hnd); return False; @@ -1176,7 +1176,7 @@ static void receive_notify2_message_list(int msg_type, pid_t src, void *msg, siz msg_count = IVAL(buf, 0); msg_ptr = buf + 4; - DEBUG(5, ("receive_notify2_message_list: got %d messages in list\n", msg_count)); + DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count)); if (msg_count == 0) { DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n")); @@ -2393,9 +2393,7 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint if (!StrCaseCmp(value, "DefaultSpoolDirectory")) { - fstring string; - - fstrcpy(string, string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH)); + const char *string="C:\\PRINTERS"; *type = 0x1; *needed = 2*(strlen(string)+1); if((*data = (uint8 *)talloc(ctx, ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL) @@ -2411,7 +2409,7 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint } if (!StrCaseCmp(value, "Architecture")) { - pstring string="Windows NT x86"; + const char *string="Windows NT x86"; *type = 0x1; *needed = 2*(strlen(string)+1); if((*data = (uint8 *)talloc(ctx, ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL) @@ -5135,7 +5133,7 @@ static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const c else pstrcpy( line, v ); - DEBUGADD(6,("%d:%s:%d\n", i, line, strlen(line))); + DEBUGADD(6,("%d:%s:%lu\n", i, line, (unsigned long)strlen(line))); /* add one extra unit16 for the second terminating NULL */ @@ -7912,6 +7910,11 @@ WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP return WERR_BADFID; } + if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER ) { + DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n")); + return WERR_INVALID_PARAM; + } + if (!get_printer_snum(p,handle, &snum)) return WERR_BADFID; @@ -8698,7 +8701,7 @@ WERROR _spoolss_getprinterdataex(pipes_struct *p, SPOOL_Q_GETPRINTERDATAEX *q_u, /* Is the handle to a printer or to the server? */ if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER) { - DEBUG(10,("_spoolss_getprinterdatex: Not implemented for server handles yet\n")); + DEBUG(10,("_spoolss_getprinterdataex: Not implemented for server handles yet\n")); status = WERR_INVALID_PARAM; goto done; } @@ -8780,10 +8783,15 @@ WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u, SetPrinterData if key is "PrinterDriverData" */ if (!Printer) { - DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); + DEBUG(2,("_spoolss_setprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); return WERR_BADFID; } + if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER ) { + DEBUG(10,("_spoolss_setprinterdataex: Not implemented for server handles yet\n")); + return WERR_INVALID_PARAM; + } + if ( !get_printer_snum(p,handle, &snum) ) return WERR_BADFID; @@ -9092,8 +9100,8 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_ { if ( (enum_values=talloc(p->mem_ctx, num_entries*sizeof(PRINTER_ENUM_VALUES))) == NULL ) { - DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%d] bytes!\n", - num_entries*sizeof(PRINTER_ENUM_VALUES))); + DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n", + (unsigned long)num_entries*sizeof(PRINTER_ENUM_VALUES))); result = WERR_NOMEM; goto done; } diff --git a/source3/rpc_server/srv_srvsvc.c b/source3/rpc_server/srv_srvsvc.c index deba122421..0da3cf70dd 100644 --- a/source3/rpc_server/srv_srvsvc.c +++ b/source3/rpc_server/srv_srvsvc.c @@ -5,7 +5,7 @@ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, * Copyright (C) Paul Ashton 1997, * Copyright (C) Jeremy Allison 2001, - * Copyright (C) Anthony Liguori 2003. + * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/source3/rpc_server/srv_wkssvc.c b/source3/rpc_server/srv_wkssvc.c index 8efa29fd0b..856f451779 100644 --- a/source3/rpc_server/srv_wkssvc.c +++ b/source3/rpc_server/srv_wkssvc.c @@ -4,7 +4,7 @@ * Copyright (C) Andrew Tridgell 1992-1997, * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, * Copyright (C) Paul Ashton 1997, - * Copyright (C) Anthony Liguori 2003. + * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/source3/rpcclient/cmd_ds.c b/source3/rpcclient/cmd_ds.c index 4c2f52e291..721bd59ba0 100644 --- a/source3/rpcclient/cmd_ds.c +++ b/source3/rpcclient/cmd_ds.c @@ -47,13 +47,33 @@ static NTSTATUS cmd_ds_dsrole_getprimarydominfo(struct cli_state *cli, return result; } +static NTSTATUS cmd_ds_enum_domain_trusts(struct cli_state *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + NTSTATUS result; + uint32 flags = 0x1; + DS_DOMAIN_TRUSTS *trusts = NULL; + int num_domains = 0; + + result = cli_ds_enum_domain_trusts( cli, mem_ctx, cli->desthost, flags, + &trusts, &num_domains ); + + printf( "%d domains returned\n", num_domains ); + + SAFE_FREE( trusts ); + + return result; +} + /* List of commands exported by this module */ struct cmd_set ds_commands[] = { { "LSARPC-DS" }, - { "dsroledominfo", RPC_RTYPE_NTSTATUS, cmd_ds_dsrole_getprimarydominfo, NULL, PI_LSARPC_DS, "Get Primary Domain Information", "" }, + { "dsroledominfo", RPC_RTYPE_NTSTATUS, cmd_ds_dsrole_getprimarydominfo, NULL, PI_LSARPC_DS, "Get Primary Domain Information", "" }, + { "dsenumdomtrusts", RPC_RTYPE_NTSTATUS, cmd_ds_enum_domain_trusts, NULL, PI_NETLOGON, "Enumerate all trusted domains in an AD forest", "" }, { NULL } }; diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c index 40d01d0f5a..722d66621a 100644 --- a/source3/rpcclient/cmd_samr.c +++ b/source3/rpcclient/cmd_samr.c @@ -125,7 +125,7 @@ static const char *display_time(NTTIME nttime) mins=(sec - (days*60*60*24) - (hours*60*60) ) / 60; secs=sec - (days*60*60*24) - (hours*60*60) - (mins*60); - snprintf(string, sizeof(string)-1, "%u days, %u hours, %u minutes, %u seconds", days, hours, mins, secs); + fstr_sprintf(string, "%u days, %u hours, %u minutes, %u seconds", days, hours, mins, secs); return (string); } diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index af021962f5..831d2beaa4 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -37,21 +37,6 @@ static struct cmd_list { struct cmd_set *cmd_set; } *cmd_list; -/***************************************************************************** - stubb functions -****************************************************************************/ - -void become_root( void ) -{ - return; -} - -void unbecome_root( void ) -{ - return; -} - - /**************************************************************************** handle completion of commands for readline ****************************************************************************/ @@ -370,66 +355,64 @@ static NTSTATUS cmd_none(struct cli_state *cli, TALLOC_CTX *mem_ctx, static NTSTATUS cmd_schannel(struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { + NTSTATUS ret; uchar trust_password[16]; uint32 sec_channel_type; - uint32 neg_flags = 0x000001ff; - NTSTATUS result; static uchar zeros[16]; + if (argc == 2) { + strhex_to_str(cli->auth_info.sess_key, + strlen(argv[1]), + argv[1]); + memcpy(cli->sess_key, cli->auth_info.sess_key, sizeof(cli->sess_key)); + + cli->pipe_auth_flags = AUTH_PIPE_NETSEC; + cli->pipe_auth_flags |= AUTH_PIPE_SIGN; + cli->pipe_auth_flags |= AUTH_PIPE_SEAL; + + return NT_STATUS_OK; + } + /* Cleanup */ - if ((memcmp(cli->auth_info.sess_key, zeros, sizeof(cli->auth_info.sess_key)) != 0) - && (cli->saved_netlogon_pipe_fnum != 0)) { + if ((memcmp(cli->auth_info.sess_key, zeros, sizeof(cli->auth_info.sess_key)) != 0)) { if (cli->pipe_auth_flags == (AUTH_PIPE_NETSEC|AUTH_PIPE_SIGN|AUTH_PIPE_SEAL)) { + /* already in this mode nothing to do */ return NT_STATUS_OK; } else { - /* still have session, just need to use it again */ + /* schannel is setup, just need to use it again */ cli->pipe_auth_flags = AUTH_PIPE_NETSEC; cli->pipe_auth_flags |= AUTH_PIPE_SIGN; cli->pipe_auth_flags |= AUTH_PIPE_SEAL; if (cli->nt_pipe_fnum != 0) cli_nt_session_close(cli); + return NT_STATUS_OK; } } if (cli->nt_pipe_fnum != 0) cli_nt_session_close(cli); - cli->pipe_auth_flags = 0; - + cli->pipe_auth_flags = AUTH_PIPE_NETSEC; + cli->pipe_auth_flags |= AUTH_PIPE_SIGN; + cli->pipe_auth_flags |= AUTH_PIPE_SEAL; + if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_password, NULL, &sec_channel_type)) { return NT_STATUS_UNSUCCESSFUL; } - - if (!cli_nt_session_open(cli, PI_NETLOGON)) { - DEBUG(0, ("Could not initialise %s\n", - get_pipe_name_from_index(PI_NETLOGON))); - return NT_STATUS_UNSUCCESSFUL; - } - - neg_flags |= NETLOGON_NEG_SCHANNEL; - result = cli_nt_setup_creds(cli, sec_channel_type, trust_password, - &neg_flags, 2); - - if (!NT_STATUS_IS_OK(result)) { - ZERO_STRUCT(cli->auth_info.sess_key); - cli->pipe_auth_flags = 0; - return result; + ret = cli_nt_setup_netsec(cli, sec_channel_type, trust_password); + if (NT_STATUS_IS_OK(ret)) { + char *hex_session_key; + hex_encode(cli->auth_info.sess_key, + sizeof(cli->auth_info.sess_key), + &hex_session_key); + printf("Got Session key: %s\n", hex_session_key); + SAFE_FREE(hex_session_key); } - - memcpy(cli->auth_info.sess_key, cli->sess_key, - sizeof(cli->auth_info.sess_key)); - - cli->saved_netlogon_pipe_fnum = cli->nt_pipe_fnum; - - cli->pipe_auth_flags = AUTH_PIPE_NETSEC; - cli->pipe_auth_flags |= AUTH_PIPE_SIGN; - cli->pipe_auth_flags |= AUTH_PIPE_SEAL; - - return NT_STATUS_OK; + return ret; } /* Built in rpcclient commands */ @@ -536,7 +519,9 @@ static NTSTATUS do_cmd(struct cli_state *cli, } } - if ((cmd_entry->pipe_idx == PI_NETLOGON) && !(cli->pipe_auth_flags & AUTH_PIPE_NETSEC)) { + /* some of the DsXXX commands use the netlogon pipe */ + + if (lp_client_schannel() && (cmd_entry->pipe_idx == PI_NETLOGON) && !(cli->pipe_auth_flags & AUTH_PIPE_NETSEC)) { uint32 neg_flags = 0x000001ff; uint32 sec_channel_type; @@ -741,7 +726,8 @@ out_free: opt_ipaddr ? &server_ip : NULL, 0, "IPC$", "IPC", cmdline_auth_info.username, lp_workgroup(), - cmdline_auth_info.password, 0, NULL); + cmdline_auth_info.password, 0, + cmdline_auth_info.signing_state,NULL); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("Cannot connect to server. Error was %s\n", nt_errstr(nt_status))); diff --git a/source3/sam/idmap.c b/source3/sam/idmap.c index 7a8f270e15..4d8b768c2f 100644 --- a/source3/sam/idmap.c +++ b/source3/sam/idmap.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. ID Mapping Copyright (C) Tim Potter 2000 - Copyright (C) Anthony Liguori <aliguor@us.ibm.com> 2003 + Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003 Copyright (C) Simo Sorce 2003 Copyright (C) Jeremy Allison 2003. @@ -153,10 +153,11 @@ NTSTATUS idmap_set_mapping(const DOM_SID *sid, unid_t id, int id_type) struct idmap_methods *map = remote_map; DOM_SID tmp_sid; - DEBUG(10, ("idmap_set_mapping: Set %s to %s %d\n", + DEBUG(10, ("idmap_set_mapping: Set %s to %s %lu\n", sid_string_static(sid), ((id_type & ID_TYPEMASK) == ID_USERID) ? "UID" : "GID", - ((id_type & ID_TYPEMASK) == ID_USERID) ? id.uid : id.gid)); + ((id_type & ID_TYPEMASK) == ID_USERID) ? (unsigned long)id.uid : + (unsigned long)id.gid)); if ( (NT_STATUS_IS_OK(cache_map-> get_sid_from_id(&tmp_sid, id, diff --git a/source3/sam/idmap_tdb.c b/source3/sam/idmap_tdb.c index 7f8dce1f1a..2055103898 100644 --- a/source3/sam/idmap_tdb.c +++ b/source3/sam/idmap_tdb.c @@ -4,7 +4,7 @@ idmap TDB backend Copyright (C) Tim Potter 2000 - Copyright (C) Anthony Liguori 2003 + Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003 Copyright (C) Simo Sorce 2003 This program is free software; you can redistribute it and/or modify @@ -116,7 +116,8 @@ static NTSTATUS db_allocate_id(unid_t *id, int id_type) /* check it is in the range */ if (hwm > idmap_state.uid_high) { - DEBUG(0, ("idmap Fatal Error: UID range full!! (max: %u)\n", idmap_state.uid_high)); + DEBUG(0, ("idmap Fatal Error: UID range full!! (max: %lu)\n", + (unsigned long)idmap_state.uid_high)); return NT_STATUS_UNSUCCESSFUL; } @@ -129,7 +130,8 @@ static NTSTATUS db_allocate_id(unid_t *id, int id_type) /* recheck it is in the range */ if (hwm > idmap_state.uid_high) { - DEBUG(0, ("idmap Fatal Error: UID range full!! (max: %u)\n", idmap_state.uid_high)); + DEBUG(0, ("idmap Fatal Error: UID range full!! (max: %lu)\n", + (unsigned long)idmap_state.uid_high)); return NT_STATUS_UNSUCCESSFUL; } @@ -144,7 +146,8 @@ static NTSTATUS db_allocate_id(unid_t *id, int id_type) /* check it is in the range */ if (hwm > idmap_state.gid_high) { - DEBUG(0, ("idmap Fatal Error: GID range full!! (max: %u)\n", idmap_state.gid_high)); + DEBUG(0, ("idmap Fatal Error: GID range full!! (max: %lu)\n", + (unsigned long)idmap_state.gid_high)); return NT_STATUS_UNSUCCESSFUL; } @@ -158,7 +161,8 @@ static NTSTATUS db_allocate_id(unid_t *id, int id_type) /* recheck it is in the range */ if (hwm > idmap_state.gid_high) { - DEBUG(0, ("idmap Fatal Error: GID range full!! (max: %u)\n", idmap_state.gid_high)); + DEBUG(0, ("idmap Fatal Error: GID range full!! (max: %lu)\n", + (unsigned long)idmap_state.gid_high)); return NT_STATUS_UNSUCCESSFUL; } @@ -185,10 +189,10 @@ static NTSTATUS internal_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type) switch (id_type & ID_TYPEMASK) { case ID_USERID: - slprintf(keystr, sizeof(keystr), "UID %d", id.uid); + slprintf(keystr, sizeof(keystr), "UID %lu", (unsigned long)id.uid); break; case ID_GROUPID: - slprintf(keystr, sizeof(keystr), "GID %d", id.gid); + slprintf(keystr, sizeof(keystr), "GID %lu", (unsigned long)id.gid); break; default: return NT_STATUS_UNSUCCESSFUL; @@ -374,9 +378,11 @@ static NTSTATUS db_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *sid) /* Store the UID side */ /* Store new id */ if (*id_type & ID_USERID) { - slprintf(ugid_str, sizeof(ugid_str), "UID %d", (*id).uid); + slprintf(ugid_str, sizeof(ugid_str), "UID %lu", + (unsigned long)((*id).uid)); } else { - slprintf(ugid_str, sizeof(ugid_str), "GID %d", (*id).gid); + slprintf(ugid_str, sizeof(ugid_str), "GID %lu", + (unsigned long)((*id).gid)); } ugid_data.dptr = ugid_str; @@ -430,9 +436,9 @@ static NTSTATUS db_set_mapping(const DOM_SID *sid, unid_t id, int id_type) ksid.dsize = strlen(ksidstr) + 1; if (id_type & ID_USERID) { - slprintf(kidstr, sizeof(kidstr), "UID %d", id.uid); + slprintf(kidstr, sizeof(kidstr), "UID %lu", (unsigned long)id.uid); } else if (id_type & ID_GROUPID) { - slprintf(kidstr, sizeof(kidstr), "GID %d", id.gid); + slprintf(kidstr, sizeof(kidstr), "GID %lu", (unsigned long)id.gid); } else { return NT_STATUS_INVALID_PARAMETER; } diff --git a/source3/sam/idmap_util.c b/source3/sam/idmap_util.c index f767cc898c..f794ea5173 100644 --- a/source3/sam/idmap_util.c +++ b/source3/sam/idmap_util.c @@ -146,7 +146,7 @@ NTSTATUS idmap_uid_to_sid(DOM_SID *sid, uid_t uid) unid_t id; int flags; - DEBUG(10,("idmap_uid_to_sid: uid = [%d]\n", uid)); + DEBUG(10,("idmap_uid_to_sid: uid = [%lu]\n", (unsigned long)uid)); flags = ID_USERID; id.uid = uid; @@ -164,7 +164,7 @@ NTSTATUS idmap_gid_to_sid(DOM_SID *sid, gid_t gid) unid_t id; int flags; - DEBUG(10,("idmap_gid_to_sid: gid = [%d]\n", gid)); + DEBUG(10,("idmap_gid_to_sid: gid = [%lu]\n", (unsigned long)gid)); flags = ID_GROUPID; #if 0 /* JERRY */ @@ -195,7 +195,7 @@ NTSTATUS idmap_sid_to_uid(const DOM_SID *sid, uid_t *uid, uint32 flags) ret = idmap_get_id_from_sid(&id, &flags, sid); if ( NT_STATUS_IS_OK(ret) ) { - DEBUG(10,("idmap_sid_to_uid: uid = [%d]\n", id.uid)); + DEBUG(10,("idmap_sid_to_uid: uid = [%lu]\n", (unsigned long)id.uid)); *uid = id.uid; } @@ -225,7 +225,7 @@ NTSTATUS idmap_sid_to_gid(const DOM_SID *sid, gid_t *gid, uint32 flags) if ( NT_STATUS_IS_OK(ret) ) { - DEBUG(10,("idmap_sid_to_gid: gid = [%d]\n", id.gid)); + DEBUG(10,("idmap_sid_to_gid: gid = [%lu]\n", (unsigned long)id.gid)); *gid = id.gid; } diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 2802fbb151..fed3a51b88 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -28,16 +28,16 @@ extern char *OutBuffer; *****************************************************************************/ typedef struct { - ubi_slNode msg_next; - int com_type; - files_struct *fsp; - time_t expire_time; - int lock_num; - SMB_BIG_UINT offset; - SMB_BIG_UINT count; - uint16 lock_pid; - char *inbuf; - int length; + ubi_slNode msg_next; + int com_type; + files_struct *fsp; + time_t expire_time; + int lock_num; + SMB_BIG_UINT offset; + SMB_BIG_UINT count; + uint16 lock_pid; + char *inbuf; + int length; } blocking_lock_record; static ubi_slList blocking_lock_queue = { NULL, (ubi_slNodePtr)&blocking_lock_queue, 0}; @@ -48,8 +48,8 @@ static ubi_slList blocking_lock_queue = { NULL, (ubi_slNodePtr)&blocking_lock_qu static void free_blocking_lock_record(blocking_lock_record *blr) { - SAFE_FREE(blr->inbuf); - SAFE_FREE(blr); + SAFE_FREE(blr->inbuf); + SAFE_FREE(blr); } /**************************************************************************** @@ -58,17 +58,17 @@ static void free_blocking_lock_record(blocking_lock_record *blr) static files_struct *get_fsp_from_pkt(char *inbuf) { - switch(CVAL(inbuf,smb_com)) { - case SMBlock: - case SMBlockread: - return file_fsp(inbuf,smb_vwv0); - case SMBlockingX: - return file_fsp(inbuf,smb_vwv2); - default: - DEBUG(0,("get_fsp_from_pkt: PANIC - unknown type on blocking lock queue - exiting.!\n")); - exit_server("PANIC - unknown type on blocking lock queue"); - } - return NULL; /* Keep compiler happy. */ + switch(CVAL(inbuf,smb_com)) { + case SMBlock: + case SMBlockread: + return file_fsp(inbuf,smb_vwv0); + case SMBlockingX: + return file_fsp(inbuf,smb_vwv2); + default: + DEBUG(0,("get_fsp_from_pkt: PANIC - unknown type on blocking lock queue - exiting.!\n")); + exit_server("PANIC - unknown type on blocking lock queue"); + } + return NULL; /* Keep compiler happy. */ } /**************************************************************************** @@ -77,7 +77,7 @@ static files_struct *get_fsp_from_pkt(char *inbuf) static BOOL in_chained_smb(void) { - return (chain_size != 0); + return (chain_size != 0); } static void received_unlock_msg(int msg_type, pid_t src, void *buf, size_t len); @@ -89,66 +89,68 @@ static void received_unlock_msg(int msg_type, pid_t src, void *buf, size_t len); BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num, uint16 lock_pid, SMB_BIG_UINT offset, SMB_BIG_UINT count) { - static BOOL set_lock_msg; - blocking_lock_record *blr; - NTSTATUS status; - - if(in_chained_smb() ) { - DEBUG(0,("push_blocking_lock_request: cannot queue a chained request (currently).\n")); - return False; - } - - /* - * Now queue an entry on the blocking lock queue. We setup - * the expiration time here. - */ - - if((blr = (blocking_lock_record *)malloc(sizeof(blocking_lock_record))) == NULL) { - DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" )); - return False; - } - - if((blr->inbuf = (char *)malloc(length)) == NULL) { - DEBUG(0,("push_blocking_lock_request: Malloc fail (2)!\n" )); - SAFE_FREE(blr); - return False; - } - - blr->com_type = CVAL(inbuf,smb_com); - blr->fsp = get_fsp_from_pkt(inbuf); - blr->expire_time = (lock_timeout == -1) ? (time_t)-1 : time(NULL) + (time_t)lock_timeout; - blr->lock_num = lock_num; - blr->lock_pid = lock_pid; - blr->offset = offset; - blr->count = count; - memcpy(blr->inbuf, inbuf, length); - blr->length = length; - - /* Add a pending lock record for this. */ - status = brl_lock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, - lock_pid, sys_getpid(), blr->fsp->conn->cnum, - offset, count, - PENDING_LOCK); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n")); - free_blocking_lock_record(blr); - return False; - } + static BOOL set_lock_msg; + blocking_lock_record *blr; + NTSTATUS status; + + if(in_chained_smb() ) { + DEBUG(0,("push_blocking_lock_request: cannot queue a chained request (currently).\n")); + return False; + } + + /* + * Now queue an entry on the blocking lock queue. We setup + * the expiration time here. + */ - ubi_slAddTail(&blocking_lock_queue, blr); + if((blr = (blocking_lock_record *)malloc(sizeof(blocking_lock_record))) == NULL) { + DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" )); + return False; + } + + if((blr->inbuf = (char *)malloc(length)) == NULL) { + DEBUG(0,("push_blocking_lock_request: Malloc fail (2)!\n" )); + SAFE_FREE(blr); + return False; + } - /* Ensure we'll receive messages when this is unlocked. */ - if (!set_lock_msg) { - message_register(MSG_SMB_UNLOCK, received_unlock_msg); - set_lock_msg = True; - } + blr->com_type = CVAL(inbuf,smb_com); + blr->fsp = get_fsp_from_pkt(inbuf); + blr->expire_time = (lock_timeout == -1) ? (time_t)-1 : time(NULL) + (time_t)lock_timeout; + blr->lock_num = lock_num; + blr->lock_pid = lock_pid; + blr->offset = offset; + blr->count = count; + memcpy(blr->inbuf, inbuf, length); + blr->length = length; + + /* Add a pending lock record for this. */ + status = brl_lock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, + lock_pid, sys_getpid(), blr->fsp->conn->cnum, + offset, count, PENDING_LOCK); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n")); + free_blocking_lock_record(blr); + return False; + } + + ubi_slAddTail(&blocking_lock_queue, blr); + + /* Ensure we'll receive messages when this is unlocked. */ + if (!set_lock_msg) { + message_register(MSG_SMB_UNLOCK, received_unlock_msg); + set_lock_msg = True; + } - DEBUG(3,("push_blocking_lock_request: lock request length=%d blocked with expiry time %d (+%d) \ + DEBUG(3,("push_blocking_lock_request: lock request length=%d blocked with expiry time %d (+%d) \ for fnum = %d, name = %s\n", length, (int)blr->expire_time, lock_timeout, - blr->fsp->fnum, blr->fsp->fsp_name )); + blr->fsp->fnum, blr->fsp->fsp_name )); - return True; + /* Push the MID of this packet on the signing queue. */ + srv_defer_sign_response(SVAL(inbuf,smb_mid)); + + return True; } /**************************************************************************** @@ -170,27 +172,27 @@ static void send_blocking_reply(char *outbuf, int outsize) static void reply_lockingX_success(blocking_lock_record *blr) { - char *outbuf = OutBuffer; - int bufsize = BUFFER_SIZE; - char *inbuf = blr->inbuf; - int outsize = 0; + char *outbuf = OutBuffer; + int bufsize = BUFFER_SIZE; + char *inbuf = blr->inbuf; + int outsize = 0; - construct_reply_common(inbuf, outbuf); - set_message(outbuf,2,0,True); + construct_reply_common(inbuf, outbuf); + set_message(outbuf,2,0,True); - /* - * As this message is a lockingX call we must handle - * any following chained message correctly. - * This is normally handled in construct_reply(), - * but as that calls switch_message, we can't use - * that here and must set up the chain info manually. - */ + /* + * As this message is a lockingX call we must handle + * any following chained message correctly. + * This is normally handled in construct_reply(), + * but as that calls switch_message, we can't use + * that here and must set up the chain info manually. + */ - outsize = chain_reply(inbuf,outbuf,blr->length,bufsize); + outsize = chain_reply(inbuf,outbuf,blr->length,bufsize); - outsize += chain_size; + outsize += chain_size; - send_blocking_reply(outbuf,outsize); + send_blocking_reply(outbuf,outsize); } /**************************************************************************** @@ -492,18 +494,18 @@ Waiting....\n", static BOOL blocking_lock_record_process(blocking_lock_record *blr) { - switch(blr->com_type) { - case SMBlock: - return process_lock(blr); - case SMBlockread: - return process_lockread(blr); - case SMBlockingX: - return process_lockingX(blr); - default: - DEBUG(0,("blocking_lock_record_process: PANIC - unknown type on blocking lock queue - exiting.!\n")); - exit_server("PANIC - unknown type on blocking lock queue"); - } - return False; /* Keep compiler happy. */ + switch(blr->com_type) { + case SMBlock: + return process_lock(blr); + case SMBlockread: + return process_lockread(blr); + case SMBlockingX: + return process_lockingX(blr); + default: + DEBUG(0,("blocking_lock_record_process: PANIC - unknown type on blocking lock queue - exiting.!\n")); + exit_server("PANIC - unknown type on blocking lock queue"); + } + return False; /* Keep compiler happy. */ } /**************************************************************************** @@ -512,27 +514,27 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr) void remove_pending_lock_requests_by_fid(files_struct *fsp) { - blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); - blocking_lock_record *prev = NULL; + blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); + blocking_lock_record *prev = NULL; - while(blr != NULL) { - if(blr->fsp->fnum == fsp->fnum) { + while(blr != NULL) { + if(blr->fsp->fnum == fsp->fnum) { - DEBUG(10,("remove_pending_lock_requests_by_fid - removing request type %d for \ + DEBUG(10,("remove_pending_lock_requests_by_fid - removing request type %d for \ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); - brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, - blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum, - blr->offset, blr->count, True, NULL, NULL); + brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, + blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum, + blr->offset, blr->count, True, NULL, NULL); - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); - continue; - } + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + continue; + } - prev = blr; - blr = (blocking_lock_record *)ubi_slNext(blr); - } + prev = blr; + blr = (blocking_lock_record *)ubi_slNext(blr); + } } /**************************************************************************** @@ -541,28 +543,28 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); void remove_pending_lock_requests_by_mid(int mid) { - blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); - blocking_lock_record *prev = NULL; + blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); + blocking_lock_record *prev = NULL; - while(blr != NULL) { - if(SVAL(blr->inbuf,smb_mid) == mid) { - files_struct *fsp = blr->fsp; + while(blr != NULL) { + if(SVAL(blr->inbuf,smb_mid) == mid) { + files_struct *fsp = blr->fsp; - DEBUG(10,("remove_pending_lock_requests_by_mid - removing request type %d for \ + DEBUG(10,("remove_pending_lock_requests_by_mid - removing request type %d for \ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); - blocking_lock_reply_error(blr,NT_STATUS_CANCELLED); - brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, - blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum, - blr->offset, blr->count, True, NULL, NULL); - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); - continue; - } - - prev = blr; - blr = (blocking_lock_record *)ubi_slNext(blr); - } + blocking_lock_reply_error(blr,NT_STATUS_CANCELLED); + brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, + blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum, + blr->offset, blr->count, True, NULL, NULL); + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + continue; + } + + prev = blr; + blr = (blocking_lock_record *)ubi_slNext(blr); + } } /**************************************************************************** @@ -611,112 +613,112 @@ unsigned blocking_locks_timeout(unsigned default_timeout) void process_blocking_lock_queue(time_t t) { - blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); - blocking_lock_record *prev = NULL; - - if(blr == NULL) - return; - - /* - * Go through the queue and see if we can get any of the locks. - */ - - while(blr != NULL) { - connection_struct *conn = NULL; - uint16 vuid; - files_struct *fsp = NULL; - - /* - * Ensure we don't have any old chain_fsp values - * sitting around.... - */ - chain_size = 0; - file_chain_reset(); - fsp = blr->fsp; - - conn = conn_find(SVAL(blr->inbuf,smb_tid)); - vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : - SVAL(blr->inbuf,smb_uid); - - DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n", - fsp->fnum, fsp->fsp_name )); - - if((blr->expire_time != -1) && (blr->expire_time <= t)) { - /* - * Lock expired - throw away all previously - * obtained locks and return lock error. - */ - DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n", - fsp->fnum, fsp->fsp_name )); - - brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - blr->lock_pid, sys_getpid(), conn->cnum, - blr->offset, blr->count, True, NULL, NULL); - - blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); - continue; - } - - if(!change_to_user(conn,vuid)) { - DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n", - vuid )); - /* - * Remove the entry and return an error to the client. - */ - blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); - - brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - blr->lock_pid, sys_getpid(), conn->cnum, - blr->offset, blr->count, True, NULL, NULL); - - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); - continue; - } - - if(!set_current_service(conn,True)) { - DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) )); - /* - * Remove the entry and return an error to the client. - */ - blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); - - brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - blr->lock_pid, sys_getpid(), conn->cnum, - blr->offset, blr->count, True, NULL, NULL); - - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); - change_to_root_user(); - continue; - } - - /* - * Go through the remaining locks and try and obtain them. - * The call returns True if all locks were obtained successfully - * and False if we still need to wait. - */ - - if(blocking_lock_record_process(blr)) { - - brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - blr->lock_pid, sys_getpid(), conn->cnum, - blr->offset, blr->count, True, NULL, NULL); - - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); - change_to_root_user(); - continue; - } - - change_to_root_user(); - - /* - * Move to the next in the list. - */ - prev = blr; - blr = (blocking_lock_record *)ubi_slNext(blr); - } + blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); + blocking_lock_record *prev = NULL; + + if(blr == NULL) + return; + + /* + * Go through the queue and see if we can get any of the locks. + */ + + while(blr != NULL) { + connection_struct *conn = NULL; + uint16 vuid; + files_struct *fsp = NULL; + + /* + * Ensure we don't have any old chain_fsp values + * sitting around.... + */ + chain_size = 0; + file_chain_reset(); + fsp = blr->fsp; + + conn = conn_find(SVAL(blr->inbuf,smb_tid)); + vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : + SVAL(blr->inbuf,smb_uid); + + DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n", + fsp->fnum, fsp->fsp_name )); + + if((blr->expire_time != -1) && (blr->expire_time <= t)) { + /* + * Lock expired - throw away all previously + * obtained locks and return lock error. + */ + DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n", + fsp->fnum, fsp->fsp_name )); + + brl_unlock(fsp->dev, fsp->inode, fsp->fnum, + blr->lock_pid, sys_getpid(), conn->cnum, + blr->offset, blr->count, True, NULL, NULL); + + blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + continue; + } + + if(!change_to_user(conn,vuid)) { + DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n", + vuid )); + /* + * Remove the entry and return an error to the client. + */ + blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); + + brl_unlock(fsp->dev, fsp->inode, fsp->fnum, + blr->lock_pid, sys_getpid(), conn->cnum, + blr->offset, blr->count, True, NULL, NULL); + + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + continue; + } + + if(!set_current_service(conn,True)) { + DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) )); + /* + * Remove the entry and return an error to the client. + */ + blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); + + brl_unlock(fsp->dev, fsp->inode, fsp->fnum, + blr->lock_pid, sys_getpid(), conn->cnum, + blr->offset, blr->count, True, NULL, NULL); + + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + change_to_root_user(); + continue; + } + + /* + * Go through the remaining locks and try and obtain them. + * The call returns True if all locks were obtained successfully + * and False if we still need to wait. + */ + + if(blocking_lock_record_process(blr)) { + + brl_unlock(fsp->dev, fsp->inode, fsp->fnum, + blr->lock_pid, sys_getpid(), conn->cnum, + blr->offset, blr->count, True, NULL, NULL); + + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + change_to_root_user(); + continue; + } + + change_to_root_user(); + + /* + * Move to the next in the list. + */ + prev = blr; + blr = (blocking_lock_record *)ubi_slNext(blr); + } } diff --git a/source3/smbd/change_trust_pw.c b/source3/smbd/change_trust_pw.c index 4993e285ca..2eff77b1f7 100644 --- a/source3/smbd/change_trust_pw.c +++ b/source3/smbd/change_trust_pw.c @@ -58,7 +58,7 @@ NTSTATUS change_trust_account_password( const char *domain, const char *remote_m NULL, 0, "IPC$", "IPC", "", "", - "", 0, NULL))) + "", 0, Undefined, NULL))) { DEBUG(0,("modify_trust_password: Connection to %s failed!\n", remote_machine)); nt_status = NT_STATUS_UNSUCCESSFUL; diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c index 5c1d9a79a6..6bc8626d81 100644 --- a/source3/smbd/chgpasswd.c +++ b/source3/smbd/chgpasswd.c @@ -674,6 +674,8 @@ BOOL check_lanman_password(char *user, uchar * pass1, Code to change the lanman hashed password. It nulls out the NT hashed password as it will no longer be valid. + NOTE this function is designed to be called as root. Check the old password + is correct before calling. JRA. ************************************************************/ BOOL change_lanman_password(SAM_ACCOUNT *sampass, uchar *pass2) @@ -730,9 +732,7 @@ BOOL change_lanman_password(SAM_ACCOUNT *sampass, uchar *pass2) } /* Now flush the sam_passwd struct to persistent storage */ - become_root(); ret = pdb_update_sam_account (sampass); - unbecome_root(); return ret; } @@ -740,6 +740,7 @@ BOOL change_lanman_password(SAM_ACCOUNT *sampass, uchar *pass2) /*********************************************************** Code to check and change the OEM hashed password. ************************************************************/ + NTSTATUS pass_oem_change(char *user, uchar * lmdata, uchar * lmhash, uchar * ntdata, uchar * nthash) @@ -747,8 +748,7 @@ NTSTATUS pass_oem_change(char *user, fstring new_passwd; const char *unix_user; SAM_ACCOUNT *sampass = NULL; - NTSTATUS nt_status - = check_oem_password(user, lmdata, lmhash, ntdata, nthash, + NTSTATUS nt_status = check_oem_password(user, lmdata, lmhash, ntdata, nthash, &sampass, new_passwd, sizeof(new_passwd)); if (!NT_STATUS_IS_OK(nt_status)) @@ -765,7 +765,10 @@ NTSTATUS pass_oem_change(char *user, unix_user = pdb_get_username(sampass); + /* We've already checked the old password here.... */ + become_root(); nt_status = change_oem_password(sampass, NULL, new_passwd); + unbecome_root(); memset(new_passwd, 0, sizeof(new_passwd)); @@ -942,6 +945,8 @@ static NTSTATUS check_oem_password(const char *user, /*********************************************************** Code to change the oem password. Changes both the lanman and NT hashes. Old_passwd is almost always NULL. + NOTE this function is designed to be called as root. Check the old password + is correct before calling. JRA. ************************************************************/ NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passwd) @@ -997,9 +1002,7 @@ NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passw } /* Now write it into the file. */ - become_root(); ret = pdb_update_sam_account (hnd); - unbecome_root(); if (!ret) { return NT_STATUS_ACCESS_DENIED; diff --git a/source3/smbd/close.c b/source3/smbd/close.c index 1be13270ba..0700aeaa0a 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -163,8 +163,8 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close) share_entry_count = del_share_mode(fsp, &share_entry); - DEBUG(10,("close_normal_file: share_entry_count = %d for file %s\n", - share_entry_count, fsp->fsp_name )); + DEBUG(10,("close_normal_file: share_entry_count = %lu for file %s\n", + (unsigned long)share_entry_count, fsp->fsp_name )); /* * We delete on close if it's the last open, and the diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index 85e28f5d17..39072f9b91 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -428,6 +428,8 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int } + srv_signing_trans_start(SVAL(inbuf,smb_mid)); + if (pscnt < tpscnt || dscnt < tdscnt) { /* We need to send an interim response then receive the rest of the parameter/data bytes */ @@ -455,6 +457,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int SAFE_FREE(data); SAFE_FREE(setup); END_PROFILE(SMBtrans); + srv_signing_trans_stop(); return(ERROR_DOS(ERRSRV,ERRerror)); } @@ -506,11 +509,10 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int memcpy(data+ddisp,smb_base(inbuf)+doff,dcnt); } } - - + DEBUG(3,("trans <%s> data=%u params=%u setup=%u\n", name,tdscnt,tpscnt,suwcnt)); - + /* * WinCE wierdness.... */ @@ -542,6 +544,8 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int SAFE_FREE(params); SAFE_FREE(setup); + srv_signing_trans_stop(); + if (close_on_completion) close_cnum(conn,vuid); @@ -561,6 +565,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int bad_param: + srv_signing_trans_stop(); DEBUG(0,("reply_trans: invalid trans parameters\n")); SAFE_FREE(data); SAFE_FREE(params); diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c index 04d6a9a8a8..a5f7a7b2ea 100644 --- a/source3/smbd/lanman.c +++ b/source3/smbd/lanman.c @@ -1897,76 +1897,78 @@ static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param char **rdata,char **rparam, int *rdata_len,int *rparam_len) { - char *p = skip_string(param+2,2); - fstring user; - fstring pass1,pass2; + char *p = skip_string(param+2,2); + fstring user; + fstring pass1,pass2; - pull_ascii_fstring(user,p); + pull_ascii_fstring(user,p); - p = skip_string(p,1); + p = skip_string(p,1); - memset(pass1,'\0',sizeof(pass1)); - memset(pass2,'\0',sizeof(pass2)); - memcpy(pass1,p,16); - memcpy(pass2,p+16,16); + memset(pass1,'\0',sizeof(pass1)); + memset(pass2,'\0',sizeof(pass2)); + memcpy(pass1,p,16); + memcpy(pass2,p+16,16); - *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_badpass); - SSVAL(*rparam,2,0); /* converter word */ + SSVAL(*rparam,0,NERR_badpass); + SSVAL(*rparam,2,0); /* converter word */ - DEBUG(3,("Set password for <%s>\n",user)); + DEBUG(3,("Set password for <%s>\n",user)); - /* - * Attempt to verify the old password against smbpasswd entries - * Win98 clients send old and new password in plaintext for this call. - */ + /* + * Attempt to verify the old password against smbpasswd entries + * Win98 clients send old and new password in plaintext for this call. + */ - { - auth_serversupplied_info *server_info = NULL; - DATA_BLOB password = data_blob(pass1, strlen(pass1)+1); - if (NT_STATUS_IS_OK(check_plaintext_password(user,password,&server_info))) { - - if (NT_STATUS_IS_OK(change_oem_password(server_info->sam_account, pass1, pass2))) - { - SSVAL(*rparam,0,NERR_Success); - } - - free_server_info(&server_info); - } - data_blob_clear_free(&password); - } + { + auth_serversupplied_info *server_info = NULL; + DATA_BLOB password = data_blob(pass1, strlen(pass1)+1); - /* - * If the plaintext change failed, attempt - * the old encrypted method. NT will generate this - * after trying the samr method. Note that this - * method is done as a last resort as this - * password change method loses the NT password hash - * and cannot change the UNIX password as no plaintext - * is received. - */ + if (NT_STATUS_IS_OK(check_plaintext_password(user,password,&server_info))) { - if(SVAL(*rparam,0) != NERR_Success) - { - SAM_ACCOUNT *hnd = NULL; + become_root(); + if (NT_STATUS_IS_OK(change_oem_password(server_info->sam_account, pass1, pass2))) { + SSVAL(*rparam,0,NERR_Success); + } + unbecome_root(); - if (check_lanman_password(user,(unsigned char *)pass1,(unsigned char *)pass2, &hnd) && - change_lanman_password(hnd,pass2)) - { - SSVAL(*rparam,0,NERR_Success); - } - pdb_free_sam(&hnd); - } + free_server_info(&server_info); + } + data_blob_clear_free(&password); + } + /* + * If the plaintext change failed, attempt + * the old encrypted method. NT will generate this + * after trying the samr method. Note that this + * method is done as a last resort as this + * password change method loses the NT password hash + * and cannot change the UNIX password as no plaintext + * is received. + */ + + if(SVAL(*rparam,0) != NERR_Success) { + SAM_ACCOUNT *hnd = NULL; - memset((char *)pass1,'\0',sizeof(fstring)); - memset((char *)pass2,'\0',sizeof(fstring)); + if (check_lanman_password(user,(unsigned char *)pass1,(unsigned char *)pass2, &hnd)) { + become_root(); + if (change_lanman_password(hnd,pass2)) { + SSVAL(*rparam,0,NERR_Success); + } + unbecome_root(); + pdb_free_sam(&hnd); + } + } + + memset((char *)pass1,'\0',sizeof(fstring)); + memset((char *)pass2,'\0',sizeof(fstring)); - return(True); + return(True); } /**************************************************************************** diff --git a/source3/smbd/mangle_hash.c b/source3/smbd/mangle_hash.c index ac8e425fd3..ac2d7681e8 100644 --- a/source3/smbd/mangle_hash.c +++ b/source3/smbd/mangle_hash.c @@ -313,6 +313,7 @@ static BOOL is_8_3(const char *fname, BOOL check_case, BOOL allow_wildcards) const char *f; smb_ucs2_t *ucs2name; NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + size_t size; if (!fname || !*fname) return False; @@ -324,9 +325,9 @@ static BOOL is_8_3(const char *fname, BOOL check_case, BOOL allow_wildcards) if (strlen(f) > 12) return False; - ucs2name = acnv_uxu2(f); - if (!ucs2name) { - DEBUG(0,("is_8_3: internal error acnv_uxu2() failed!\n")); + size = push_ucs2_allocate(&ucs2name, f); + if (size == (size_t)-1) { + DEBUG(0,("is_8_3: internal error push_ucs2_allocate() failed!\n")); goto done; } diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c index f452dd845b..28e3cf97d1 100644 --- a/source3/smbd/negprot.c +++ b/source3/smbd/negprot.c @@ -277,6 +277,22 @@ static int reply_nt1(char *inbuf, char *outbuf) if (global_encrypted_passwords_negotiated) secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE; + if (lp_server_signing()) { + if (lp_security() >= SEC_USER) { + secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED; + /* No raw mode with smb signing. */ + capabilities &= ~CAP_RAW_MODE; + if (lp_server_signing() == Required) + secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED; + srv_set_signing_negotiated(); + } else { + DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n")); + if (lp_server_signing() == Required) { + exit_server("reply_nt1: smb signing required and share level security selected."); + } + } + } + set_message(outbuf,17,0,True); SCVAL(outbuf,smb_vwv1,secword); @@ -521,6 +537,10 @@ int reply_negprot(connection_struct *conn, DEBUG( 5, ( "negprot index=%d\n", choice ) ); + if ((lp_server_signing() == Required) && (Protocol < PROTOCOL_NT1)) { + exit_server("SMB signing is required and client negotiated a downlevel protocol"); + } + END_PROFILE(SMBnegprot); return(outsize); } diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c index de1b331778..9adf827c79 100644 --- a/source3/smbd/notify.c +++ b/source3/smbd/notify.c @@ -44,6 +44,7 @@ static struct change_notify *change_notify_list; /**************************************************************************** Setup the common parts of the return packet and send it. *****************************************************************************/ + static void change_notify_reply_packet(char *inbuf, NTSTATUS error_code) { char outbuf[smb_size+38]; @@ -178,7 +179,7 @@ BOOL change_notify_set(char *inbuf, files_struct *fsp, connection_struct *conn, struct change_notify *cnbp; if((cnbp = (struct change_notify *)malloc(sizeof(*cnbp))) == NULL) { - DEBUG(0,("call_nt_transact_notify_change: malloc fail !\n" )); + DEBUG(0,("change_notify_set: malloc fail !\n" )); return -1; } @@ -197,6 +198,9 @@ BOOL change_notify_set(char *inbuf, files_struct *fsp, connection_struct *conn, DLIST_ADD(change_notify_list, cnbp); + /* Push the MID of this packet on the signing queue. */ + srv_defer_sign_response(SVAL(inbuf,smb_mid)); + return True; } diff --git a/source3/smbd/ntquotas.c b/source3/smbd/ntquotas.c index 2e865000ec..88d7c4e164 100644 --- a/source3/smbd/ntquotas.c +++ b/source3/smbd/ntquotas.c @@ -188,7 +188,7 @@ int vfs_get_user_ntquota_list(files_struct *fsp, SMB_NTQUOTA_LIST **qt_list) } if (vfs_get_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &tmp_qt)!=0) { - DEBUG(1,("no quota entry for sid[%s] path[%s]\n", + DEBUG(5,("no quota entry for sid[%s] path[%s]\n", sid_string_static(&sid),fsp->conn->connectpath)); continue; } diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index c574d9d563..3ffa6efa77 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -1443,6 +1443,7 @@ int reply_ntcancel(connection_struct *conn, START_PROFILE(SMBntcancel); remove_pending_change_notify_requests_by_mid(mid); remove_pending_lock_requests_by_mid(mid); + srv_cancel_sign_response(mid); DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", mid)); @@ -2321,6 +2322,8 @@ due to being in oplock break state.\n", (unsigned int)function_code )); dump_data(10, data, data_count); } + srv_signing_trans_start(SVAL(inbuf,smb_mid)); + if(num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) { /* We need to send an interim response then receive the rest of the parameter/data bytes */ @@ -2484,6 +2487,7 @@ due to being in oplock break state.\n", (unsigned int)function_code )); SAFE_FREE(params); SAFE_FREE(data); END_PROFILE(SMBnttrans); + srv_signing_trans_stop(); return ERROR_DOS(ERRSRV,ERRerror); } @@ -2494,6 +2498,8 @@ due to being in oplock break state.\n", (unsigned int)function_code )); an error packet. */ + srv_signing_trans_stop(); + SAFE_FREE(setup); SAFE_FREE(params); SAFE_FREE(data); @@ -2504,6 +2510,7 @@ due to being in oplock break state.\n", (unsigned int)function_code )); bad_param: + srv_signing_trans_stop(); SAFE_FREE(params); SAFE_FREE(data); SAFE_FREE(setup); diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 6d03eaa29a..5f49640aa4 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -125,6 +125,7 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn, directory. */ flags &= ~O_CREAT; + local_flags &= ~O_CREAT; } } @@ -166,6 +167,14 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn, local_flags |= O_NONBLOCK; #endif + /* Don't create files with Microsoft wildcard characters. */ + if ((local_flags & O_CREAT) && !VALID_STAT(*psbuf) && ms_has_wild(fname)) { + unix_ERR_class = ERRDOS; + unix_ERR_code = ERRinvalidname; + unix_ERR_ntstatus = NT_STATUS_OBJECT_NAME_INVALID; + return False; + } + /* Actually do the open */ fsp->fd = fd_open(conn, fname, local_flags, mode); if (fsp->fd == -1) { @@ -675,8 +684,8 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou dev = %x, inode = %.0f. Deleting it to continue...\n", (int)broken_entry.pid, fname, (unsigned int)dev, (double)inode)); if (process_exists(broken_entry.pid)) { - DEBUG(0,("open_mode_check: Existent process %d left active oplock.\n", - broken_entry.pid )); + DEBUG(0,("open_mode_check: Existent process %lu left active oplock.\n", + (unsigned long)broken_entry.pid )); } if (del_share_entry(dev, inode, &broken_entry, NULL) == -1) { @@ -874,7 +883,7 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_ if (file_existed && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE)) { if (!open_match_attributes(conn, fname, psbuf->st_mode, mode, &new_mode)) { DEBUG(5,("open_file_shared: attributes missmatch for file %s (0%o, 0%o)\n", - fname, psbuf->st_mode, mode )); + fname, (int)psbuf->st_mode, (int)mode )); file_free(fsp); errno = EACCES; return NULL; @@ -1290,6 +1299,15 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST return NULL; } + if (ms_has_wild(fname)) { + file_free(fsp); + DEBUG(5,("open_directory: failing create on filename %s with wildcards\n", fname)); + unix_ERR_class = ERRDOS; + unix_ERR_code = ERRinvalidname; + unix_ERR_ntstatus = NT_STATUS_OBJECT_NAME_INVALID; + return NULL; + } + if(vfs_MkDir(conn,fname, unix_mode(conn,aDIR, fname)) < 0) { DEBUG(2,("open_directory: unable to create %s. Error was %s\n", fname, strerror(errno) )); diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c index 8525687793..19e6956d9e 100644 --- a/source3/smbd/oplock.c +++ b/source3/smbd/oplock.c @@ -660,6 +660,7 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id, time_t start_time; BOOL shutdown_server = False; BOOL oplock_timeout = False; + BOOL sign_state; connection_struct *saved_user_conn; connection_struct *saved_fsp_conn; int saved_vuid; @@ -742,8 +743,16 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id, /* 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; - if (!send_smb(smbd_server_fd(), outbuf)) + /* Save the server smb signing state. */ + sign_state = srv_oplock_set_signing(False); + + if (!send_smb(smbd_server_fd(), outbuf)) { + srv_oplock_set_signing(sign_state); exit_server("oplock_break: send_smb failed."); + } + + /* Restore the sign state to what it was. */ + srv_oplock_set_signing(sign_state); /* We need this in case a readraw crosses on the wire. */ global_oplock_break = True; @@ -791,6 +800,9 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id, } else if (smb_read_error == READ_ERROR) { DEBUG( 0, ("oplock_break: receive_smb error (%s)\n", strerror(errno)) ); shutdown_server = True; + } else if (smb_read_error == READ_BAD_SIG) { + DEBUG( 0, ("oplock_break: bad signature from client\n" )); + 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; diff --git a/source3/smbd/password.c b/source3/smbd/password.c index e2c143f1e2..b988f2ec74 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -29,10 +29,11 @@ static int next_vuid = VUID_OFFSET; static int num_validated_vuids; /**************************************************************************** -check if a uid has been validated, and return an pointer to the user_struct -if it has. NULL if not. vuid is biased by an offset. This allows us to -tell random client vuid's (normally zero) from valid vuids. + Check if a uid has been validated, and return an pointer to the user_struct + if it has. NULL if not. vuid is biased by an offset. This allows us to + tell random client vuid's (normally zero) from valid vuids. ****************************************************************************/ + user_struct *get_valid_user_struct(uint16 vuid) { user_struct *usp; @@ -54,8 +55,9 @@ user_struct *get_valid_user_struct(uint16 vuid) } /**************************************************************************** -invalidate a uid + Invalidate a uid. ****************************************************************************/ + void invalidate_vuid(uint16 vuid) { user_struct *vuser = get_valid_user_struct(vuid); @@ -85,8 +87,9 @@ void invalidate_vuid(uint16 vuid) } /**************************************************************************** -invalidate all vuid entries for this process + Invalidate all vuid entries for this process. ****************************************************************************/ + void invalidate_all_vuids(void) { user_struct *usp, *next=NULL; @@ -108,7 +111,7 @@ void invalidate_all_vuids(void) * */ -int register_vuid(auth_serversupplied_info *server_info, const char *smb_name) +int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB response_blob, const char *smb_name) { user_struct *vuser = NULL; @@ -238,38 +241,42 @@ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name) vuser->homes_snum = -1; } + if (lp_server_signing() && !vuser->guest && !srv_is_signing_active()) { + /* Try and turn on server signing on the first non-guest sessionsetup. */ + srv_set_signing(vuser->session_key, response_blob); + } + return vuser->vuid; } - /**************************************************************************** -add a name to the session users list + Add a name to the session users list. ****************************************************************************/ + void add_session_user(const char *user) { - fstring suser; - struct passwd *passwd; + fstring suser; + struct passwd *passwd; - if (!(passwd = Get_Pwnam(user))) return; + if (!(passwd = Get_Pwnam(user))) + return; - fstrcpy(suser,passwd->pw_name); + fstrcpy(suser,passwd->pw_name); - 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 - { - pstrcat(session_users," "); - pstrcat(session_users,suser); + 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 { + pstrcat(session_users," "); + pstrcat(session_users,suser); + } } - } } - /**************************************************************************** -check if a username is valid + Check if a username is valid. ****************************************************************************/ + BOOL user_ok(const char *user,int snum, gid_t *groups, size_t n_groups) { char **valid, **invalid; @@ -308,8 +315,9 @@ BOOL user_ok(const char *user,int snum, gid_t *groups, size_t n_groups) } /**************************************************************************** -validate a group username entry. Return the username or NULL + Validate a group username entry. Return the username or NULL. ****************************************************************************/ + static char *validate_group(char *group, DATA_BLOB password,int snum) { #ifdef HAVE_NETGROUP diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 18acb35f7a..dce1c4bc03 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -53,9 +53,9 @@ extern int max_send; ****************************************************************************/ typedef struct { - ubi_slNode msg_next; - char *msg_buf; - int msg_len; + ubi_slNode msg_next; + char *msg_buf; + int msg_len; } pending_message_list; static ubi_slList smb_oplock_queue = { NULL, (ubi_slNodePtr)&smb_oplock_queue, 0}; @@ -67,29 +67,30 @@ static ubi_slList smb_oplock_queue = { NULL, (ubi_slNodePtr)&smb_oplock_queue, 0 static BOOL push_message(ubi_slList *list_head, char *buf, int msg_len) { - pending_message_list *msg = (pending_message_list *) + pending_message_list *msg = (pending_message_list *) malloc(sizeof(pending_message_list)); - if(msg == NULL) - { - DEBUG(0,("push_message: malloc fail (1)\n")); - return False; - } + if(msg == NULL) { + DEBUG(0,("push_message: malloc fail (1)\n")); + return False; + } - msg->msg_buf = (char *)malloc(msg_len); - if(msg->msg_buf == NULL) - { - DEBUG(0,("push_message: malloc fail (2)\n")); - SAFE_FREE(msg); - return False; - } + msg->msg_buf = (char *)malloc(msg_len); + if(msg->msg_buf == NULL) { + DEBUG(0,("push_message: malloc fail (2)\n")); + SAFE_FREE(msg); + return False; + } + + memcpy(msg->msg_buf, buf, msg_len); + msg->msg_len = msg_len; - memcpy(msg->msg_buf, buf, msg_len); - msg->msg_len = msg_len; + ubi_slAddTail( list_head, msg); - ubi_slAddTail( list_head, msg); + /* Push the MID of this packet on the signing queue. */ + srv_defer_sign_response(SVAL(buf,smb_mid)); - return True; + return True; } /**************************************************************************** @@ -295,28 +296,29 @@ BOOL receive_next_smb(char *inbuf, int bufsize, int timeout) void respond_to_all_remaining_local_messages(void) { - char buffer[1024]; - - /* - * 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; - } - - /* - * Keep doing receive_local_message with a 1 ms timeout until - * we have no more messages. - */ - while(receive_local_message(buffer, sizeof(buffer), 1)) { - /* Deal with oplock break requests from other smbd's. */ - process_local_message(buffer, sizeof(buffer)); - } - - return; + char buffer[1024]; + + /* + * 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; + } + + /* + * Keep doing receive_local_message with a 1 ms timeout until + * we have no more messages. + */ + + while(receive_local_message(buffer, sizeof(buffer), 1)) { + /* Deal with oplock break requests from other smbd's. */ + process_local_message(buffer, sizeof(buffer)); + } + + return; } @@ -339,13 +341,11 @@ force write permissions on print services. functions. Any message that has a NULL function is unimplemented - please feel free to contribute implementations! */ -static const struct smb_message_struct -{ - const char *name; - int (*fn)(connection_struct *conn, char *, char *, int, int); - int flags; -} - smb_messages[256] = { +static const struct smb_message_struct { + const char *name; + int (*fn)(connection_struct *conn, char *, char *, int, int); + int flags; +} smb_messages[256] = { /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE}, /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE}, @@ -849,67 +849,62 @@ set. Ignoring max smbd restriction.\n")); } /**************************************************************************** - process an smb from the client - split out from the smbd_process() code so - it can be used by the oplock break code. + Process an smb from the client - split out from the smbd_process() code so + it can be used by the oplock break code. ****************************************************************************/ + void process_smb(char *inbuf, char *outbuf) { - static int trans_num; - int msg_type = CVAL(inbuf,0); - int32 len = smb_len(inbuf); - int nread = len + 4; - - DO_PROFILE_INC(smb_count); - - if (trans_num == 0) { - /* on the first packet, check the global hosts allow/ hosts - deny parameters before doing any parsing of the packet - passed to us by the client. This prevents attacks on our - parsing code from hosts not in the hosts allow list */ - if (smbd_process_limit() || - !check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1))) { - /* send a negative session response "not listening on calling - name" */ - static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81}; - DEBUG( 1, ( "Connection denied from %s\n", - client_addr() ) ); - (void)send_smb(smbd_server_fd(),(char *)buf); - exit_server("connection denied"); - } - } - - DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type, len ) ); - DEBUG( 3, ( "Transaction %d of length %d\n", trans_num, nread ) ); - - if (msg_type == 0) - show_msg(inbuf); - else if(msg_type == SMBkeepalive) - return; /* Keepalive packet. */ - - nread = construct_reply(inbuf,outbuf,nread,max_send); + static int trans_num; + int msg_type = CVAL(inbuf,0); + int32 len = smb_len(inbuf); + int nread = len + 4; + + DO_PROFILE_INC(smb_count); + + if (trans_num == 0) { + /* on the first packet, check the global hosts allow/ hosts + deny parameters before doing any parsing of the packet + passed to us by the client. This prevents attacks on our + parsing code from hosts not in the hosts allow list */ + if (smbd_process_limit() || + !check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1))) { + /* send a negative session response "not listening on calling name" */ + static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81}; + DEBUG( 1, ( "Connection denied from %s\n", client_addr() ) ); + (void)send_smb(smbd_server_fd(),(char *)buf); + exit_server("connection denied"); + } + } + + DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type, len ) ); + DEBUG( 3, ( "Transaction %d of length %d\n", trans_num, nread ) ); + + if (msg_type == 0) + show_msg(inbuf); + else if(msg_type == SMBkeepalive) + return; /* Keepalive packet. */ + + nread = construct_reply(inbuf,outbuf,nread,max_send); - if(nread > 0) - { - if (CVAL(outbuf,0) == 0) - show_msg(outbuf); + if(nread > 0) { + if (CVAL(outbuf,0) == 0) + show_msg(outbuf); - if (nread != smb_len(outbuf) + 4) - { - DEBUG(0,("ERROR: Invalid message response size! %d %d\n", - nread, smb_len(outbuf))); - } - else - if (!send_smb(smbd_server_fd(),outbuf)) - exit_server("process_smb: send_smb failed."); - } - trans_num++; + if (nread != smb_len(outbuf) + 4) { + DEBUG(0,("ERROR: Invalid message response size! %d %d\n", + nread, smb_len(outbuf))); + } else if (!send_smb(smbd_server_fd(),outbuf)) { + exit_server("process_smb: send_smb failed."); + } + } + trans_num++; } - - /**************************************************************************** -return a string containing the function name of a SMB command + Return a string containing the function name of a SMB command. ****************************************************************************/ + const char *smb_fn_name(int type) { const char *unknown_name = "SMBunknown"; @@ -949,92 +944,94 @@ void construct_reply_common(char *inbuf,char *outbuf) } /**************************************************************************** - construct a chained reply and add it to the already made reply - **************************************************************************/ + Construct a chained reply and add it to the already made reply +****************************************************************************/ + int chain_reply(char *inbuf,char *outbuf,int size,int bufsize) { - static char *orig_inbuf; - static char *orig_outbuf; - int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0); - unsigned smb_off2 = SVAL(inbuf,smb_vwv1); - char *inbuf2, *outbuf2; - int outsize2; - char inbuf_saved[smb_wct]; - char outbuf_saved[smb_wct]; - int wct = CVAL(outbuf,smb_wct); - int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct); - - /* maybe its not chained */ - if (smb_com2 == 0xFF) { - SCVAL(outbuf,smb_vwv0,0xFF); - return outsize; - } - - if (chain_size == 0) { - /* this is the first part of the chain */ - orig_inbuf = inbuf; - 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)); - SCVAL(outbuf,smb_vwv0,smb_com2); - - /* remember how much the caller added to the chain, only counting stuff - after the parameter words */ - chain_size += outsize - smb_wct; - - /* work out pointers into the original packets. The - headers on these need to be filled in */ - inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct; - outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct; - - /* remember the original command type */ - smb_com1 = CVAL(orig_inbuf,smb_com); - - /* save the data which will be overwritten by the new headers */ - memcpy(inbuf_saved,inbuf2,smb_wct); - memcpy(outbuf_saved,outbuf2,smb_wct); - - /* give the new packet the same header as the last part of the SMB */ - memmove(inbuf2,inbuf,smb_wct); - - /* create the in buffer */ - SCVAL(inbuf2,smb_com,smb_com2); - - /* create the out buffer */ - construct_reply_common(inbuf2, outbuf2); - - DEBUG(3,("Chained message\n")); - show_msg(inbuf2); - - /* process the request */ - outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size, - bufsize-chain_size); - - /* copy the new reply and request headers over the old ones, but - preserve the smb_com field */ - memmove(orig_outbuf,outbuf2,smb_wct); - SCVAL(orig_outbuf,smb_com,smb_com1); - - /* restore the saved data, being careful not to overwrite any - data from the reply header */ - memcpy(inbuf2,inbuf_saved,smb_wct); - { - int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf); - if (ofs < 0) ofs = 0; - memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs); - } - - return outsize2; + static char *orig_inbuf; + static char *orig_outbuf; + int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0); + unsigned smb_off2 = SVAL(inbuf,smb_vwv1); + char *inbuf2, *outbuf2; + int outsize2; + char inbuf_saved[smb_wct]; + char outbuf_saved[smb_wct]; + int wct = CVAL(outbuf,smb_wct); + int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct); + + /* maybe its not chained */ + if (smb_com2 == 0xFF) { + SCVAL(outbuf,smb_vwv0,0xFF); + return outsize; + } + + if (chain_size == 0) { + /* this is the first part of the chain */ + orig_inbuf = inbuf; + 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)); + SCVAL(outbuf,smb_vwv0,smb_com2); + + /* remember how much the caller added to the chain, only counting stuff + after the parameter words */ + chain_size += outsize - smb_wct; + + /* work out pointers into the original packets. The + headers on these need to be filled in */ + inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct; + outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct; + + /* remember the original command type */ + smb_com1 = CVAL(orig_inbuf,smb_com); + + /* save the data which will be overwritten by the new headers */ + memcpy(inbuf_saved,inbuf2,smb_wct); + memcpy(outbuf_saved,outbuf2,smb_wct); + + /* give the new packet the same header as the last part of the SMB */ + memmove(inbuf2,inbuf,smb_wct); + + /* create the in buffer */ + SCVAL(inbuf2,smb_com,smb_com2); + + /* create the out buffer */ + construct_reply_common(inbuf2, outbuf2); + + DEBUG(3,("Chained message\n")); + show_msg(inbuf2); + + /* process the request */ + outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size, + bufsize-chain_size); + + /* copy the new reply and request headers over the old ones, but + preserve the smb_com field */ + memmove(orig_outbuf,outbuf2,smb_wct); + SCVAL(orig_outbuf,smb_com,smb_com1); + + /* restore the saved data, being careful not to overwrite any + data from the reply header */ + memcpy(inbuf2,inbuf_saved,smb_wct); + + { + int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf); + if (ofs < 0) ofs = 0; + memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs); + } + + return outsize2; } /**************************************************************************** @@ -1065,17 +1062,16 @@ static int setup_select_timeout(void) void check_reload(int t) { - static time_t last_smb_conf_reload_time = 0; + static time_t last_smb_conf_reload_time = 0; - if(last_smb_conf_reload_time == 0) - last_smb_conf_reload_time = t; + if(last_smb_conf_reload_time == 0) + last_smb_conf_reload_time = t; - if (reload_after_sighup || (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK)) - { - reload_services(True); - reload_after_sighup = False; - last_smb_conf_reload_time = t; - } + if (reload_after_sighup || (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK)) { + reload_services(True); + reload_after_sighup = False; + last_smb_conf_reload_time = t; + } } /**************************************************************************** @@ -1084,165 +1080,164 @@ void check_reload(int t) static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_timeout_processing_time) { - 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; - - if (smb_read_error == READ_EOF) - { - DEBUG(3,("end of file from client\n")); - return False; - } - - if (smb_read_error == READ_ERROR) - { - DEBUG(3,("receive_smb error (%s) exiting\n", - strerror(errno))); - return False; - } - - *last_timeout_processing_time = t = time(NULL); - - if(last_keepalive_sent_time == 0) - last_keepalive_sent_time = t; - - if(last_idle_closed_check == 0) - last_idle_closed_check = t; - - /* become root again if waiting */ - change_to_root_user(); - - /* run all registered idle events */ - smb_run_idle_events(t); - - /* 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) - { - extern struct auth_context *negprot_global_auth_context; - if (!send_keepalive(smbd_server_fd())) { - DEBUG( 2, ( "Keepalive failed - exiting.\n" ) ); - return False; - } - - /* send a keepalive for a password server or the like. - This is attached to the auth_info created in the - negprot */ - if (negprot_global_auth_context - && negprot_global_auth_context->challenge_set_method - && negprot_global_auth_context->challenge_set_method->send_keepalive) { - negprot_global_auth_context->challenge_set_method->send_keepalive - (&negprot_global_auth_context->challenge_set_method->private_data); - } - - 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; - } - - if(global_machine_password_needs_changing && - /* for ADS we need to do a regular ADS password change, not a domain - password change */ - lp_security() == SEC_DOMAIN) - { - unsigned char trust_passwd_hash[16]; - time_t lct; - - /* - * We're in domain level security, and the code that - * read the machine password flagged that the machine - * password needs changing. - */ - - /* - * First, open the machine password file with an exclusive lock. - */ - - if (secrets_lock_trust_account_password(lp_workgroup(), True) == False) { - DEBUG(0,("process: unable to lock the machine account password for \ + 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; + + if (smb_read_error == READ_EOF) { + DEBUG(3,("timeout_processing: End of file from client (client has disconnected).\n")); + return False; + } + + if (smb_read_error == READ_ERROR) { + DEBUG(3,("timeout_processing: receive_smb error (%s) Exiting\n", + strerror(errno))); + return False; + } + + if (smb_read_error == READ_BAD_SIG) { + DEBUG(3,("timeout_processing: receive_smb error bad smb signature. Exiting\n")); + return False; + } + + *last_timeout_processing_time = t = time(NULL); + + if(last_keepalive_sent_time == 0) + last_keepalive_sent_time = t; + + if(last_idle_closed_check == 0) + last_idle_closed_check = t; + + /* become root again if waiting */ + change_to_root_user(); + + /* run all registered idle events */ + smb_run_idle_events(t); + + /* 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) { + extern struct auth_context *negprot_global_auth_context; + if (!send_keepalive(smbd_server_fd())) { + DEBUG( 2, ( "Keepalive failed - exiting.\n" ) ); + return False; + } + + /* send a keepalive for a password server or the like. + This is attached to the auth_info created in the + negprot */ + if (negprot_global_auth_context && negprot_global_auth_context->challenge_set_method + && negprot_global_auth_context->challenge_set_method->send_keepalive) { + + negprot_global_auth_context->challenge_set_method->send_keepalive + (&negprot_global_auth_context->challenge_set_method->private_data); + } + + 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; + } + + if(global_machine_password_needs_changing && + /* for ADS we need to do a regular ADS password change, not a domain + password change */ + lp_security() == SEC_DOMAIN) { + + unsigned char trust_passwd_hash[16]; + time_t lct; + + /* + * We're in domain level security, and the code that + * read the machine password flagged that the machine + * password needs changing. + */ + + /* + * First, open the machine password file with an exclusive lock. + */ + + if (secrets_lock_trust_account_password(lp_workgroup(), True) == False) { + DEBUG(0,("process: unable to lock the machine account password for \ machine %s in domain %s.\n", global_myname(), lp_workgroup() )); - return True; - } + return True; + } - if(!secrets_fetch_trust_account_password(lp_workgroup(), - trust_passwd_hash, - &lct, NULL)) { - DEBUG(0,("process: unable to read the machine account password for \ + if(!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd_hash, &lct, NULL)) { + DEBUG(0,("process: unable to read the machine account password for \ machine %s in domain %s.\n", global_myname(), lp_workgroup())); - secrets_lock_trust_account_password(lp_workgroup(), False); - return True; - } + secrets_lock_trust_account_password(lp_workgroup(), False); + return True; + } - /* - * Make sure someone else hasn't already done this. - */ + /* + * Make sure someone else hasn't already done this. + */ - if(t < lct + lp_machine_password_timeout()) { - global_machine_password_needs_changing = False; - secrets_lock_trust_account_password(lp_workgroup(), False); - return True; - } + if(t < lct + lp_machine_password_timeout()) { + global_machine_password_needs_changing = False; + secrets_lock_trust_account_password(lp_workgroup(), False); + return True; + } - /* always just contact the PDC here */ + /* always just contact the PDC here */ - change_trust_account_password( lp_workgroup(), NULL); - global_machine_password_needs_changing = False; - secrets_lock_trust_account_password(lp_workgroup(), False); - } - - /* - * Check to see if we have any blocking locks - * outstanding on the queue. - */ - process_blocking_lock_queue(t); - - /* update printer queue caches if necessary */ + change_trust_account_password( lp_workgroup(), NULL); + global_machine_password_needs_changing = False; + secrets_lock_trust_account_password(lp_workgroup(), False); + } + + /* + * Check to see if we have any blocking locks + * outstanding on the queue. + */ + process_blocking_lock_queue(t); + + /* update printer queue caches if necessary */ - update_monitored_printq_cache(); + update_monitored_printq_cache(); - /* - * Check to see if we have any change notifies - * outstanding on the queue. - */ - process_pending_change_notify_queue(t); + /* + * Check to see if we have any change notifies + * outstanding on the queue. + */ + process_pending_change_notify_queue(t); - /* - * Now we are root, check if the log files need pruning. - * Force a log file check. - */ - force_check_log_size(); - check_log_size(); + /* + * Now we are root, check if the log files need pruning. + * Force a log file check. + */ + force_check_log_size(); + check_log_size(); - /* Send any queued printer notify message to interested smbd's. */ + /* Send any queued printer notify message to interested smbd's. */ - print_notify_send_messages(0); + print_notify_send_messages(0); - /* - * Modify the select timeout depending upon - * what we have remaining in our queues. - */ + /* + * Modify the select timeout depending upon + * what we have remaining in our queues. + */ - *select_timeout = setup_select_timeout(); + *select_timeout = setup_select_timeout(); - return True; + return True; } /**************************************************************************** diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index e7f01ad02f..71312295f4 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -48,8 +48,6 @@ int reply_special(char *inbuf,char *outbuf) int msg_type = CVAL(inbuf,0); int msg_flags = CVAL(inbuf,1); pstring name1,name2; - - int len; char name_type = 0; static BOOL already_got_session = False; @@ -75,23 +73,16 @@ int reply_special(char *inbuf,char *outbuf) return(0); } name_extract(inbuf,4,name1); - name_extract(inbuf,4 + name_len(inbuf + 4),name2); + name_type = name_extract(inbuf,4 + name_len(inbuf + 4),name2); DEBUG(2,("netbios connect: name1=%s name2=%s\n", name1,name2)); - name1[15] = 0; - - len = strlen(name2); - if (len == 16) { - name_type = name2[15]; - name2[15] = 0; - } - set_local_machine_name(name1, True); set_remote_machine_name(name2, True); - DEBUG(2,("netbios connect: local=%s remote=%s\n", - get_local_machine_name(), get_remote_machine_name() )); + DEBUG(2,("netbios connect: local=%s remote=%s, name type = %x\n", + get_local_machine_name(), get_remote_machine_name(), + name_type)); if (name_type == 'R') { /* We are being asked for a pathworks session --- @@ -1281,6 +1272,16 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name) *directory = *mask = 0; + /* We must check for wildcards in the name given + * directly by the client - before any unmangling. + * This prevents an unmangling of a UNIX name containing + * a DOS wildcard like '*' or '?' from unmangling into + * a wildcard delete which was not intended. + * FIX for #226. JRA. + */ + + has_wild = ms_has_wild(name); + rc = unix_convert(name,conn,0,&bad_path,&sbuf); p = strrchr_m(name,'/'); @@ -1305,13 +1306,12 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name) if (!rc && mangle_is_mangled(mask)) mangle_check_cache( mask ); - has_wild = ms_has_wild(mask); - if (!has_wild) { pstrcat(directory,"/"); pstrcat(directory,mask); error = can_delete(directory,conn,dirtype); - if (!NT_STATUS_IS_OK(error)) return error; + if (!NT_STATUS_IS_OK(error)) + return error; if (SMB_VFS_UNLINK(conn,directory) == 0) { count++; @@ -1338,12 +1338,15 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name) pstring fname; pstrcpy(fname,dname); - if(!mask_match(fname, mask, case_sensitive)) continue; + if(!mask_match(fname, mask, case_sensitive)) + continue; slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname); error = can_delete(fname,conn,dirtype); - if (!NT_STATUS_IS_OK(error)) continue; - if (SMB_VFS_UNLINK(conn,fname) == 0) count++; + if (!NT_STATUS_IS_OK(error)) + continue; + if (SMB_VFS_UNLINK(conn,fname) == 0) + count++; DEBUG(3,("unlink_internals: succesful unlink [%s]\n",fname)); } CloseDir(dirptr); @@ -1379,7 +1382,8 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size DEBUG(3,("reply_unlink : %s\n",name)); status = unlink_internals(conn, dirtype, name); - if (!NT_STATUS_IS_OK(status)) return ERROR_NT(status); + if (!NT_STATUS_IS_OK(status)) + return ERROR_NT(status); /* * Win2k needs a changenotify request response before it will @@ -1472,6 +1476,10 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s files_struct *fsp; START_PROFILE(SMBreadbraw); + if (srv_is_signing_active()) { + exit_server("reply_readbraw: SMB signing is active - raw reads/writes are disallowed."); + } + /* * Special check if an oplock break has been issued * and the readraw request croses on the wire, we must @@ -1870,6 +1878,10 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, int outsize = 0; START_PROFILE(SMBwritebraw); + if (srv_is_signing_active()) { + exit_server("reply_readbraw: SMB signing is active - raw reads/writes are disallowed."); + } + CHECK_FSP(fsp,conn); CHECK_WRITE(fsp); @@ -2828,7 +2840,11 @@ NTSTATUS mkdir_internal(connection_struct *conn, pstring directory) int ret= -1; unix_convert(directory,conn,0,&bad_path,&sbuf); - + + if (ms_has_wild(directory)) { + return NT_STATUS_OBJECT_NAME_INVALID; + } + if (check_name(directory, conn)) ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory)); diff --git a/source3/smbd/service.c b/source3/smbd/service.c index 18e0887071..c2855487a5 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -661,7 +661,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, #else /* the alternative is just to check the directory exists */ if (stat(conn->connectpath, &st) != 0 || !S_ISDIR(st.st_mode)) { - DEBUG(0,("'%s' is not a directory, when connecting to [%s]\n", conn->connectpath, lp_servicename(SNUM(conn)))); + DEBUG(0,("'%s' does not exist or is not a directory, when connecting to [%s]\n", conn->connectpath, lp_servicename(SNUM(conn)))); change_to_root_user(); yield_connection(conn, lp_servicename(SNUM(conn))); conn_free(conn); diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 7d77ed3071..88b442215d 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -3,7 +3,7 @@ handle SMBsessionsetup Copyright (C) Andrew Tridgell 1998-2001 Copyright (C) Andrew Bartlett 2001 - Copyright (C) Jim McDonough 2002 + Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002 Copyright (C) Luke Howard 2003 This program is free software; you can redistribute it and/or modify @@ -62,7 +62,7 @@ static int add_signature(char *outbuf, char *p) char *start = p; fstring lanman; - snprintf( lanman, sizeof(lanman), "Samba %s", VERSION ); + fstr_sprintf( lanman, "Samba %s", VERSION ); p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE); p += srvstr_push(outbuf, p, lanman, -1, STR_TERMINATE); @@ -153,6 +153,7 @@ static int reply_spnego_kerberos(connection_struct *conn, uint8 session_key[16]; uint8 tok_id[2]; BOOL foreign = False; + DATA_BLOB nullblob = data_blob(NULL, 0); ZERO_STRUCT(ticket); ZERO_STRUCT(auth_data); @@ -235,7 +236,7 @@ static int reply_spnego_kerberos(connection_struct *conn, memcpy(server_info->session_key, session_key, sizeof(session_key)); /* register_vuid keeps the server info */ - sess_vuid = register_vuid(server_info, user); + sess_vuid = register_vuid(server_info, nullblob, user); free(user); @@ -250,6 +251,16 @@ static int reply_spnego_kerberos(connection_struct *conn, } SSVAL(outbuf, smb_uid, sess_vuid); + + if (!server_info->guest) { + /* We need to start the signing engine + * here but a W2K client sends the old + * "BSRSPYL " signature instead of the + * correct one. Subsequent packets will + * be correct. + */ + srv_check_sign_mac(inbuf); + } } /* wrap that up in a nice GSS-API wrapping */ @@ -275,7 +286,7 @@ static int reply_spnego_kerberos(connection_struct *conn, End the NTLMSSP exchange context if we are OK/complete fail ***************************************************************************/ -static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *outbuf, +static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *outbuf, AUTH_NTLMSSP_STATE **auth_ntlmssp_state, DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status) { @@ -294,8 +305,10 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *outbuf, if (NT_STATUS_IS_OK(nt_status)) { int sess_vuid; + DATA_BLOB nullblob = data_blob(NULL, 0); + /* register_vuid keeps the server info */ - sess_vuid = register_vuid(server_info, (*auth_ntlmssp_state)->ntlmssp_state->user); + sess_vuid = register_vuid(server_info, nullblob, (*auth_ntlmssp_state)->ntlmssp_state->user); (*auth_ntlmssp_state)->server_info = NULL; if (sess_vuid == -1) { @@ -310,6 +323,16 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *outbuf, } SSVAL(outbuf,smb_uid,sess_vuid); + + if (!server_info->guest) { + /* We need to start the signing engine + * here but a W2K client sends the old + * "BSRSPYL " signature instead of the + * correct one. Subsequent packets will + * be correct. + */ + srv_check_sign_mac(inbuf); + } } } @@ -348,16 +371,27 @@ static int reply_spnego_negotiate(connection_struct *conn, if (!parse_negTokenTarg(blob1, OIDs, &secblob)) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); } + + /* only look at the first OID for determining the mechToken -- + accoirding to RFC2478, we should choose the one we want + and renegotiate, but i smell a client bug here.. + + Problem observed when connecting to a member (samba box) + of an AD domain as a user in a Samba domain. Samba member + server sent back krb5/mskrb5/ntlmssp as mechtypes, but the + client (2ksp3) replied with ntlmssp/mskrb5/krb5 and an + NTLMSSP mechtoken. --jerry */ + if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 || + strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) { + got_kerberos = True; + } + for (i=0;OIDs[i];i++) { DEBUG(3,("Got OID %s\n", OIDs[i])); - if (strcmp(OID_KERBEROS5, OIDs[i]) == 0 || - strcmp(OID_KERBEROS5_OLD, OIDs[i]) == 0) { - got_kerberos = True; - } free(OIDs[i]); } - DEBUG(3,("Got secblob of size %d\n", secblob.length)); + DEBUG(3,("Got secblob of size %lu\n", (unsigned long)secblob.length)); #ifdef HAVE_KRB5 if (got_kerberos && (SEC_ADS == lp_security())) { @@ -382,7 +416,7 @@ static int reply_spnego_negotiate(connection_struct *conn, data_blob_free(&secblob); - reply_spnego_ntlmssp(conn, outbuf, &global_ntlmssp_state, + reply_spnego_ntlmssp(conn, inbuf, outbuf, &global_ntlmssp_state, &chal, nt_status); data_blob_free(&chal); @@ -419,7 +453,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, data_blob_free(&auth); - reply_spnego_ntlmssp(conn, outbuf, &global_ntlmssp_state, + reply_spnego_ntlmssp(conn, inbuf, outbuf, &global_ntlmssp_state, &auth_reply, nt_status); data_blob_free(&auth_reply); @@ -742,7 +776,6 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, free_user_info(&user_info); data_blob_free(&lm_resp); - data_blob_free(&nt_resp); data_blob_clear_free(&plaintext_password); if (!NT_STATUS_IS_OK(nt_status)) { @@ -750,9 +783,10 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, } if (!NT_STATUS_IS_OK(nt_status)) { + data_blob_free(&nt_resp); return ERROR_NT(nt_status_squash(nt_status)); } - + /* it's ok - setup a reply */ set_message(outbuf,3,0,True); if (Protocol >= PROTOCOL_NT1) { @@ -770,12 +804,17 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, to a uid can get through without a password, on the same VC */ /* register_vuid keeps the server info */ - sess_vuid = register_vuid(server_info, sub_user); - + sess_vuid = register_vuid(server_info, nt_resp, sub_user); + data_blob_free(&nt_resp); + if (sess_vuid == -1) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); } + if (!server_info->guest && !srv_check_sign_mac(inbuf)) { + exit_server("reply_sesssetup_and_X: bad smb signature"); + } + SSVAL(outbuf,smb_uid,sess_vuid); SSVAL(inbuf,smb_uid,sess_vuid); diff --git a/source3/smbd/statcache.c b/source3/smbd/statcache.c index 22b8a33a1e..fbebdb240f 100644 --- a/source3/smbd/statcache.c +++ b/source3/smbd/statcache.c @@ -98,7 +98,12 @@ void stat_cache_add( const char *full_orig_name, const char *orig_translated_pat translated_path_length--; } - original_path = strdup(full_orig_name); + if(case_sensitive) { + original_path = strdup(full_orig_name); + } else { + original_path = strdup_upper(full_orig_name); + } + if (!original_path) { SAFE_FREE(translated_path); return; @@ -111,9 +116,6 @@ void stat_cache_add( const char *full_orig_name, const char *orig_translated_pat original_path_length--; } - if(!case_sensitive) - strupper_m(original_path); - if (original_path_length != translated_path_length) { if (original_path_length < translated_path_length) { DEBUG(0, ("OOPS - tried to store stat cache entry for werid length paths [%s] %u and [%s] %u)!\n", @@ -161,6 +163,7 @@ void stat_cache_add( const char *full_orig_name, const char *orig_translated_pat } scp->original_path = scp->names; + /* pointer into the structure... */ scp->translated_path = scp->names + original_path_length + 1; safe_strcpy(scp->original_path, original_path, original_path_length); safe_strcpy(scp->translated_path, translated_path, translated_path_length); @@ -194,7 +197,7 @@ BOOL stat_cache_lookup(connection_struct *conn, pstring name, pstring dirpath, char **start, SMB_STRUCT_STAT *pst) { stat_cache_entry *scp; - pstring chk_name; + char *chk_name; size_t namelen; hash_element *hash_elem; char *sp; @@ -218,10 +221,20 @@ BOOL stat_cache_lookup(connection_struct *conn, pstring name, pstring dirpath, return False; } - pstrcpy(chk_name, name); + if (case_sensitive) { + chk_name = strdup(name); + if (!chk_name) { + DEBUG(0, ("stat_cache_lookup: strdup failed!\n")); + return False; + } + + } else { + chk_name = strdup_upper(name); + if (!chk_name) { + DEBUG(0, ("stat_cache_lookup: strdup_upper failed!\n")); + return False; + } - if(!case_sensitive) { - strupper_m( chk_name ); /* * In some language encodings the length changes * if we uppercase. We need to treat this differently @@ -252,11 +265,13 @@ BOOL stat_cache_lookup(connection_struct *conn, pstring name, pstring dirpath, * We reached the end of the name - no match. */ DO_PROFILE_INC(statcache_misses); + SAFE_FREE(chk_name); return False; } if((*chk_name == '\0') || (strcmp(chk_name, ".") == 0) || (strcmp(chk_name, "..") == 0)) { DO_PROFILE_INC(statcache_misses); + SAFE_FREE(chk_name); return False; } } else { @@ -265,6 +280,7 @@ BOOL stat_cache_lookup(connection_struct *conn, pstring name, pstring dirpath, if(SMB_VFS_STAT(conn,scp->translated_path, pst) != 0) { /* Discard this entry - it doesn't exist in the filesystem. */ hash_remove(&stat_cache, hash_elem); + SAFE_FREE(chk_name); return False; } @@ -290,6 +306,7 @@ BOOL stat_cache_lookup(connection_struct *conn, pstring name, pstring dirpath, ++*start; pstrcpy(dirpath, scp->translated_path); + SAFE_FREE(chk_name); return (namelen == scp->translated_path_length); } } diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index bdcd04443e..86906fa5be 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -326,7 +326,13 @@ static BOOL exact_match(char *str,char *mask, BOOL case_sig) return False; if (case_sig) return strcmp(str,mask)==0; - return StrCaseCmp(str,mask) == 0; + if (StrCaseCmp(str,mask) != 0) { + return False; + } + if (ms_has_wild(str)) { + return False; + } + return True; } /**************************************************************************** @@ -1906,7 +1912,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, if (strequal(base_name,".")) { pstrcpy(dos_fname, "\\"); } else { - snprintf(dos_fname, sizeof(dos_fname), "\\%s", fname); + pstr_sprintf(dos_fname, "\\%s", fname); string_replace(dos_fname, '/', '\\'); } @@ -3353,6 +3359,8 @@ int reply_trans2(connection_struct *conn, memcpy( data, smb_base(inbuf) + dsoff, num_data); } + srv_signing_trans_start(SVAL(inbuf,smb_mid)); + if(num_data_sofar < total_data || num_params_sofar < total_params) { /* We need to send an interim response then receive the rest of the parameter/data bytes */ @@ -3525,6 +3533,7 @@ int reply_trans2(connection_struct *conn, SAFE_FREE(params); SAFE_FREE(data); END_PROFILE(SMBtrans2); + srv_signing_trans_stop(); return ERROR_DOS(ERRSRV,ERRerror); } @@ -3535,6 +3544,8 @@ int reply_trans2(connection_struct *conn, an error packet. */ + srv_signing_trans_stop(); + SAFE_FREE(params); SAFE_FREE(data); END_PROFILE(SMBtrans2); @@ -3544,6 +3555,7 @@ int reply_trans2(connection_struct *conn, bad_param: + srv_signing_trans_stop(); SAFE_FREE(params); SAFE_FREE(data); END_PROFILE(SMBtrans2); diff --git a/source3/smbd/utmp.c b/source3/smbd/utmp.c index 9833a11f2d..6ff2f586ba 100644 --- a/source3/smbd/utmp.c +++ b/source3/smbd/utmp.c @@ -491,8 +491,8 @@ static BOOL sys_utmp_fill(struct utmp *u, * If size limit proves troublesome, then perhaps use "ut_id_encode()". */ if (strlen(id_str) > sizeof(u->ut_line)) { - DEBUG(1,("id_str [%s] is too long for %d char utmp field\n", - id_str, sizeof(u->ut_line))); + DEBUG(1,("id_str [%s] is too long for %lu char utmp field\n", + id_str, (unsigned long)sizeof(u->ut_line))); return False; } utmp_strcpy(u->ut_line, id_str, sizeof(u->ut_line)); diff --git a/source3/tdb/tdbtool.c b/source3/tdb/tdbtool.c index 221ef4a5f2..92009dcef4 100644 --- a/source3/tdb/tdbtool.c +++ b/source3/tdb/tdbtool.c @@ -118,6 +118,7 @@ static void help(void) " erase : erase the database\n" " dump : dump the database as strings\n" " insert key data : insert a record\n" +" move key file : move a record to a destination tdb\n" " store key data : store a record (replace)\n" " show key : show a record by key\n" " delete key : delete a record by key\n" @@ -251,16 +252,26 @@ static void show_tdb(void) } key.dptr = k; -/* key.dsize = strlen(k)+1;*/ - key.dsize = strlen(k); + key.dsize = strlen(k)+1; dbuf = tdb_fetch(tdb, key); if (!dbuf.dptr) { - terror("fetch failed"); - return; + /* maybe it is non-NULL terminated key? */ + key.dsize = strlen(k); + dbuf = tdb_fetch(tdb, key); + + if ( !dbuf.dptr ) { + terror("fetch failed"); + return; + } } + /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */ print_rec(tdb, key, dbuf, NULL); + + free( dbuf.dptr ); + + return; } static void delete_tdb(void) @@ -281,6 +292,57 @@ static void delete_tdb(void) } } +static void move_rec(void) +{ + char *k = get_token(1); + char *file = get_token(0); + TDB_DATA key, dbuf; + TDB_CONTEXT *dst_tdb; + + if (!k) { + help(); + return; + } + + if ( !file ) { + terror("need destination tdb name"); + return; + } + + key.dptr = k; + key.dsize = strlen(k)+1; + + dbuf = tdb_fetch(tdb, key); + if (!dbuf.dptr) { + /* maybe it is non-NULL terminated key? */ + key.dsize = strlen(k); + dbuf = tdb_fetch(tdb, key); + + if ( !dbuf.dptr ) { + terror("fetch failed"); + return; + } + } + + print_rec(tdb, key, dbuf, NULL); + + dst_tdb = tdb_open(file, 0, 0, O_RDWR, 0600); + if ( !dst_tdb ) { + terror("unable to open destination tdb"); + return; + } + + if ( tdb_store( dst_tdb, key, dbuf, TDB_REPLACE ) == -1 ) { + terror("failed to move record"); + } + else + printf("record moved\n"); + + tdb_close( dst_tdb ); + + return; +} + #if 0 static int print_conn_key(TDB_DATA key) { @@ -455,6 +517,9 @@ int main(int argc, char *argv[]) } else if (strcmp(tok,"dump") == 0) { bIterate = 0; tdb_traverse(tdb, print_rec, NULL); + } else if (strcmp(tok,"move") == 0) { + bIterate = 0; + move_rec(); } else if (strcmp(tok,"list") == 0) { tdb_dump_all(tdb); } else if (strcmp(tok, "free") == 0) { diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c index f74fcedcf4..d91dbf50e0 100644 --- a/source3/torture/cmd_vfs.c +++ b/source3/torture/cmd_vfs.c @@ -528,7 +528,8 @@ static NTSTATUS cmd_stat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c printf(" Inode: %10u", (unsigned int)st.st_ino); printf(" Links: %10u\n", (unsigned int)st.st_nlink); printf(" Access: %05o", (st.st_mode) & 007777); - printf(" Uid: %5d/%.16s Gid: %5d/%.16s\n", st.st_uid, user, st.st_gid, group); + printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_uid, user, + (unsigned long)st.st_gid, group); printf(" Access: %s", ctime(&(st.st_atime))); printf(" Modify: %s", ctime(&(st.st_mtime))); printf(" Change: %s", ctime(&(st.st_ctime))); @@ -590,7 +591,8 @@ static NTSTATUS cmd_fstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, printf(" Inode: %10u", (unsigned int)st.st_ino); printf(" Links: %10u\n", (unsigned int)st.st_nlink); printf(" Access: %05o", (st.st_mode) & 007777); - printf(" Uid: %5d/%.16s Gid: %5d/%.16s\n", st.st_uid, user, st.st_gid, group); + printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_uid, user, + (unsigned long)st.st_gid, group); printf(" Access: %s", ctime(&(st.st_atime))); printf(" Modify: %s", ctime(&(st.st_mtime))); printf(" Change: %s", ctime(&(st.st_ctime))); @@ -640,7 +642,8 @@ static NTSTATUS cmd_lstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, printf(" Inode: %10u", (unsigned int)st.st_ino); printf(" Links: %10u\n", (unsigned int)st.st_nlink); printf(" Access: %05o", (st.st_mode) & 007777); - printf(" Uid: %5d/%.16s Gid: %5d/%.16s\n", st.st_uid, user, st.st_gid, group); + printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_uid, user, + (unsigned long)st.st_gid, group); printf(" Access: %s", ctime(&(st.st_atime))); printf(" Modify: %s", ctime(&(st.st_mtime))); printf(" Change: %s", ctime(&(st.st_ctime))); diff --git a/source3/torture/locktest.c b/source3/torture/locktest.c index 63b9590dd6..86379bf3b6 100644 --- a/source3/torture/locktest.c +++ b/source3/torture/locktest.c @@ -157,7 +157,7 @@ static struct cli_state *connect_one(char *share, int snum) zero_ip(&ip); - slprintf(myname,sizeof(myname), "lock-%u-%u", getpid(), count++); + slprintf(myname,sizeof(myname), "lock-%lu-%u", (unsigned long)getpid(), count++); make_nmb_name(&calling, myname, 0x0); make_nmb_name(&called , server, 0x20); diff --git a/source3/torture/locktest2.c b/source3/torture/locktest2.c index 97844b5609..5fbaf9ec58 100644 --- a/source3/torture/locktest2.c +++ b/source3/torture/locktest2.c @@ -173,11 +173,11 @@ static struct cli_state *connect_one(char *share) } } - slprintf(myname,sizeof(myname), "lock-%u-%u", getpid(), count++); + slprintf(myname,sizeof(myname), "lock-%lu-%u", (unsigned long)getpid(), count++); nt_status = cli_full_connection(&c, myname, server_n, NULL, 0, share, "?????", username, lp_workgroup(), password, 0, - NULL); + Undefined, NULL); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0, ("cli_full_connection failed with error %s\n", nt_errstr(nt_status))); diff --git a/source3/torture/mangle_test.c b/source3/torture/mangle_test.c index 660d4d17af..9a719349b6 100644 --- a/source3/torture/mangle_test.c +++ b/source3/torture/mangle_test.c @@ -54,7 +54,7 @@ static BOOL test_one(struct cli_state *cli, const char *name) return False; } - snprintf(name2, sizeof(name2), "\\mangle_test\\%s", shortname); + fstr_sprintf(name2, "\\mangle_test\\%s", shortname); if (!cli_unlink(cli, name2)) { printf("unlink of %s (%s) failed (%s)\n", name2, name, cli_errstr(cli)); diff --git a/source3/torture/nsstest.c b/source3/torture/nsstest.c index 0a08cb6e8f..a803cd7e71 100644 --- a/source3/torture/nsstest.c +++ b/source3/torture/nsstest.c @@ -29,11 +29,11 @@ static int total_errors; static void *find_fn(const char *name) { - char s[1024]; + pstring s; static void *h; void *res; - snprintf(s,sizeof(s), "_nss_%s_%s", nss_name, name); + pstr_sprintf(s, "_nss_%s_%s", nss_name, name); if (!h) { h = sys_dlopen(so_path, RTLD_LAZY); @@ -296,11 +296,11 @@ static int nss_initgroups(char *user, gid_t group, gid_t **groups, long int *sta static void print_passwd(struct passwd *pwd) { - printf("%s:%s:%d:%d:%s:%s:%s\n", + printf("%s:%s:%lu:%lu:%s:%s:%s\n", pwd->pw_name, pwd->pw_passwd, - pwd->pw_uid, - pwd->pw_gid, + (unsigned long)pwd->pw_uid, + (unsigned long)pwd->pw_gid, pwd->pw_gecos, pwd->pw_dir, pwd->pw_shell); @@ -309,10 +309,10 @@ static void print_passwd(struct passwd *pwd) static void print_group(struct group *grp) { int i; - printf("%s:%s:%d: ", + printf("%s:%s:%lu: ", grp->gr_name, grp->gr_passwd, - grp->gr_gid); + (unsigned long)grp->gr_gid); if (!grp->gr_mem[0]) { printf("\n"); @@ -343,9 +343,9 @@ static void nss_test_initgroups(char *name, gid_t gid) } for (i=0; i<start-1; i++) { - printf("%d, ", groups[i]); + printf("%lu, ", (unsigned long)groups[i]); } - printf("%d\n", groups[i]); + printf("%lu\n", (unsigned long)groups[i]); } diff --git a/source3/torture/torture.c b/source3/torture/torture.c index f26ebb49b3..d20c48d645 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -159,7 +159,7 @@ BOOL torture_open_connection(struct cli_state **c) host, NULL, port_to_use, share, "?????", username, workgroup, - password, flags, &retry); + password, flags, Undefined, &retry); if (!NT_STATUS_IS_OK(status)) { return False; } @@ -1128,7 +1128,7 @@ static BOOL run_tcon_devtype_test(int dummy) host, NULL, port_to_use, NULL, NULL, username, workgroup, - password, flags, &retry); + password, flags, Undefined, &retry); if (!NT_STATUS_IS_OK(status)) { printf("could not open connection\n"); @@ -4366,7 +4366,7 @@ static BOOL run_error_map_extract(int dummy) { } for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) { - snprintf(user, sizeof(user), "%X", error); + fstr_sprintf(user, "%X", error); if (cli_session_setup(&c_nt, user, password, strlen(password), @@ -4586,7 +4586,7 @@ static BOOL run_test(const char *name) } for (i=0;torture_ops[i].name;i++) { - snprintf(randomfname, sizeof(randomfname), "\\XX%x", + fstr_sprintf(randomfname, "\\XX%x", (unsigned)random()); if (strequal(name, torture_ops[i].name)) { diff --git a/source3/utils/net.c b/source3/utils/net.c index e643a3d10d..8f6b09a3fa 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -77,20 +77,7 @@ static int opt_machine_pass = 0; BOOL opt_have_ip = False; struct in_addr opt_dest_ip; -/***************************************************************************** - stubb functions -****************************************************************************/ - -void become_root( void ) -{ - return; -} - -void unbecome_root( void ) -{ - return; -} - +extern BOOL AllowDebugChange; uint32 get_sec_channel_type(const char *param) { @@ -154,7 +141,7 @@ NTSTATUS connect_to_ipc(struct cli_state **c, struct in_addr *server_ip, server_ip, opt_port, "IPC$", "IPC", opt_user_name, opt_workgroup, - opt_password, 0, NULL); + opt_password, 0, Undefined, NULL); if (NT_STATUS_IS_OK(nt_status)) { return nt_status; @@ -184,7 +171,7 @@ NTSTATUS connect_to_ipc_anonymous(struct cli_state **c, server_ip, opt_port, "IPC$", "IPC", "", "", - "", 0, NULL); + "", 0, Undefined, NULL); if (NT_STATUS_IS_OK(nt_status)) { return nt_status; @@ -580,6 +567,8 @@ static struct functable net_func[] = { zero_ip(&opt_dest_ip); + /* set default debug level to 0 regardless of what smb.conf sets */ + DEBUGLEVEL_CLASS[DBGC_ALL] = 0; dbf = x_stderr; pc = poptGetContext(NULL, argc, (const char **) argv, long_options, @@ -615,9 +604,14 @@ static struct functable net_func[] = { } } - lp_load(dyn_CONFIGFILE,True,False,False); - - argv_new = (const char **)poptGetArgs(pc); + /* + * Don't load debug level from smb.conf. It should be + * set by cmdline arg or remain default (0) + */ + AllowDebugChange = False; + lp_load(dyn_CONFIGFILE,True,False,False); + + argv_new = (const char **)poptGetArgs(pc); argc_new = argc; for (i=0; i<argc; i++) { diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 69d282420d..631e235127 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -68,7 +68,7 @@ static int net_ads_lookup(int argc, const char **argv) { ADS_STRUCT *ads; - ads = ads_init(NULL, NULL, opt_host); + ads = ads_init(NULL, opt_target_workgroup, opt_host); if (ads) { ads->auth.flags |= ADS_AUTH_NO_BIND; } @@ -89,7 +89,7 @@ static int net_ads_info(int argc, const char **argv) { ADS_STRUCT *ads; - ads = ads_init(NULL, NULL, opt_host); + ads = ads_init(NULL, opt_target_workgroup, opt_host); if (ads) { ads->auth.flags |= ADS_AUTH_NO_BIND; @@ -129,7 +129,7 @@ static ADS_STRUCT *ads_startup(void) BOOL second_time = False; char *cp; - ads = ads_init(NULL, NULL, opt_host); + ads = ads_init(NULL, opt_target_workgroup, opt_host); if (!opt_user_name) { opt_user_name = "administrator"; @@ -848,7 +848,7 @@ static int net_ads_printer_publish(int argc, const char **argv) opt_user_name, opt_workgroup, opt_password ? opt_password : "", CLI_FULL_CONNECTION_USE_KERBEROS, - NULL); + Undefined, NULL); if (NT_STATUS_IS_ERR(nt_status)) { d_printf("Unable to open a connnection to %s to obtain data " diff --git a/source3/utils/net_cache.c b/source3/utils/net_cache.c index 8dd9db599d..a955916458 100644 --- a/source3/utils/net_cache.c +++ b/source3/utils/net_cache.c @@ -214,7 +214,7 @@ static int net_cache_del(int argc, const char **argv) const char *keystr = argv[0]; if (argc < 1) { - d_printf("\nUsage: net cache add <key string>\n"); + d_printf("\nUsage: net cache del <key string>\n"); return -1; } diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c index 689d4ff813..b035d8d2f1 100644 --- a/source3/utils/net_idmap.c +++ b/source3/utils/net_idmap.c @@ -95,10 +95,14 @@ static int net_idmap_restore(int argc, const char **argv) if ( (len > 0) && (line[len-1] == '\n') ) line[len-1] = '\0'; + /* Yuck - this is broken for sizeof(gid_t) != sizeof(int) */ + if (sscanf(line, "GID %d %s", &id.gid, sid_string) == 2) { type = ID_GROUPID; } + /* Yuck - this is broken for sizeof(uid_t) != sizeof(int) */ + if (sscanf(line, "UID %d %s", &id.uid, sid_string) == 2) { type = ID_USERID; } @@ -114,9 +118,10 @@ static int net_idmap_restore(int argc, const char **argv) } if (!NT_STATUS_IS_OK(idmap_set_mapping(&sid, id, type))) { - d_printf("Could not set mapping of %s %d to sid %s\n", + d_printf("Could not set mapping of %s %lu to sid %s\n", (type == ID_GROUPID) ? "GID" : "UID", - (type == ID_GROUPID) ? id.gid : id.uid, + (type == ID_GROUPID) ? (unsigned long)id.gid: + (unsigned long)id.uid, sid_string_static(&sid)); continue; } diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index e5e9a68b2e..9eadbbbade 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -400,8 +400,7 @@ sam_account_from_delta(SAM_ACCOUNT *account, SAM_ACCOUNT_INFO *delta) return NT_STATUS_OK; } -static NTSTATUS -fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) +static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) { NTSTATUS nt_ret; fstring account; @@ -429,6 +428,7 @@ fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) (delta->acb_info & ACB_DOMTRUST) ) { pstrcpy(add_script, lp_addmachine_script()); } else { + *add_script = '\0'; DEBUG(1, ("Unknown user type: %s\n", smbpasswd_encode_acb_info(delta->acb_info))); } @@ -439,8 +439,7 @@ fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) add_ret = smbrun(add_script,NULL); DEBUG(1,("fetch_account: Running the command `%s' " "gave %d\n", add_script, add_ret)); - } - else { + } else { DEBUG(8,("fetch_account_info: no add user/machine script. Asking winbindd\n")); /* don't need a RID allocated since the user already has a SID */ @@ -487,8 +486,8 @@ fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) } else { if (map.gid != passwd->pw_gid) { if (!(grp = getgrgid(map.gid))) { - DEBUG(0, ("Could not find unix group %d for user %s (group SID=%s)\n", - map.gid, pdb_get_username(sam_account), sid_string_static(&group_sid))); + DEBUG(0, ("Could not find unix group %lu for user %s (group SID=%s)\n", + (unsigned long)map.gid, pdb_get_username(sam_account), sid_string_static(&group_sid))); } else { smb_set_primary_group(grp->gr_name, pdb_get_username(sam_account)); } @@ -585,7 +584,7 @@ fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta) } if (!(grp = getgrgid(map.gid))) { - DEBUG(0, ("Could not find unix group %d\n", map.gid)); + DEBUG(0, ("Could not find unix group %lu\n", (unsigned long)map.gid)); return NT_STATUS_NO_SUCH_GROUP; } diff --git a/source3/utils/net_time.c b/source3/utils/net_time.c index 40619a0796..45c1783805 100644 --- a/source3/utils/net_time.c +++ b/source3/utils/net_time.c @@ -71,12 +71,12 @@ static time_t nettime(int *zone) /* return a time as a string ready to be passed to /bin/date */ static char *systime(time_t t) { - static char s[100]; + static fstring s; struct tm *tm; tm = localtime(&t); - snprintf(s, sizeof(s), "%02d%02d%02d%02d%04d.%02d", + fstr_sprintf(s, "%02d%02d%02d%02d%04d.%02d", tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_year + 1900, tm->tm_sec); return s; diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 3dfa157bda..1d36a7ce52 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -32,7 +32,9 @@ enum squid_mode { SQUID_2_4_BASIC, SQUID_2_5_BASIC, - SQUID_2_5_NTLMSSP + SQUID_2_5_NTLMSSP, + GSS_SPNEGO, + GSS_SPNEGO_CLIENT }; @@ -342,6 +344,501 @@ static void manage_squid_basic_request(enum squid_mode squid_mode, } } +static void offer_gss_spnego_mechs(void) { + + DATA_BLOB token; + ASN1_DATA asn1; + SPNEGO_DATA spnego; + ssize_t len; + char *reply_base64; + + ZERO_STRUCT(spnego); + + /* Server negTokenInit (mech offerings) */ + spnego.type = SPNEGO_NEG_TOKEN_INIT; + spnego.negTokenInit.mechTypes = smb_xmalloc(sizeof(char *) * 2); + spnego.negTokenInit.mechTypes[0] = smb_xstrdup(OID_NTLMSSP); + spnego.negTokenInit.mechTypes[1] = NULL; + + ZERO_STRUCT(asn1); + asn1_push_tag(&asn1, ASN1_SEQUENCE(0)); + asn1_push_tag(&asn1, ASN1_CONTEXT(0)); + asn1_write_GeneralString(&asn1, "NONE"); + asn1_pop_tag(&asn1); + asn1_pop_tag(&asn1); + spnego.negTokenInit.mechListMIC = data_blob(asn1.data, asn1.length); + asn1_free(&asn1); + + len = write_spnego_data(&token, &spnego); + free_spnego_data(&spnego); + + if (len == -1) { + DEBUG(1, ("Could not write SPNEGO data blob\n")); + x_fprintf(x_stdout, "BH\n"); + return; + } + + reply_base64 = base64_encode_data_blob(token); + x_fprintf(x_stdout, "TT %s *\n", reply_base64); + + SAFE_FREE(reply_base64); + data_blob_free(&token); + DEBUG(10, ("sent SPNEGO negTokenInit\n")); + return; +} + +static void manage_gss_spnego_request(enum squid_mode squid_mode, + char *buf, int length) +{ + static NTLMSSP_STATE *ntlmssp_state = NULL; + SPNEGO_DATA spnego; + DATA_BLOB request, token; + NTSTATUS status; + ssize_t len; + + const char *reply_code; + char *reply_base64; + pstring reply_argument; + + if (strlen(buf) < 2) { + + if (ntlmssp_state != NULL) { + DEBUG(1, ("Request for initial SPNEGO request where " + "we already have a state\n")); + x_fprintf(x_stdout, "BH\n"); + return; + } + + DEBUG(1, ("NTLMSSP query [%s] invalid", buf)); + x_fprintf(x_stdout, "BH\n"); + return; + } + + if ( (strlen(buf) == 2) && (strcmp(buf, "YR") == 0) ) { + + /* Initial request, get the negTokenInit offering + mechanisms */ + + offer_gss_spnego_mechs(); + return; + } + + /* All subsequent requests are "KK" (Knock, Knock ;)) and have + a blob. This might be negTokenInit or negTokenTarg */ + + if ( (strlen(buf) <= 3) || (strncmp(buf, "KK", 2) != 0) ) { + DEBUG(1, ("GSS-SPNEGO query [%s] invalid\n", buf)); + x_fprintf(x_stdout, "BH\n"); + return; + } + + request = base64_decode_data_blob(buf + 3); + len = read_spnego_data(request, &spnego); + data_blob_free(&request); + + if (len == -1) { + DEBUG(1, ("GSS-SPNEGO query [%s] invalid", buf)); + x_fprintf(x_stdout, "BH\n"); + return; + } + + if (spnego.type == SPNEGO_NEG_TOKEN_INIT) { + + /* Second request from Client. This is where the + client offers its mechanism to use. We currently + only support NTLMSSP, the decision for Kerberos + would be taken here. */ + + if ( (spnego.negTokenInit.mechTypes == NULL) || + (spnego.negTokenInit.mechTypes[0] == NULL) ) { + DEBUG(1, ("Client did not offer any mechanism")); + x_fprintf(x_stdout, "BH\n"); + return; + } + + if ( strcmp(spnego.negTokenInit.mechTypes[0], OID_NTLMSSP) != 0 ) { + DEBUG(1, ("Client did not choose NTLMSSP but %s\n", + spnego.negTokenInit.mechTypes[0])); + x_fprintf(x_stdout, "BH\n"); + return; + } + + if ( spnego.negTokenInit.mechToken.data == NULL ) { + DEBUG(1, ("Client did not provide NTLMSSP data\n")); + x_fprintf(x_stdout, "BH\n"); + return; + } + + if ( ntlmssp_state != NULL ) { + DEBUG(1, ("Client wants a new NTLMSSP challenge, but " + "already got one\n")); + x_fprintf(x_stdout, "BH\n"); + ntlmssp_server_end(&ntlmssp_state); + return; + } + + ntlmssp_server_start(&ntlmssp_state); + ntlmssp_state->check_password = winbind_pw_check; + ntlmssp_state->get_domain = get_winbind_domain; + ntlmssp_state->get_global_myname = get_winbind_netbios_name; + + DEBUG(10, ("got NTLMSSP packet:\n")); + dump_data(10, spnego.negTokenInit.mechToken.data, + spnego.negTokenInit.mechToken.length); + + free_spnego_data(&spnego); + + spnego.type = SPNEGO_NEG_TOKEN_TARG; + spnego.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; + spnego.negTokenTarg.supportedMech = strdup(OID_NTLMSSP); + + status = ntlmssp_server_update(ntlmssp_state, + spnego.negTokenInit.mechToken, + &spnego.negTokenTarg.responseToken); + + } else { + + /* spnego.type == SPNEGO_NEG_TOKEN_TARG */ + + DATA_BLOB response; + + if (spnego.negTokenTarg.responseToken.data == NULL) { + DEBUG(1, ("Got a negTokenArg without a responseToken!\n")); + x_fprintf(x_stdout, "BH\n"); + return; + } + + status = ntlmssp_server_update(ntlmssp_state, + spnego.negTokenTarg.responseToken, + &response); + + data_blob_free(&spnego.negTokenTarg.responseToken); + + spnego.negTokenTarg.responseToken = response; + + } + + if (NT_STATUS_IS_OK(status)) { + spnego.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED; + reply_code = "AF"; + pstr_sprintf(reply_argument, "%s\\%s", + ntlmssp_state->domain, ntlmssp_state->user); + } else if (NT_STATUS_EQUAL(status, + NT_STATUS_MORE_PROCESSING_REQUIRED)) { + spnego.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; + reply_code = "TT"; + pstr_sprintf(reply_argument, "*"); + } else { + spnego.negTokenTarg.negResult = SPNEGO_REJECT; + reply_code = "NA"; + pstrcpy(reply_argument, nt_errstr(status)); + } + + len = write_spnego_data(&token, &spnego); + free_spnego_data(&spnego); + + if (len == -1) { + DEBUG(1, ("Could not write SPNEGO data blob\n")); + x_fprintf(x_stdout, "BH\n"); + return; + } + + reply_base64 = base64_encode_data_blob(token); + + x_fprintf(x_stdout, "%s %s %s\n", + reply_code, reply_base64, reply_argument); + + SAFE_FREE(reply_base64); + data_blob_free(&token); + + if (NT_STATUS_IS_OK(status)) { + ntlmssp_server_end(&ntlmssp_state); + } + + return; +} + +static NTLMSSP_CLIENT_STATE *client_ntlmssp_state = NULL; + +static void manage_client_ntlmssp_init(SPNEGO_DATA spnego) +{ + NTSTATUS status; + DATA_BLOB null_blob = data_blob(NULL, 0); + DATA_BLOB to_server; + char *to_server_base64; + const char *my_mechs[] = {OID_NTLMSSP, NULL}; + + DEBUG(10, ("Got spnego negTokenInit with NTLMSSP\n")); + + if (client_ntlmssp_state != NULL) { + DEBUG(1, ("Request for initial SPNEGO request where " + "we already have a state\n")); + x_fprintf(x_stdout, "BH\n"); + return; + } + + if ( (opt_username == NULL) || (opt_domain == NULL) ) { + DEBUG(1, ("Need username and domain for NTLMSSP\n")); + x_fprintf(x_stdout, "BH\n"); + return; + } + + if (opt_password == NULL) { + + /* Request a password from the calling process. After + sending it, the calling process should retry with + the negTokenInit. */ + + DEBUG(10, ("Requesting password\n")); + x_fprintf(x_stdout, "PW\n"); + return; + } + + status = ntlmssp_client_start(&client_ntlmssp_state); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Could not start NTLMSSP client: %s\n", + nt_errstr(status))); + x_fprintf(x_stdout, "BH\n"); + ntlmssp_client_end(&client_ntlmssp_state); + return; + } + + status = ntlmssp_set_username(client_ntlmssp_state, opt_username); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Could not set username: %s\n", + nt_errstr(status))); + x_fprintf(x_stdout, "BH\n"); + ntlmssp_client_end(&client_ntlmssp_state); + return; + } + + status = ntlmssp_set_domain(client_ntlmssp_state, opt_domain); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Could not set domain: %s\n", + nt_errstr(status))); + x_fprintf(x_stdout, "BH\n"); + ntlmssp_client_end(&client_ntlmssp_state); + return; + } + + status = ntlmssp_set_password(client_ntlmssp_state, opt_password); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Could not set password: %s\n", + nt_errstr(status))); + x_fprintf(x_stdout, "BH\n"); + ntlmssp_client_end(&client_ntlmssp_state); + return; + } + + spnego.type = SPNEGO_NEG_TOKEN_INIT; + spnego.negTokenInit.mechTypes = my_mechs; + spnego.negTokenInit.reqFlags = 0; + spnego.negTokenInit.mechListMIC = null_blob; + + status = ntlmssp_client_update(client_ntlmssp_state, null_blob, + &spnego.negTokenInit.mechToken); + + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + DEBUG(1, ("Expected MORE_PROCESSING_REQUIRED, got: %s\n", + nt_errstr(status))); + x_fprintf(x_stdout, "BH\n"); + ntlmssp_client_end(&client_ntlmssp_state); + return; + } + + write_spnego_data(&to_server, &spnego); + data_blob_free(&spnego.negTokenInit.mechToken); + + to_server_base64 = base64_encode_data_blob(to_server); + data_blob_free(&to_server); + x_fprintf(x_stdout, "KK %s\n", to_server_base64); + SAFE_FREE(to_server_base64); + return; +} + +static void manage_client_ntlmssp_targ(SPNEGO_DATA spnego) +{ + NTSTATUS status; + DATA_BLOB null_blob = data_blob(NULL, 0); + DATA_BLOB request; + DATA_BLOB to_server; + char *to_server_base64; + + DEBUG(10, ("Got spnego negTokenTarg with NTLMSSP\n")); + + if (client_ntlmssp_state == NULL) { + DEBUG(1, ("Got NTLMSSP tArg without a client state\n")); + x_fprintf(x_stdout, "BH\n"); + ntlmssp_client_end(&client_ntlmssp_state); + return; + } + + if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) { + x_fprintf(x_stdout, "NA\n"); + ntlmssp_client_end(&client_ntlmssp_state); + return; + } + + if (spnego.negTokenTarg.negResult == SPNEGO_ACCEPT_COMPLETED) { + x_fprintf(x_stdout, "AF\n"); + ntlmssp_client_end(&client_ntlmssp_state); + return; + } + + status = ntlmssp_client_update(client_ntlmssp_state, + spnego.negTokenTarg.responseToken, + &request); + + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + DEBUG(1, ("Expected MORE_PROCESSING_REQUIRED from " + "ntlmssp_client_update, got: %s\n", + nt_errstr(status))); + x_fprintf(x_stdout, "BH\n"); + data_blob_free(&request); + ntlmssp_client_end(&client_ntlmssp_state); + return; + } + + spnego.type = SPNEGO_NEG_TOKEN_TARG; + spnego.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; + spnego.negTokenTarg.supportedMech = OID_NTLMSSP; + spnego.negTokenTarg.responseToken = request; + spnego.negTokenTarg.mechListMIC = null_blob; + + write_spnego_data(&to_server, &spnego); + data_blob_free(&request); + + to_server_base64 = base64_encode_data_blob(to_server); + data_blob_free(&to_server); + x_fprintf(x_stdout, "KK %s\n", to_server_base64); + SAFE_FREE(to_server_base64); + return; +} + +static void manage_client_krb5_init(SPNEGO_DATA spnego) +{ + DEBUG(1, ("to be done ... \n")); + x_fprintf(x_stdout, "BH\n"); + return; +} + +static void manage_client_krb5_targ(SPNEGO_DATA spnego) +{ + DEBUG(1, ("Got a negTokenTarg with a Kerberos token. This should not " + "happen!\n")); + x_fprintf(x_stdout, "BH\n"); + return; +} + +static void manage_gss_spnego_client_request(enum squid_mode squid_mode, + char *buf, int length) +{ + DATA_BLOB request; + SPNEGO_DATA spnego; + ssize_t len; + + if (strlen(buf) <= 3) { + DEBUG(1, ("SPNEGO query [%s] too short\n", buf)); + x_fprintf(x_stdout, "BH\n"); + return; + } + + request = base64_decode_data_blob(buf+3); + + if (strncmp(buf, "PW ", 3) == 0) { + + /* We asked for a password and obviously got it :-) */ + + opt_password = strndup(request.data, request.length); + + if (opt_password == NULL) { + DEBUG(1, ("Out of memory\n")); + x_fprintf(x_stdout, "BH\n"); + data_blob_free(&request); + return; + } + + x_fprintf(x_stdout, "OK\n"); + data_blob_free(&request); + return; + } + + if ( (strncmp(buf, "TT ", 3) != 0) && + (strncmp(buf, "AF ", 3) != 0) && + (strncmp(buf, "NA ", 3) != 0) ) { + DEBUG(1, ("SPNEGO request [%s] invalid\n", buf)); + x_fprintf(x_stdout, "BH\n"); + data_blob_free(&request); + return; + } + + /* So we got a server challenge to generate a SPNEGO + client-to-server request... */ + + len = read_spnego_data(request, &spnego); + data_blob_free(&request); + + if (len == -1) { + DEBUG(1, ("Could not read SPNEGO data for [%s]\n", buf)); + x_fprintf(x_stdout, "BH\n"); + return; + } + + if (spnego.type == SPNEGO_NEG_TOKEN_INIT) { + + /* The server offers a list of mechanisms */ + + const char **mechType = spnego.negTokenInit.mechTypes; + + while (*mechType != NULL) { + + if (strcmp(*mechType, OID_NTLMSSP) == 0) { + manage_client_ntlmssp_init(spnego); + goto out; + } + + if (strcmp(*mechType, OID_KERBEROS5_OLD) == 0) { + manage_client_krb5_init(spnego); + goto out; + } + + mechType++; + } + + DEBUG(1, ("Server offered no compatible mechanism\n")); + x_fprintf(x_stdout, "BH\n"); + return; + } + + if (spnego.type == SPNEGO_NEG_TOKEN_TARG) { + + if (strcmp(spnego.negTokenTarg.supportedMech, + OID_NTLMSSP) == 0) { + manage_client_ntlmssp_targ(spnego); + goto out; + } + + if (strcmp(spnego.negTokenTarg.supportedMech, + OID_KERBEROS5_OLD) == 0) { + manage_client_krb5_targ(spnego); + goto out; + } + + } + + DEBUG(1, ("Got an SPNEGO token I could not handle [%s]!\n", buf)); + x_fprintf(x_stdout, "BH\n"); + return; + + out: + free_spnego_data(&spnego); + return; +} + static void manage_squid_request(enum squid_mode squid_mode) { char buf[SQUID_BUFFER_SIZE+1]; @@ -383,6 +880,10 @@ static void manage_squid_request(enum squid_mode squid_mode) manage_squid_basic_request(squid_mode, buf, length); } else if (squid_mode == SQUID_2_5_NTLMSSP) { manage_squid_ntlmssp_request(squid_mode, buf, length); + } else if (squid_mode == GSS_SPNEGO) { + manage_gss_spnego_request(squid_mode, buf, length); + } else if (squid_mode == GSS_SPNEGO_CLIENT) { + manage_gss_spnego_client_request(squid_mode, buf, length); } } @@ -1334,6 +1835,10 @@ enum { squid_stream(SQUID_2_5_BASIC); } else if (strcmp(helper_protocol, "squid-2.4-basic")== 0) { squid_stream(SQUID_2_4_BASIC); + } else if (strcmp(helper_protocol, "gss-spnego")== 0) { + squid_stream(GSS_SPNEGO); + } else if (strcmp(helper_protocol, "gss-spnego-client") == 0) { + squid_stream(GSS_SPNEGO_CLIENT); } else { x_fprintf(x_stderr, "unknown helper protocol [%s]\n", helper_protocol); exit(1); @@ -1372,7 +1877,7 @@ enum { } else { fstring user; - snprintf(user, sizeof(user)-1, "%s%c%s", opt_domain, winbind_separator(), opt_username); + fstr_sprintf(user, "%s%c%s", opt_domain, winbind_separator(), opt_username); if (!check_plaintext_auth(user, opt_password, True)) { exit(1); } diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index 96d0d3c057..0f1f6edf08 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -51,21 +51,6 @@ #define MASK_ALWAYS_GOOD 0x0000001F #define MASK_USER_GOOD 0x00401F00 -/***************************************************************************** - stubb functions -****************************************************************************/ - -void become_root( void ) -{ - return; -} - -void unbecome_root( void ) -{ - return; -} - - /********************************************************* Add all currently available users to another db ********************************************************/ @@ -176,16 +161,17 @@ static int print_sam_info (SAM_ACCOUNT *sam_pwent, BOOL verbosity, BOOL smbpwdst pdb_sethexpwd(lm_passwd, pdb_get_lanman_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent)); pdb_sethexpwd(nt_passwd, pdb_get_nt_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent)); - printf("%s:%d:%s:%s:%s:LCT-%08X:\n", + printf("%s:%lu:%s:%s:%s:LCT-%08X:\n", pdb_get_username(sam_pwent), - uid, + (unsigned long)uid, lm_passwd, nt_passwd, pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sam_pwent),NEW_PW_FORMAT_SPACE_PADDED_LEN), (uint32)pdb_get_pass_last_set_time(sam_pwent)); } else { uid = nametouid(pdb_get_username(sam_pwent)); - printf ("%s:%d:%s\n", pdb_get_username(sam_pwent), uid, pdb_get_fullname(sam_pwent)); + printf ("%s:%lu:%s\n", pdb_get_username(sam_pwent), (unsigned long)uid, + pdb_get_fullname(sam_pwent)); } return 0; diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c index 69dc2dd47a..c90c042106 100644 --- a/source3/utils/smbcacls.c +++ b/source3/utils/smbcacls.c @@ -724,7 +724,8 @@ static struct cli_state *connect_one(const char *share) &ip, 0, share, "?????", cmdline_auth_info.username, lp_workgroup(), - cmdline_auth_info.password, 0, NULL))) { + cmdline_auth_info.password, 0, + cmdline_auth_info.signing_state, NULL))) { return c; } else { DEBUG(0,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status))); diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c index b7333f2317..190627e2a5 100644 --- a/source3/utils/smbcontrol.c +++ b/source3/utils/smbcontrol.c @@ -591,12 +591,6 @@ static const struct { { NULL } }; -/* Yuck - we need these because we link to printing*.o even though - they aren't used. */ - -void become_root(void) {} -void unbecome_root(void) {} - /* Display usage information */ static void usage(poptContext *pc) diff --git a/source3/utils/smbcquotas.c b/source3/utils/smbcquotas.c index 9c7379ca2a..64321d5bfc 100644 --- a/source3/utils/smbcquotas.c +++ b/source3/utils/smbcquotas.c @@ -371,7 +371,8 @@ static struct cli_state *connect_one(const char *share) &ip, 0, share, "?????", cmdline_auth_info.username, lp_workgroup(), - cmdline_auth_info.password, 0, NULL))) { + cmdline_auth_info.password, 0, + cmdline_auth_info.signing_state, NULL))) { return c; } else { DEBUG(0,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status))); diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c index eade5331af..6ab6d35e73 100644 --- a/source3/utils/smbpasswd.c +++ b/source3/utils/smbpasswd.c @@ -37,21 +37,6 @@ static const char *remote_machine = NULL; static fstring ldap_secret; -/***************************************************************************** - stubb functions -****************************************************************************/ - -void become_root( void ) -{ - return; -} - -void unbecome_root( void ) -{ - return; -} - - /********************************************************* Print command usage on stderr and die. **********************************************************/ diff --git a/source3/utils/status.c b/source3/utils/status.c index bbaeecdd6b..8bf67fc4d6 100644 --- a/source3/utils/status.c +++ b/source3/utils/status.c @@ -45,11 +45,6 @@ static int locks_only = 0; /* Added by RJS */ static BOOL processes_only=False; static int show_brl; -/* we need these because we link to locking*.o */ - void become_root(void) {} - void unbecome_root(void) {} - - /* added by OH */ static void Ucrit_addUsername(const char *username) { diff --git a/source3/web/statuspage.c b/source3/web/statuspage.c index 44461232b8..c579e8f112 100644 --- a/source3/web/statuspage.c +++ b/source3/web/statuspage.c @@ -93,7 +93,7 @@ static char *mapPid2Machine (pid_t pid) } /* PID not in list or machine name NULL? return pid as string */ - snprintf (pidbuf, sizeof (pidbuf) - 1, "%d", pid); + snprintf (pidbuf, sizeof (pidbuf) - 1, "%lu", (unsigned long)pid); return pidbuf; } diff --git a/source3/web/swat.c b/source3/web/swat.c index d97278c485..a1c132a088 100644 --- a/source3/web/swat.c +++ b/source3/web/swat.c @@ -51,10 +51,6 @@ static int iNumNonAutoPrintServices = 0; #define ENABLE_USER_FLAG "enable_user_flag" #define RHOST "remote_host" -/* we need these because we link to locking*.o */ - void become_root(void) {} - void unbecome_root(void) {} - /**************************************************************************** ****************************************************************************/ static int enum_index(int value, const struct enum_list *enumlist) @@ -168,12 +164,12 @@ static const char* get_parm_translated( static pstring output; if(strcmp(pLabel, pTranslated) != 0) { - snprintf(output, sizeof(output), + pstr_sprintf(output, "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>", pAnchor, pHelp, pLabel, pTranslated); return output; } - snprintf(output, sizeof(output), + pstr_sprintf(output, "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s", pAnchor, pHelp, pLabel); return output; @@ -316,9 +312,10 @@ static void show_parameters(int snum, int allparameters, unsigned int parm_filte if (printers & !(parm->flags & FLAG_PRINT)) continue; if (!printers & !(parm->flags & FLAG_SHARE)) continue; } - if (parm_filter == FLAG_BASIC) { + + if (!( parm_filter & FLAG_ADVANCED )) { if (!(parm->flags & FLAG_BASIC)) { - void *ptr = parm->ptr; + void *ptr = parm->ptr; if (parm->class == P_LOCAL && snum >= 0) { ptr = lp_local_ptr(snum, ptr); @@ -359,16 +356,15 @@ static void show_parameters(int snum, int allparameters, unsigned int parm_filte break; case P_SEP: continue; - } + } } if (printers && !(parm->flags & FLAG_PRINT)) continue; } - if (parm_filter == FLAG_WIZARD) { - if (!((parm->flags & FLAG_WIZARD))) continue; - } - if (parm_filter == FLAG_ADVANCED) { - if (!((parm->flags & FLAG_ADVANCED))) continue; - } + + if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue; + + if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue; + if (heading && heading != last_heading) { d_printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading)); last_heading = heading; @@ -523,10 +519,12 @@ static void show_main_buttons(void) ****************************************************************************/ static void ViewModeBoxes(int mode) { - d_printf("<p>%s\n", _("Configuration View: ")); + d_printf("<p>%s\n", _("Current View Is:  \n")); d_printf("<input type=radio name=\"ViewMode\" value=0 %s>Basic\n", (mode == 0) ? "checked" : ""); d_printf("<input type=radio name=\"ViewMode\" value=1 %s>Advanced\n", (mode == 1) ? "checked" : ""); - d_printf("<input type=radio name=\"ViewMode\" value=2 %s>Developer\n", (mode == 2) ? "checked" : ""); + d_printf("<br>%s\n", _("Change View To: ")); + d_printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic")); + d_printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced")); d_printf("</p><br>\n"); } @@ -782,6 +780,10 @@ static void globals_page(void) if ( cgi_variable("ViewMode") ) mode = atoi(cgi_variable("ViewMode")); + if ( cgi_variable("BasicMode")) + mode = 0; + if ( cgi_variable("AdvMode")) + mode = 1; d_printf("<form name=\"swatform\" method=post action=globals>\n"); @@ -793,9 +795,6 @@ static void globals_page(void) case 1: parm_filter = FLAG_ADVANCED; break; - case 2: - parm_filter = FLAG_DEVELOPER; - break; } d_printf("<br>\n"); if (have_write_access) { @@ -854,8 +853,14 @@ static void shares_page(void) d_printf("<FORM name=\"swatform\" method=post>\n"); d_printf("<table>\n"); + if ( cgi_variable("ViewMode") ) mode = atoi(cgi_variable("ViewMode")); + if ( cgi_variable("BasicMode")) + mode = 0; + if ( cgi_variable("AdvMode")) + mode = 1; + ViewModeBoxes( mode ); switch ( mode ) { case 0: @@ -864,9 +869,6 @@ static void shares_page(void) case 1: parm_filter = FLAG_ADVANCED; break; - case 2: - parm_filter = FLAG_DEVELOPER; - break; } d_printf("<br><tr>\n"); d_printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share")); @@ -1196,6 +1198,11 @@ static void printers_page(void) if ( cgi_variable("ViewMode") ) mode = atoi(cgi_variable("ViewMode")); + if ( cgi_variable("BasicMode")) + mode = 0; + if ( cgi_variable("AdvMode")) + mode = 1; + ViewModeBoxes( mode ); switch ( mode ) { case 0: @@ -1204,9 +1211,6 @@ static void printers_page(void) case 1: parm_filter = FLAG_ADVANCED; break; - case 2: - parm_filter = FLAG_DEVELOPER; - break; } d_printf("<table>\n"); d_printf("<tr><td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Printer")); |