diff options
author | Gerald Carter <jerry@samba.org> | 2003-06-06 14:53:28 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2003-06-06 14:53:28 +0000 |
commit | 7e7904e91ebf6c33cea422e903762409099717d1 (patch) | |
tree | 6efec48ab63a369d1597c4b9c8fa9fa1a39599d8 | |
parent | 3fbef9f51c5b3741c53752834352db04e1c2660d (diff) | |
download | samba-7e7904e91ebf6c33cea422e903762409099717d1.tar.gz |
working on creating the 3.0 release tree
143 files changed, 6307 insertions, 5529 deletions
diff --git a/source/Makefile.in b/source/Makefile.in index 5fa3018c696..1ebaa37d0b1 100644 --- a/source/Makefile.in +++ b/source/Makefile.in @@ -31,6 +31,7 @@ PRINTLIBS=@PRINTLIBS@ AUTHLIBS=@AUTHLIBS@ ACLLIBS=@ACLLIBS@ PASSDBLIBS=@PASSDBLIBS@ +IDMAP_LIBS=@IDMAP_LIBS@ ADSLIBS=@ADSLIBS@ KRB5LIBS=@KRB5_LIBS@ @@ -41,8 +42,8 @@ INSTALLCLIENTCMD_SH=@INSTALLCLIENTCMD_SH@ INSTALLCLIENTCMD_A=@INSTALLCLIENTCMD_A@ VPATH=@srcdir@ -srcdir=@srcdir@ -builddir=@builddir@ +srcdir=@abs_srcdir@ +builddir=@abs_builddir@ SHELL=/bin/sh # XXX: Perhaps this should be @SHELL@ instead -- apparently autoconf @@ -60,6 +61,7 @@ LIBDIR = @libdir@ VFSLIBDIR = $(LIBDIR)/vfs PDBLIBDIR = $(LIBDIR)/pdb RPCLIBDIR = $(LIBDIR)/rpc +IDMAPLIBDIR = $(LIBDIR)/idmap CHARSETLIBDIR = $(LIBDIR)/charset AUTHLIBDIR = $(LIBDIR)/auth CONFIGDIR = @configdir@ @@ -119,15 +121,15 @@ PATH_FLAGS = $(PATH_FLAGS6) $(PASSWD_FLAGS) # Note that all executable programs now provide for an optional executable suffix. SBIN_PROGS = bin/smbd@EXEEXT@ bin/nmbd@EXEEXT@ bin/swat@EXEEXT@ \ - bin/wrepld@EXEEXT@ @EXTRA_SBIN_PROGS@ + @EXTRA_SBIN_PROGS@ BIN_PROGS1 = bin/smbclient@EXEEXT@ bin/net@EXEEXT@ bin/smbspool@EXEEXT@ \ bin/testparm@EXEEXT@ bin/testprns@EXEEXT@ bin/smbstatus@EXEEXT@ BIN_PROGS2 = bin/smbcontrol@EXEEXT@ bin/smbtree@EXEEXT@ bin/tdbbackup@EXEEXT@ \ - bin/nmblookup@EXEEXT@ bin/pdbedit@EXEEXT@ + bin/nmblookup@EXEEXT@ bin/pdbedit@EXEEXT@ bin/editreg@EXEEXT@ BIN_PROGS3 = bin/smbpasswd@EXEEXT@ bin/rpcclient@EXEEXT@ bin/smbcacls@EXEEXT@ \ bin/profiles@EXEEXT@ bin/ntlm_auth@EXEEXT@ \ - bin/editreg@EXEEXT@ bin/smbcquotas@EXEEXT@ + bin/smbcquotas@EXEEXT@ TORTURE_PROGS = bin/smbtorture@EXEEXT@ bin/msgtest@EXEEXT@ \ bin/masktest@EXEEXT@ bin/locktest@EXEEXT@ \ @@ -141,14 +143,13 @@ SHLIBS = @SHLIB_PROGS@ @LIBSMBCLIENT@ SCRIPTS = $(srcdir)/script/smbtar $(builddir)/script/findsmb -QUOTAOBJS=@QUOTAOBJS@ - VFS_MODULES = @VFS_MODULES@ PDB_MODULES = @PDB_MODULES@ RPC_MODULES = @RPC_MODULES@ +IDMAP_MODULES = @IDMAP_MODULES@ CHARSET_MODULES = @CHARSET_MODULES@ AUTH_MODULES = @AUTH_MODULES@ -MODULES = $(VFS_MODULES) $(PDB_MODULES) $(RPC_MODULES) $(CHARSET_MODULES) $(AUTH_MODULES) +MODULES = $(VFS_MODULES) $(PDB_MODULES) $(RPC_MODULES) $(IDMAP_MODULES) $(CHARSET_MODULES) $(AUTH_MODULES) ###################################################################### # object file lists @@ -157,6 +158,8 @@ MODULES = $(VFS_MODULES) $(PDB_MODULES) $(RPC_MODULES) $(CHARSET_MODULES) $(AUTH TDBBASE_OBJ = tdb/tdb.o tdb/spinlock.o TDB_OBJ = $(TDBBASE_OBJ) tdb/tdbutil.o +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 \ @@ -175,10 +178,9 @@ LIB_OBJ = lib/charcnv.o lib/debug.o lib/fault.o \ nsswitch/wb_client.o nsswitch/wb_common.o \ lib/pam_errors.o intl/lang_tdb.o lib/account_pol.o \ lib/adt_tree.o lib/gencache.o $(TDB_OBJ) \ - lib/module.o lib/genparser.o lib/genparser_samba.o \ - lib/ldap_escape.o @CHARSET_STATIC@ + lib/module.o lib/ldap_escape.o @CHARSET_STATIC@ -LIB_SMBD_OBJ = lib/system_smbd.o lib/util_smbd.o +LIB_SMBD_OBJ = lib/system_smbd.o lib/util_smbd.o READLINE_OBJ = lib/readline.o @@ -204,9 +206,7 @@ SECRETS_OBJ = passdb/secrets.o LIBNMB_OBJ = libsmb/unexpected.o libsmb/namecache.o libsmb/nmblib.o \ libsmb/namequery.o -LIBNTLMSSP_OBJ = libsmb/ntlmssp.o libsmb/ntlmssp_parse.o libsmb/ntlmssp_sign.o - -LIBSAMBA_OBJ = libsmb/nterr.o libsmb/smbdes.o libsmb/smbencrypt.o +LIBSAMBA_OBJ = libsmb/nterr.o libsmb/smbdes.o libsmb/smbencrypt.o libsmb/ntlmssp.o libsmb/ntlmssp_parse.o libsmb/ntlmssp_sign.o LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \ libsmb/clikrb5.o libsmb/clispnego.o libsmb/asn1.o \ @@ -219,7 +219,7 @@ LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \ libsmb/clioplock.o libsmb/errormap.o libsmb/clirap2.o \ libsmb/passchange.o libsmb/doserr.o \ libsmb/trustdom_cache.o \ - $(RPC_PARSE_OBJ1) $(LIBNTLMSSP_OBJ) $(LIBSAMBA_OBJ) $(LIBNMB_OBJ) + $(RPC_PARSE_OBJ1) $(LIBSAMBA_OBJ) $(LIBNMB_OBJ) LIBMSRPC_OBJ = rpc_client/cli_lsarpc.o rpc_client/cli_samr.o \ rpc_client/cli_netlogon.o rpc_client/cli_srvsvc.o \ @@ -279,26 +279,19 @@ PASSDB_GET_SET_OBJ = passdb/pdb_get_set.o PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \ passdb/machine_sid.o passdb/util_sam_sid.o passdb/pdb_compat.o \ - passdb/privileges.o @LDAP_OBJ@ @PDB_STATIC@ + passdb/privileges.o @PDB_STATIC@ XML_OBJ = passdb/pdb_xml.o MYSQL_OBJ = passdb/pdb_mysql.o -DEVEL_HELP_OBJ = modules/developer.o - -SAM_STATIC_MODULES = sam/sam_plugin.o sam/sam_skel.o sam/sam_ads.o +DEVEL_HELP_OBJ = modules/weird.o -IDMAP_OBJ = sam/idmap.o sam/idmap_util.o sam/idmap_tdb.o - -SAM_OBJ = sam/account.o sam/get_set_account.o sam/get_set_group.o \ - sam/get_set_domain.o sam/interface.o $(SAM_STATIC_MODULES) - -SAMTEST_OBJ = torture/samtest.o torture/cmd_sam.o $(PARAM_OBJ) $(SAM_OBJ) $(LIB_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(READLINE_OBJ) lib/util_seaccess.o $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(PASSDB_OBJ) $(SECRETS_OBJ) $(GROUPDB_OBJ) +IDMAP_OBJ = sam/idmap.o sam/idmap_util.o @IDMAP_STATIC@ GROUPDB_OBJ = groupdb/mapping.o PROFILE_OBJ = profile/profile.o PROFILES_OBJ = utils/profiles.o -EDITREG_OBJ = utils/editreg.o lib/snprintf.o +EDITREG_OBJ = utils/editreg.o OPLOCK_OBJ = smbd/oplock.o smbd/oplock_irix.o smbd/oplock_linux.o @@ -306,9 +299,9 @@ NOTIFY_OBJ = smbd/notify.o smbd/notify_hash.o smbd/notify_kernel.o VFS_AUDIT_OBJ = modules/vfs_audit.o 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_FAKE_PERMS_OBJ = modules/vfs_fake_perms.o PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o @@ -330,6 +323,8 @@ MANGLE_OBJ = smbd/mangle.o smbd/mangle_hash.o smbd/mangle_map.o smbd/mangle_hash SMBD_OBJ_MAIN = smbd/server.o +BUILDOPT_OBJ = smbd/build_options.o + SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \ smbd/utmp.o smbd/session.o \ smbd/dfree.o smbd/dir.o smbd/password.o smbd/conn.o smbd/fileio.o \ @@ -342,20 +337,19 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \ smbd/posix_acls.o lib/sysacls.o lib/server_mutex.o \ smbd/process.o smbd/service.o smbd/error.o \ printing/printfsp.o lib/util_seaccess.o \ - smbd/build_options.o \ - smbd/change_trust_pw.o \ + lib/sysquotas.o smbd/change_trust_pw.o smbd/fake_file.o \ + smbd/quotas.o smbd/ntquotas.o \ $(MANGLE_OBJ) @VFS_STATIC@ SMBD_OBJ_BASE = $(PARAM_OBJ) $(SMBD_OBJ_SRV) $(MSDFS_OBJ) $(LIBSMB_OBJ) \ - $(RPC_SERVER_OBJ) $(RPC_PARSE_OBJ) $(SECRETS_OBJ) $(UBIQX_OBJ) \ + $(RPC_SERVER_OBJ) $(RPC_PARSE_OBJ) $(SECRETS_OBJ) \ $(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) \ - $(LIB_OBJ) $(PRINTBACKEND_OBJ) $(QUOTAOBJS) $(OPLOCK_OBJ) \ + $(LIB_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) \ $(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \ $(LIBMSRPC_OBJ) $(LIBMSRPC_SERVER_OBJ) \ $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(LIBADS_SERVER_OBJ) \ - $(LIB_SMBD_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \ - $(IDMAP_OBJ) - + $(LIB_SMBD_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) $(IDMAP_OBJ) \ + $(UBIQX_OBJ) $(BUILDOPT_OBJ) $(SMBLDAP_OBJ) PRINTING_OBJ = printing/pcap.o printing/print_svid.o \ printing/print_cups.o printing/print_generic.o \ @@ -395,7 +389,7 @@ 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) $(IDMAP_OBJ) + $(POPT_LIB_OBJ) $(IDMAP_OBJ) $(SMBLDAP_OBJ) SMBSH_OBJ = smbwrapper/smbsh.o smbwrapper/shared.o \ $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) @@ -420,14 +414,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) \ - $(IDMAP_OBJ) + $(IDMAP_OBJ) $(SMBLDAP_OBJ) PDBEDIT_OBJ = utils/pdbedit.o $(PARAM_OBJ) $(PASSDB_OBJ) $(LIBSAMBA_OBJ) \ $(UBIQX_OBJ) $(LIB_OBJ) $(GROUPDB_OBJ) $(SECRETS_OBJ) \ - $(POPT_LIB_OBJ) $(IDMAP_OBJ) - -SMBGROUPEDIT_OBJ = utils/smbgroupedit.o $(GROUPDB_OBJ) $(PARAM_OBJ) \ - $(LIBSAMBA_OBJ) $(PASSDB_OBJ) $(SECRETS_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) $(IDMAP_OBJ) + $(POPT_LIB_OBJ) $(IDMAP_OBJ) $(SMBLDAP_OBJ) RPCCLIENT_OBJ1 = rpcclient/rpcclient.o rpcclient/cmd_lsarpc.o \ rpcclient/cmd_samr.o rpcclient/cmd_spoolss.o \ @@ -441,7 +432,7 @@ RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \ $(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(LIBMSRPC_OBJ) \ $(READLINE_OBJ) $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) \ $(LIBADS_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) \ - $(IDMAP_OBJ) + $(IDMAP_OBJ) $(SMBLDAP_OBJ) PAM_WINBIND_OBJ = nsswitch/pam_winbind.po nsswitch/wb_common.po lib/snprintf.po @@ -469,7 +460,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) + $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ) LIBBIGBALLOFMUD_PICOBJS = $(LIBBIGBALLOFMUD_OBJ:.o=.po) @@ -489,7 +480,7 @@ NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \ $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \ $(LIBMSRPC_OBJ) $(LIBMSRPC_SERVER_OBJ) \ $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) $(POPT_LIB_OBJ) \ - $(IDMAP_OBJ) + $(IDMAP_OBJ) $(SMBLDAP_OBJ) CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \ $(LIB_OBJ) $(KRBCLIENT_OBJ) @@ -563,12 +554,12 @@ PROTO_OBJ = $(SMBD_OBJ_MAIN) \ $(RPC_PIPE_OBJ) $(RPC_PARSE_OBJ) $(KRBCLIENT_OBJ) \ $(AUTH_OBJ) $(PARAM_OBJ) $(LOCKING_OBJ) $(SECRETS_OBJ) \ $(PRINTING_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) $(NOTIFY_OBJ) \ - $(QUOTAOBJS) $(PASSDB_OBJ) $(GROUPDB_OBJ) $(MSDFS_OBJ) \ + $(PASSDB_OBJ) $(GROUPDB_OBJ) $(MSDFS_OBJ) \ $(READLINE_OBJ) $(PROFILE_OBJ) $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) \ $(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) \ - $(IDMAP_OBJ) $(RPC_ECHO_OBJ) + $(IDMAP_OBJ) $(RPC_ECHO_OBJ) $(SMBLDAP_OBJ) NSS_OBJ_0 = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) $(LIBSMB_OBJ) \ $(LIB_OBJ) $(NSSWINS_OBJ) @@ -607,10 +598,11 @@ WINBINDD_OBJ = \ $(WINBINDD_OBJ1) $(PASSDB_OBJ) $(GROUPDB_OBJ) \ $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \ $(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) \ - $(PROFILE_OBJ) $(UNIGRP_OBJ) $(IDMAP_OBJ) \ - $(SECRETS_OBJ) $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) + $(PROFILE_OBJ) $(UNIGRP_OBJ) $(IDMAP_OBJ) $(SMBLDAP_OBJ) \ + $(SECRETS_OBJ) $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) -WBINFO_OBJ = nsswitch/wbinfo.o libsmb/smbencrypt.o libsmb/smbdes.o $(POPT_LIB_OBJ) +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@ @@ -621,7 +613,7 @@ POPT_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \ TDBBACKUP_OBJ = tdb/tdbbackup.o $(TDBBASE_OBJ) -NTLM_AUTH_OBJ = utils/ntlm_auth.o $(LIBNTLMSSP_OBJ) $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ) +NTLM_AUTH_OBJ = utils/ntlm_auth.o $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ) ###################################################################### # now the rules... @@ -663,7 +655,7 @@ wins : SHOWFLAGS nsswitch/libnss_wins.@SHLIBEXT@ modules: SHOWFLAGS proto_exists $(MODULES) -everything: all libsmbclient debug2html smbfilter talloctort torture +everything: all libsmbclient debug2html smbfilter talloctort modules torture .SUFFIXES: .SUFFIXES: .c .o .po .po32 .lo @@ -710,6 +702,14 @@ dynconfig.po: dynconfig.c Makefile @BROKEN_CC@ -mv `echo $@ | sed -e 's%^.*/%%g' -e 's%\.po$$%.o%'` $@ @POBAD_CC@ @mv $*.po.o $@ +smbd/build_options.o: smbd/build_options.c Makefile include/config.h include/build_env.h include/proto.h + @echo Compiling $*.c + @$(CC) $(FLAGS) $(PATH_FLAGS) -c $< -o $@ + +smbd/build_options.c: include/config.h.in script/mkbuildoptions.awk + @echo Generating $@ + @dir=smbd $(MAKEDIR) && $(AWK) -f $(srcdir)/script/mkbuildoptions.awk > $(builddir)/smbd/build_options.c < $(srcdir)/include/config.h.in + .c.po: @if (: >> $@ || : > $@) >/dev/null 2>&1; then rm -f $@; else \ dir=`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` $(MAKEDIR); fi @@ -736,7 +736,7 @@ bin/.dummy: bin/smbd@EXEEXT@: $(SMBD_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(SMBD_OBJ) $(ADSLIBS) $(LDFLAGS) $(DYNEXP) $(PRINTLIBS) \ - $(AUTHLIBS) $(ACLLIBS) $(PASSDBLIBS) $(LIBS) @POPTLIBS@ + $(AUTHLIBS) $(ACLLIBS) $(PASSDBLIBS) $(IDMAP_LIBS) $(LIBS) @POPTLIBS@ bin/nmbd@EXEEXT@: $(NMBD_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ @@ -749,11 +749,11 @@ 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) $(IDMAP_LIBS) @POPTLIBS@ $(KRB5LIBS) 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) $(IDMAP_LIBS) $(RPCCLIENT_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ $(ADSLIBS) bin/smbclient@EXEEXT@: $(CLIENT_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ @@ -761,7 +761,7 @@ bin/smbclient@EXEEXT@: $(CLIENT_OBJ) @BUILD_POPT@ bin/.dummy bin/net@EXEEXT@: $(NET_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(NET_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(ADSLIBS) + @$(CC) $(FLAGS) -o $@ $(NET_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(ADSLIBS) $(PASSDBLIBS) bin/profiles@EXEEXT@: $(PROFILES_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ @@ -809,19 +809,15 @@ 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) $(IDMAP_LIBS) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) bin/pdbedit@EXEEXT@: $(PDBEDIT_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(PASSDBLIBS) $(PDBEDIT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ + @$(CC) $(FLAGS) -o $@ $(PASSDBLIBS) $(IDMAP_LIBS) $(PDBEDIT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ bin/samtest@EXEEXT@: $(SAMTEST_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SAMTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDBLIBS) $(ADSLIBS) - -bin/smbgroupedit@EXEEXT@: $(SMBGROUPEDIT_OBJ) bin/.dummy - @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SMBGROUPEDIT_OBJ) $(PASSDBLIBS) $(LDFLAGS) $(DYNEXP) $(LIBS) + @$(CC) $(FLAGS) -o $@ $(SAMTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDBLIBS) $(IDMAP_LIBS) $(ADSLIBS) bin/nmblookup@EXEEXT@: $(NMBLOOKUP_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ @@ -914,7 +910,7 @@ 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) $(ADSLIBS) + @SONAMEFLAG@`basename $@`.$(LIBBIGBALLOFMUD_MAJOR) $(PASSDBLIBS) $(IDMAP_LIBS) $(ADSLIBS) ln -snf libbigballofmud.so bin/libbigballofmud.so.0 # It would be nice to build a static bigballofmud too, but when I try @@ -975,7 +971,7 @@ nsswitch/libnss_wins.@SHLIBEXT@: $(NSS_OBJ) @SONAMEFLAG@`basename $@` bin/winbindd@EXEEXT@: $(WINBINDD_OBJ) @BUILD_POPT@ bin/.dummy - @echo Linking $@ + @echo "Linking $@" @$(LINK) -o $@ $(WINBINDD_OBJ) $(DYNEXP) $(LIBS) @POPTLIBS@ $(ADSLIBS) @LDAP_LIBS@ nsswitch/@WINBIND_NSS@: $(WINBIND_NSS_PICOBJS) @@ -984,7 +980,7 @@ nsswitch/@WINBIND_NSS@: $(WINBIND_NSS_PICOBJS) @WINBIND_NSS_EXTRA_LIBS@ @SONAMEFLAG@`basename $@` nsswitch/pam_winbind.@SHLIBEXT@: $(PAM_WINBIND_OBJ) bin/.dummy - @echo Linking $@ + @echo "Linking $@" @$(SHLD) $(LDSHFLAGS) -o $@ $(PAM_WINBIND_OBJ) \ @SONAMEFLAG@`basename $@` -lpam @@ -1051,6 +1047,11 @@ bin/xml.@SHLIBEXT@: $(XML_OBJ:.o=.po) @$(SHLD) $(LDSHFLAGS) -o $@ $(XML_OBJ:.o=.po) @XML_LIBS@ \ @SONAMEFLAG@`basename $@` +bin/winbind_idmap.@SHLIBEXT@: sam/idmap_winbind.po + @echo "Building plugin $@" + @$(SHLD) $(LDSHFLAGS) -o $@ sam/idmap_winbind.po \ + @SONAMEFLAG@`basename $@` + bin/audit.@SHLIBEXT@: $(VFS_AUDIT_OBJ:.o=.po) @echo "Building plugin $@" @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_AUDIT_OBJ:.o=.po) \ @@ -1076,11 +1077,9 @@ bin/fake_perms.@SHLIBEXT@: $(VFS_FAKE_PERMS_OBJ:.o=.po) @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_FAKE_PERMS_OBJ:.o=.po) \ @SONAMEFLAG@`basename $@` -bin/wbinfo@EXEEXT@: $(WBINFO_OBJ) $(PARAM_OBJ) $(LIB_OBJ) \ - $(UBIQX_OBJ) $(SECRETS_OBJ) @BUILD_POPT@ bin/.dummy +bin/wbinfo@EXEEXT@: $(WBINFO_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(LINK) -o $@ $(WBINFO_OBJ) $(PARAM_OBJ) $(LIB_OBJ) \ - $(UBIQX_OBJ) $(SECRETS_OBJ) $(LIBS) @POPTLIBS@ + @$(LINK) -o $@ $(WBINFO_OBJ) $(LIBS) @POPTLIBS@ bin/ntlm_auth@EXEEXT@: $(NTLM_AUTH_OBJ) $(PARAM_OBJ) $(LIB_OBJ) \ $(UBIQX_OBJ) @BUILD_POPT@ bin/.dummy @@ -1107,14 +1106,14 @@ bin/t_stringoverflow@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_stringove bin/t_doschar@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_doschar.o $(CC) $(FLAGS) -o $@ $(LIBS) torture/t_doschar.o -L ./bin -lbigballofmud - bin/t_push_ucs2@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_push_ucs2.o $(CC) $(FLAGS) -o $@ $(LIBS) torture/t_push_ucs2.o -L ./bin -lbigballofmud bin/t_snprintf@EXEEXT@: lib/snprintf.c $(CC) $(FLAGS) -o $@ -DTEST_SNPRINTF lib/snprintf.c -lm +install: installbin installman installscripts installdat installswat -install: installbin installman installscripts installdat installswat installmodules installclientlib +install-everything: install installmodules # DESTDIR is used here to prevent packagers wasting their time # duplicating the Makefile. Remove it and you will have the privelege @@ -1125,7 +1124,7 @@ install: installbin installman installscripts installdat installswat installmodu # is not used installdirs: - @$(SHELL) $(srcdir)/script/installdirs.sh $(DESTDIR)$(BASEDIR) $(DESTDIR)$(BINDIR) $(DESTDIR)$(SBINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(VARDIR) $(DESTDIR)$(PRIVATEDIR) $(DESTDIR)$(VFSLIBDIR) $(DESTDIR)$(PDBLIBDIR) $(DESTDIR)$(PIDDIR) $(DESTDIR)$(LOCKDIR) + @$(SHELL) $(srcdir)/script/installdirs.sh $(DESTDIR)$(BASEDIR) $(DESTDIR)$(BINDIR) $(DESTDIR)$(SBINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(VARDIR) $(DESTDIR)$(PRIVATEDIR) $(DESTDIR)$(PIDDIR) $(DESTDIR)$(LOCKDIR) installservers: all installdirs @$(SHELL) $(srcdir)/script/installbin.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(SBINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(VARDIR) $(SBIN_PROGS) @@ -1139,6 +1138,7 @@ installmodules: modules installdirs @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(VFSLIBDIR) $(VFS_MODULES) @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(PDBLIBDIR) $(PDB_MODULES) @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(RPCLIBDIR) $(RPC_MODULES) + @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(IDMAPLIBDIR) $(IDMAP_MODULES) @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(CHARSETLIBDIR) $(CHARSET_MODULES) @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(AUTHLIBDIR) $(AUTH_MODULES) @@ -1172,7 +1172,7 @@ python_ext: $(PYTHON_PICOBJS) fi PYTHON_OBJS="$(PYTHON_PICOBJS)" \ PYTHON_CFLAGS="$(CFLAGS) $(CPPFLAGS) $(FLAGS)" \ - LIBS="$(LIBS) $(PASSDBLIBS) $(KRB5LIBS)" \ + LIBS="$(LIBS) $(PASSDBLIBS) $(IDMAP_LIBS) $(KRB5LIBS)" \ $(PYTHON) python/setup.py build python_install: $(PYTHON_PICOBJS) @@ -1238,7 +1238,7 @@ clean: delheaders python_clean # This is quite ugly actually.. But we need to make # sure the changes to include/config.h are used. modules_clean: - @-rm -f @MODULES_CLEAN@ auth/auth.o passdb/pdb_interface.o rpc_server/srv_pipe_hnd.o lib/iconv.o smbd/vfs.o + @-rm -f @MODULES_CLEAN@ auth/auth.o passdb/pdb_interface.o smbd/server.o lib/iconv.o smbd/vfs.o sam/idmap.o # Making this target will just make sure that the prototype files # exist, not necessarily that they are up to date. Since they're @@ -1246,81 +1246,67 @@ modules_clean: # afterwards. proto_exists: include/proto.h include/wrepld_proto.h include/build_env.h \ nsswitch/winbindd_proto.h web/swat_proto.h \ - client/client_proto.h utils/net_proto.h -# include/tdbsam2_parse_info.h + client/client_proto.h utils/net_proto.h smbd/build_options.c delheaders: @echo Removing prototype headers - @/bin/rm -f $(srcdir)/include/proto.h $(srcdir)/include/build_env.h - @/bin/rm -f $(srcdir)/include/wrepld_proto.h $(srcdir)/nsswitch/winbindd_proto.h - @/bin/rm -f $(srcdir)/web/swat_proto.h - @/bin/rm -f $(srcdir)/client/client_proto.h $(srcdir)/utils/net_proto.h - @/bin/rm -f $(srcdir)/include/tdbsam2_parse_info.h - - @/bin/rm -f include/proto.h include/build_env.h include/wrepld_proto.h \ - nsswitch/winbindd_proto.h web/swat_proto.h \ - client/client_proto.h utils/net_proto.h -# include/tdbsam2_parse_info.h - -include/proto.h: + @rm -f include/proto.h include/build_env.h include/wrepld_proto.h \ + nsswitch/winbindd_proto.h web/swat_proto.h \ + client/client_proto.h utils/net_proto.h \ + smbd/build_options.c + +MKPROTO_SH = $(srcdir)/script/mkproto.sh + +include/proto.h: smbd/build_options.c @echo Building include/proto.h - @cd $(srcdir) && $(SHELL) script/mkproto.sh $(AWK) \ + @cd $(srcdir) && $(SHELL) $(MKPROTO_SH) $(AWK) \ -h _PROTO_H_ $(builddir)/include/proto.h \ $(PROTO_OBJ) -include/build_env.h: +include/build_env.h: script/build_env.sh @echo Building include/build_env.h - @cd $(srcdir) && $(SHELL) script/build_env.sh $(srcdir) $(builddir) $(CC) > $(builddir)/include/build_env.h + @$(SHELL) $(srcdir)/script/build_env.sh $(srcdir) $(builddir) $(CC) \ + > $(builddir)/include/build_env.h include/wrepld_proto.h: @echo Building include/wrepld_proto.h - @cd $(srcdir) && $(SHELL) script/mkproto.sh $(AWK) \ + @cd $(srcdir) && $(SHELL) $(MKPROTO_SH) $(AWK) \ -h _WREPLD_PROTO_H_ $(builddir)/include/wrepld_proto.h \ $(WREPL_OBJ1) nsswitch/winbindd_proto.h: - @cd $(srcdir) && $(SHELL) script/mkproto.sh $(AWK) \ - -h _WINBINDD_PROTO_H_ nsswitch/winbindd_proto.h \ + @cd $(srcdir) && $(SHELL) $(MKPROTO_SH) $(AWK) \ + -h _WINBINDD_PROTO_H_ $(builddir)/nsswitch/winbindd_proto.h \ $(WINBINDD_OBJ1) web/swat_proto.h: - @cd $(srcdir) && $(SHELL) script/mkproto.sh $(AWK) \ - -h _SWAT_PROTO_H_ web/swat_proto.h \ + @cd $(srcdir) && $(SHELL) $(MKPROTO_SH) $(AWK) \ + -h _SWAT_PROTO_H_ $(builddir)/web/swat_proto.h \ $(SWAT_OBJ1) client/client_proto.h: - @cd $(srcdir) && $(SHELL) script/mkproto.sh $(AWK) \ - -h _CLIENT_PROTO_H_ client/client_proto.h \ + @cd $(srcdir) && $(SHELL) $(MKPROTO_SH) $(AWK) \ + -h _CLIENT_PROTO_H_ $(builddir)/client/client_proto.h \ $(CLIENT_OBJ1) utils/net_proto.h: - @cd $(srcdir) && $(SHELL) script/mkproto.sh $(AWK) \ - -h _CLIENT_PROTO_H_ utils/net_proto.h \ + @cd $(srcdir) && $(SHELL) $(MKPROTO_SH) $(AWK) \ + -h _CLIENT_PROTO_H_ $(builddir)/utils/net_proto.h \ $(NET_OBJ1) -# not used yet an perl dependent -#include/tdbsam2_parse_info.h: -# @if test -n "$(PERL)"; then \ -# cd $(srcdir) && @PERL@ -w script/genstruct.pl \ -# -o include/tdbsam2_parse_info.h $(CC) -E -O2 -g \ -# include/tdbsam2.h; \ -# else \ -# echo Unable to build $@, continuing; \ -# fi - # "make headers" or "make proto" calls a subshell because we need to # make sure these commands are executed in sequence even for a # parallel make. headers: $(MAKE) delheaders; \ + $(MAKE) smbd/build_options.c; \ $(MAKE) include/proto.h; \ $(MAKE) include/build_env.h; \ $(MAKE) include/wrepld_proto.h; \ $(MAKE) nsswitch/winbindd_proto.h; \ $(MAKE) web/swat_proto.h; \ $(MAKE) client/client_proto.h; \ - $(MAKE) utils/net_proto.h; -# $(MAKE) include/tdbsam2_parse_info.h + $(MAKE) utils/net_proto.h proto: headers diff --git a/source/aclocal.m4 b/source/aclocal.m4 index f470e2e8b0e..dd1ae8df72b 100644 --- a/source/aclocal.m4 +++ b/source/aclocal.m4 @@ -678,3 +678,29 @@ dnl AC_DISABLE_STATIC - set the default static flag to --disable-static AC_DEFUN([AC_DISABLE_STATIC], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl AC_ENABLE_STATIC(no)]) + +dnl AC_TRY_RUN_STRICT(PROGRAM,CFLAGS,CPPFLAGS,LDFLAGS, +dnl [ACTION-IF-TRUE],[ACTION-IF-FALSE], +dnl [ACTION-IF-CROSS-COMPILING = RUNTIME-ERROR]) +AC_DEFUN( [AC_TRY_RUN_STRICT], +[ + old_CFLAGS="$CFLAGS"; + CFLAGS="$2"; + export CFLAGS; + old_CPPFLAGS="$CPPFLAGS"; + CPPFLAGS="$3"; + export CPPFLAGS; + old_LDFLAGS="$LDFLAGS"; + LDFLAGS="$4"; + export LDFLAGS; + AC_TRY_RUN([$1],[$5],[$6],[$7]); + CFLAGS="$old_CFLAGS"; + old_CFLAGS=""; + export CFLAGS; + CPPFLAGS="$old_CPPFLAGS"; + old_CPPFLAGS=""; + export CPPFLAGS; + LDFLAGS="$old_LDFLAGS"; + old_LDFLAGS=""; + export LDFLAGS; +]) diff --git a/source/auth/auth.c b/source/auth/auth.c index 0c4fe768307..02c7eb6d84a 100644 --- a/source/auth/auth.c +++ b/source/auth/auth.c @@ -63,7 +63,7 @@ static struct auth_init_function_entry *auth_find_backend_entry(const char *name struct auth_init_function_entry *entry = backends; while(entry) { - if (strequal(entry->name, name)) return entry; + if (strcmp(entry->name, name)==0) return entry; entry = entry->next; } @@ -262,12 +262,6 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context, break; } - /* This is one of the few places the *relies* (rather than just sets defaults - on the value of lp_security(). This needs to change. A new paramater - perhaps? */ - if (lp_security() >= SEC_SERVER) - smb_user_control(user_info, *server_info, nt_status); - if (NT_STATUS_IS_OK(nt_status)) { pdb_username = pdb_get_username((*server_info)->sam_account); if (!(*server_info)->guest) { diff --git a/source/auth/auth_domain.c b/source/auth/auth_domain.c index bc03fecf749..29916842805 100644 --- a/source/auth/auth_domain.c +++ b/source/auth/auth_domain.c @@ -130,7 +130,6 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli, struct in_addr dest_ip; fstring remote_machine; NTSTATUS result; - uint32 neg_flags = 0x000001ff; *retry = False; @@ -214,7 +213,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli))); return NT_STATUS_NO_MEMORY; } - result = cli_nt_setup_creds(*cli, sec_chan, trust_passwd, &neg_flags, 2); + result = cli_nt_establish_netlogon(*cli, sec_chan, trust_passwd); if (!NT_STATUS_IS_OK(result)) { DEBUG(0,("connect_to_domain_password_server: unable to setup the NETLOGON credentials to machine \ @@ -341,6 +340,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, */ nt_status = cli_netlogon_sam_network_logon(cli, mem_ctx, + NULL, user_info->smb_name.str, user_info->domain.str, user_info->wksta_name.str, chal, user_info->lm_resp, user_info->nt_resp, @@ -458,7 +458,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context, } /* module initialisation */ -NTSTATUS auth_init_ntdomain(struct auth_context *auth_context, const char* param, auth_methods **auth_method) +static NTSTATUS auth_init_ntdomain(struct auth_context *auth_context, const char* param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { return NT_STATUS_NO_MEMORY; @@ -546,7 +546,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte } /* module initialisation */ -NTSTATUS auth_init_trustdomain(struct auth_context *auth_context, const char* param, auth_methods **auth_method) +static NTSTATUS auth_init_trustdomain(struct auth_context *auth_context, const char* param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { return NT_STATUS_NO_MEMORY; diff --git a/source/auth/auth_rhosts.c b/source/auth/auth_rhosts.c index 34110831161..2f0de6b81e5 100644 --- a/source/auth/auth_rhosts.c +++ b/source/auth/auth_rhosts.c @@ -181,7 +181,7 @@ static NTSTATUS check_hostsequiv_security(const struct auth_context *auth_contex } /* module initialisation */ -NTSTATUS auth_init_hostsequiv(struct auth_context *auth_context, const char* param, auth_methods **auth_method) +static NTSTATUS auth_init_hostsequiv(struct auth_context *auth_context, const char* param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { return NT_STATUS_NO_MEMORY; @@ -235,7 +235,7 @@ static NTSTATUS check_rhosts_security(const struct auth_context *auth_context, } /* module initialisation */ -NTSTATUS auth_init_rhosts(struct auth_context *auth_context, const char *param, auth_methods **auth_method) +static NTSTATUS auth_init_rhosts(struct auth_context *auth_context, const char *param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { return NT_STATUS_NO_MEMORY; diff --git a/source/auth/auth_sam.c b/source/auth/auth_sam.c index a7e49a270f0..161376616b1 100644 --- a/source/auth/auth_sam.c +++ b/source/auth/auth_sam.c @@ -28,9 +28,9 @@ /**************************************************************************** core of smb password checking routine. ****************************************************************************/ -static BOOL smb_pwd_check_ntlmv1(DATA_BLOB nt_response, +static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response, const uchar *part_passwd, - DATA_BLOB sec_blob, + const DATA_BLOB *sec_blob, uint8 user_sess_key[16]) { /* Finish the encryption of part_passwd. */ @@ -42,17 +42,17 @@ static BOOL smb_pwd_check_ntlmv1(DATA_BLOB nt_response, return False; } - if (sec_blob.length != 8) { - DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect challenge size (%d)\n", sec_blob.length)); + if (sec_blob->length != 8) { + DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect challenge size (%d)\n", sec_blob->length)); return False; } - if (nt_response.length != 24) { - DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%d)\n", nt_response.length)); + if (nt_response->length != 24) { + DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%d)\n", nt_response->length)); return False; } - SMBOWFencrypt(part_passwd, sec_blob.data, p24); + SMBOWFencrypt(part_passwd, sec_blob->data, p24); if (user_sess_key != NULL) { SMBsesskeygen_ntv1(part_passwd, NULL, user_sess_key); @@ -61,16 +61,16 @@ static BOOL smb_pwd_check_ntlmv1(DATA_BLOB nt_response, #if DEBUG_PASSWORD - DEBUG(100,("Part password (P16) was |")); + DEBUG(100,("Part password (P16) was |\n")); dump_data(100, part_passwd, 16); - DEBUG(100,("Password from client was |")); - dump_data(100, nt_response.data, nt_response.length); - DEBUG(100,("Given challenge was |")); - dump_data(100, sec_blob.data, sec_blob.length); - DEBUG(100,("Value from encryption was |")); + DEBUGADD(100,("Password from client was |\n")); + dump_data(100, nt_response->data, nt_response->length); + DEBUGADD(100,("Given challenge was |\n")); + dump_data(100, sec_blob->data, sec_blob->length); + DEBUGADD(100,("Value from encryption was |\n")); dump_data(100, p24, 24); #endif - return (memcmp(p24, nt_response.data, 24) == 0); + return (memcmp(p24, nt_response->data, 24) == 0); } @@ -79,9 +79,9 @@ core of smb password checking routine. (NTLMv2, LMv2) Note: The same code works with both NTLMv2 and LMv2. ****************************************************************************/ -static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response, +static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response, const uchar *part_passwd, - const DATA_BLOB sec_blob, + const DATA_BLOB *sec_blob, const char *user, const char *domain, uint8 user_sess_key[16]) { @@ -98,42 +98,43 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response, return False; } - if (ntv2_response.length < 16) { + if (ntv2_response->length < 24) { /* We MUST have more than 16 bytes, or the stuff below will go - crazy... */ + 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)); + ntv2_response->length)); return False; } - client_key_data = data_blob(ntv2_response.data+16, ntv2_response.length-16); + client_key_data = data_blob(ntv2_response->data+16, ntv2_response->length-16); /* todo: should we be checking this for anything? We can't for LMv2, but for NTLMv2 it is meant to contain the current time etc. */ - memcpy(client_response, ntv2_response.data, sizeof(client_response)); + memcpy(client_response, ntv2_response->data, sizeof(client_response)); if (!ntv2_owf_gen(part_passwd, user, domain, kr)) { return False; } - SMBOWFencrypt_ntv2(kr, sec_blob, client_key_data, value_from_encryption); + SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption); if (user_sess_key != NULL) { SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key); } #if DEBUG_PASSWORD - DEBUG(100,("Part password (P16) was |")); + DEBUG(100,("Part password (P16) was |\n")); dump_data(100, part_passwd, 16); - DEBUG(100,("Password from client was |")); - dump_data(100, ntv2_response.data, ntv2_response.length); - DEBUG(100,("Variable data from client was |")); + DEBUGADD(100,("Password from client was |\n")); + dump_data(100, ntv2_response->data, ntv2_response->length); + DEBUGADD(100,("Variable data from client was |\n")); dump_data(100, client_key_data.data, client_key_data.length); - DEBUG(100,("Given challenge was |")); - dump_data(100, sec_blob.data, sec_blob.length); - DEBUG(100,("Value from encryption was |")); + DEBUGADD(100,("Given challenge was |\n")); + dump_data(100, sec_blob->data, sec_blob->length); + DEBUGADD(100,("Value from encryption was |\n")); dump_data(100, value_from_encryption, 16); #endif data_blob_clear_free(&client_key_data); @@ -185,8 +186,8 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context, use it (ie. does it exist in the smbpasswd file). */ DEBUG(4,("sam_password_ok: Checking NTLMv2 password with domain [%s]\n", user_info->client_domain.str)); - if (smb_pwd_check_ntlmv2( user_info->nt_resp, - nt_pw, auth_context->challenge, + if (smb_pwd_check_ntlmv2( &user_info->nt_resp, + nt_pw, &auth_context->challenge, user_info->smb_name.str, user_info->client_domain.str, user_sess_key)) @@ -195,11 +196,12 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context, } DEBUG(4,("sam_password_ok: Checking NTLMv2 password without a domain\n")); - if (smb_pwd_check_ntlmv2( user_info->nt_resp, - nt_pw, auth_context->challenge, + if (smb_pwd_check_ntlmv2( &user_info->nt_resp, + nt_pw, &auth_context->challenge, user_info->smb_name.str, "", user_sess_key)) + { return NT_STATUS_OK; } else { @@ -213,8 +215,8 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context, use it (ie. does it exist in the smbpasswd file). */ DEBUG(4,("sam_password_ok: Checking NT MD4 password\n")); - if (smb_pwd_check_ntlmv1(user_info->nt_resp, - nt_pw, auth_context->challenge, + if (smb_pwd_check_ntlmv1(&user_info->nt_resp, + nt_pw, &auth_context->challenge, user_sess_key)) { return NT_STATUS_OK; @@ -224,7 +226,7 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context, } } else { DEBUG(2,("sam_password_ok: NTLMv1 passwords NOT PERMITTED for user %s\n",pdb_get_username(sampass))); - /* no return, because we might pick up LMv2 in the LM field */ + /* no return, becouse we might pick up LMv2 in the LM field */ } } @@ -242,8 +244,8 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context, lm_pw = pdb_get_lanman_passwd(sampass); DEBUG(4,("sam_password_ok: Checking LM password\n")); - if (smb_pwd_check_ntlmv1(user_info->lm_resp, - lm_pw, auth_context->challenge, + if (smb_pwd_check_ntlmv1(&user_info->lm_resp, + lm_pw, &auth_context->challenge, user_sess_key)) { return NT_STATUS_OK; @@ -261,8 +263,8 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context, - related to Win9X, legacy NAS pass-though authentication */ DEBUG(4,("sam_password_ok: Checking LMv2 password with domain %s\n", user_info->client_domain.str)); - if (smb_pwd_check_ntlmv2( user_info->lm_resp, - nt_pw, auth_context->challenge, + if (smb_pwd_check_ntlmv2( &user_info->lm_resp, + nt_pw, &auth_context->challenge, user_info->smb_name.str, user_info->client_domain.str, user_sess_key)) @@ -271,8 +273,8 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context, } DEBUG(4,("sam_password_ok: Checking LMv2 password without a domain\n")); - if (smb_pwd_check_ntlmv2( user_info->lm_resp, - nt_pw, auth_context->challenge, + if (smb_pwd_check_ntlmv2( &user_info->lm_resp, + nt_pw, &auth_context->challenge, user_info->smb_name.str, "", user_sess_key)) @@ -286,8 +288,8 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context, DEBUG(4,("sam_password_ok: Checking NT MD4 password in LM field\n")); if (lp_ntlm_auth()) { - if (smb_pwd_check_ntlmv1(user_info->lm_resp, - nt_pw, auth_context->challenge, + if (smb_pwd_check_ntlmv1(&user_info->lm_resp, + nt_pw, &auth_context->challenge, user_sess_key)) { return NT_STATUS_OK; @@ -438,14 +440,14 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context, return NT_STATUS_NO_SUCH_USER; } - nt_status = sam_account_ok(mem_ctx, sampass, user_info); + nt_status = sam_password_ok(auth_context, mem_ctx, sampass, user_info, user_sess_key); if (!NT_STATUS_IS_OK(nt_status)) { pdb_free_sam(&sampass); return nt_status; } - nt_status = sam_password_ok(auth_context, mem_ctx, sampass, user_info, user_sess_key); + nt_status = sam_account_ok(mem_ctx, sampass, user_info); if (!NT_STATUS_IS_OK(nt_status)) { pdb_free_sam(&sampass); @@ -468,7 +470,7 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context, } /* module initialisation */ -NTSTATUS auth_init_sam(struct auth_context *auth_context, const char *param, auth_methods **auth_method) +static NTSTATUS auth_init_sam(struct auth_context *auth_context, const char *param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { return NT_STATUS_NO_MEMORY; @@ -509,7 +511,7 @@ static NTSTATUS check_samstrict_security(const struct auth_context *auth_context } /* module initialisation */ -NTSTATUS auth_init_samstrict(struct auth_context *auth_context, const char *param, auth_methods **auth_method) +static NTSTATUS auth_init_samstrict(struct auth_context *auth_context, const char *param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { return NT_STATUS_NO_MEMORY; @@ -535,11 +537,11 @@ static NTSTATUS check_samstrict_dc_security(const struct auth_context *auth_cont return NT_STATUS_LOGON_FAILURE; } - /* If we are a domain member, we must not - attempt to check the password locally, + /* If we are a PDC we must not check the password here unless it is one of our aliases, empty - or our domain if we are a logon server.*/ - + or equal to our domain name. Other names may be + Trusted domains. + */ if ((!is_myworkgroup(user_info->domain.str))&& (!is_myname(user_info->domain.str))) { @@ -552,7 +554,7 @@ static NTSTATUS check_samstrict_dc_security(const struct auth_context *auth_cont } /* module initialisation */ -NTSTATUS auth_init_samstrict_dc(struct auth_context *auth_context, const char *param, auth_methods **auth_method) +static NTSTATUS auth_init_samstrict_dc(struct auth_context *auth_context, const char *param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { return NT_STATUS_NO_MEMORY; diff --git a/source/auth/auth_server.c b/source/auth/auth_server.c index 73af290af2a..2a1e4a48d98 100644 --- a/source/auth/auth_server.c +++ b/source/auth/auth_server.c @@ -372,12 +372,19 @@ use this machine as the password server.\n")); cli_ulogoff(cli); - if NT_STATUS_IS_OK(nt_status) { + if (NT_STATUS_IS_OK(nt_status)) { struct passwd *pass = Get_Pwnam(user_info->internal_username.str); if (pass) { nt_status = make_server_info_pw(server_info, pass); } else { - nt_status = NT_STATUS_NO_SUCH_USER; + auth_add_user_script(user_info->domain.str, user_info->internal_username.str); + pass = Get_Pwnam(user_info->internal_username.str); + + if (pass) { + nt_status = make_server_info_pw(server_info, pass); + } else { + nt_status = NT_STATUS_NO_SUCH_USER; + } } } @@ -388,7 +395,7 @@ use this machine as the password server.\n")); return(nt_status); } -NTSTATUS auth_init_smbserver(struct auth_context *auth_context, const char* param, auth_methods **auth_method) +static NTSTATUS auth_init_smbserver(struct auth_context *auth_context, const char* param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { return NT_STATUS_NO_MEMORY; diff --git a/source/auth/auth_unix.c b/source/auth/auth_unix.c index 392178f77c1..b9de6f7acbd 100644 --- a/source/auth/auth_unix.c +++ b/source/auth/auth_unix.c @@ -119,7 +119,7 @@ static NTSTATUS check_unix_security(const struct auth_context *auth_context, } /* module initialisation */ -NTSTATUS auth_init_unix(struct auth_context *auth_context, const char* param, auth_methods **auth_method) +static NTSTATUS auth_init_unix(struct auth_context *auth_context, const char* param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { return NT_STATUS_NO_MEMORY; diff --git a/source/auth/auth_util.c b/source/auth/auth_util.c index e8f2af41f32..d57619942c4 100644 --- a/source/auth/auth_util.c +++ b/source/auth/auth_util.c @@ -36,7 +36,7 @@ extern DOM_SID global_sid_Authenticated_Users; Create a UNIX user on demand. ****************************************************************************/ -static int smb_create_user(const char *unix_user, const char *homedir) +static int smb_create_user(const char *domain, const char *unix_username, const char *homedir) { pstring add_script; int ret; @@ -44,7 +44,9 @@ static int smb_create_user(const char *unix_user, const char *homedir) pstrcpy(add_script, lp_adduser_script()); if (! *add_script) return -1; - all_string_sub(add_script, "%u", unix_user, sizeof(pstring)); + all_string_sub(add_script, "%u", unix_username, sizeof(pstring)); + if (domain) + all_string_sub(add_script, "%D", domain, sizeof(pstring)); if (homedir) all_string_sub(add_script, "%H", homedir, sizeof(pstring)); ret = smbrun(add_script,NULL); @@ -56,24 +58,18 @@ static int smb_create_user(const char *unix_user, const char *homedir) Add and Delete UNIX users on demand, based on NTSTATUS codes. ****************************************************************************/ -void smb_user_control(const auth_usersupplied_info *user_info, auth_serversupplied_info *server_info, NTSTATUS nt_status) +void auth_add_user_script(const char *domain, const char *username) { struct passwd *pwd=NULL; - if (NT_STATUS_IS_OK(nt_status)) { - - if (!(server_info->sam_fill_level & SAM_FILL_UNIX)) { - - /* - * User validated ok against Domain controller. - * If the admin wants us to try and create a UNIX - * user on the fly, do so. - */ - - if(lp_adduser_script() && !(pwd = Get_Pwnam(user_info->internal_username.str))) { - smb_create_user(user_info->internal_username.str, NULL); - } - } + /* + * User validated ok against Domain controller. + * If the admin wants us to try and create a UNIX + * user on the fly, do so. + */ + + if(lp_adduser_script() && !(pwd = Get_Pwnam(username))) { + smb_create_user(domain, username, NULL); } } @@ -914,30 +910,38 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, nt_status = pdb_init_sam_pw(&sam_account, passwd); passwd_free(&passwd); } else { - char *dom_user; - dom_user = talloc_asprintf(mem_ctx, "%s%s%s", - nt_domain, - lp_winbind_separator(), - internal_username); - - if (!dom_user) { - DEBUG(0, ("talloc_asprintf failed!\n")); - return NT_STATUS_NO_MEMORY; - } else { - - if (!(passwd = Get_Pwnam(dom_user)) - /* Only lookup local for the local - domain, we don't want this for - trusted domains */ - && strequal(nt_domain, lp_workgroup())) { - passwd = Get_Pwnam(internal_username); + int try = 0; + while (try < 2) { + char *dom_user; + dom_user = talloc_asprintf(mem_ctx, "%s%s%s", + nt_domain, + lp_winbind_separator(), + internal_username); + + if (!dom_user) { + DEBUG(0, ("talloc_asprintf failed!\n")); + nt_status = NT_STATUS_NO_MEMORY; + } else { + + if (!(passwd = Get_Pwnam(dom_user)) + /* Only lookup local for the local + domain, we don't want this for + trusted domains */ + && strequal(nt_domain, lp_workgroup())) { + passwd = Get_Pwnam(internal_username); + } + + if (!passwd) { + nt_status = NT_STATUS_NO_SUCH_USER; + } else { + nt_status = pdb_init_sam_pw(&sam_account, passwd); + break; + } } - - if (!passwd) { - return NT_STATUS_NO_SUCH_USER; - } else { - nt_status = pdb_init_sam_pw(&sam_account, passwd); + if (try == 0) { + auth_add_user_script(nt_domain, internal_username); } + try++; } } diff --git a/source/auth/auth_winbind.c b/source/auth/auth_winbind.c index b8276b08661..0b19746597d 100644 --- a/source/auth/auth_winbind.c +++ b/source/auth/auth_winbind.c @@ -136,7 +136,7 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context, } /* module initialisation */ -NTSTATUS auth_init_winbind(struct auth_context *auth_context, const char *param, auth_methods **auth_method) +static NTSTATUS auth_init_winbind(struct auth_context *auth_context, const char *param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { return NT_STATUS_NO_MEMORY; diff --git a/source/change-log b/source/change-log index 71f5012484f..1f7798b541f 100644 --- a/source/change-log +++ b/source/change-log @@ -2,7 +2,7 @@ SUPERCEDED Change Log for Samba ^^^^^^^^^^ Unless otherwise attributed, all changes were made by -Andrew.Tridgell@anu.edu.au. +Andrew.Tridgell@anu.edu.au. All bugs to samba-bugs@samba.org. NOTE: THIS LOG IS IN CHRONOLOGICAL ORDER diff --git a/source/client/client.c b/source/client/client.c index 918b435b2d1..69037ca1db8 100644 --- a/source/client/client.c +++ b/source/client/client.c @@ -2328,11 +2328,9 @@ static char **completion_fn(const char *text, int start, int end) if (sp == NULL) return NULL; - for (i = 0; commands[i].description; i++) { + for (i = 0; commands[i].description; i++) if ((strncmp(commands[i].name, text, sp - buf) == 0) && (commands[i].name[sp - buf] == 0)) break; - } - if (commands[i].name == NULL) return NULL; diff --git a/source/client/mount.cifs.c b/source/client/mount.cifs.c index 8ba1eff02e3..6edb06aedfb 100755 --- a/source/client/mount.cifs.c +++ b/source/client/mount.cifs.c @@ -222,6 +222,7 @@ char * parse_server(char * unc_name) printf(" %s does not begin with \\\\ or //\n",unc_name); return 0; } else { + unc_name[0] = '\\'; unc_name[0] = '/'; unc_name[1] = '/'; unc_name += 2; diff --git a/source/config.sub b/source/config.sub index 04baf3d80d1..2476310dff3 100755 --- a/source/config.sub +++ b/source/config.sub @@ -1,9 +1,9 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. -timestamp='2003-01-03' +timestamp='2001-12-03' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software @@ -118,7 +118,7 @@ esac # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in - nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; @@ -227,39 +227,26 @@ case $basic_machine in 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ - | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | fr30 | frv \ + | c4x | clipper \ + | d10v | d30v | dsp16xx \ + | fr30 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ - | ip2k \ | m32r | m68000 | m68k | m88k | mcore \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64vr | mips64vrel \ - | mips64orion | mips64orionel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipstx39 | mipstx39el \ + | mips16 | mips64 | mips64el | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el | mips64vr4300 \ + | mips64vr4300el | mips64vr5000 | mips64vr5000el \ + | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \ + | mipsisa32 \ | mn10200 | mn10300 \ - | msp430 \ | ns16k | ns32k \ - | openrisc | or32 \ + | openrisc \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ - | sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ + | sh | sh[34] | sh[34]eb | shbe | shle \ + | sparc | sparc64 | sparclet | sparclite | sparcv9 | sparcv9b \ | strongarm \ | tahoe | thumb | tic80 | tron \ | v850 | v850e \ @@ -291,52 +278,38 @@ case $basic_machine in 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | alphapca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armv*-* \ | avr-* \ | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* \ - | clipper-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ + | c[123]* | c30-* | [cjt]90-* | c54x-* \ + | clipper-* | cray2-* | cydra-* \ + | d10v-* | d30v-* \ | elxsi-* \ - | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | f30[01]-* | f700-* | fr30-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* \ | m32r-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m68000-* | m680[01234]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | mcore-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipstx39-* | mipstx39el-* \ - | msp430-* \ - | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \ + | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \ + | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \ + | mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ - | sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ - | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* | tic30-* | tic4x-* | tic54x-* | tic80-* | tron-* \ + | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclite-* \ + | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* \ + | t3e-* | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ - | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | x86-* | x86_64-* | xmp-* | xps100-* | xscale-* | xstormy16-* \ | xtensa-* \ | ymp-* \ | z8k-*) @@ -402,10 +375,6 @@ case $basic_machine in basic_machine=ns32k-sequent os=-dynix ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; convex-c1) basic_machine=c1-convex os=-bsd @@ -426,8 +395,16 @@ case $basic_machine in basic_machine=c38-convex os=-bsd ;; - cray | j90) - basic_machine=j90-cray + cray | ymp) + basic_machine=ymp-cray + os=-unicos + ;; + cray2) + basic_machine=cray2-cray + os=-unicos + ;; + [cjt]90) + basic_machine=${basic_machine}-cray os=-unicos ;; crds | unos) @@ -442,14 +419,6 @@ case $basic_machine in decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola @@ -630,6 +599,14 @@ case $basic_machine in basic_machine=m68k-atari os=-mint ;; + mipsel*-linux*) + basic_machine=mipsel-unknown + os=-linux-gnu + ;; + mips*-linux*) + basic_machine=mips-unknown + os=-linux-gnu + ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; @@ -644,10 +621,6 @@ case $basic_machine in basic_machine=m68k-rom68k os=-coff ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; msdos) basic_machine=i386-pc os=-msdos @@ -720,10 +693,6 @@ case $basic_machine in np1) basic_machine=np1-gould ;; - nv1) - basic_machine=nv1-cray - os=-unicosmp - ;; nsr-tandem) basic_machine=nsr-tandem ;; @@ -731,10 +700,6 @@ case $basic_machine in basic_machine=hppa1.1-oki os=-proelf ;; - or32 | or32-*) - basic_machine=or32-unknown - os=-coff - ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose @@ -757,13 +722,13 @@ case $basic_machine in pbb) basic_machine=m68k-tti ;; - pc532 | pc532-*) + pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) + pentiumpro | p6 | 6x86 | athlon) basic_machine=i686-pc ;; pentiumii | pentium2) @@ -784,22 +749,22 @@ case $basic_machine in power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown - ;; + ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown - ;; + ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown - ;; + ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown - ;; + ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; @@ -830,12 +795,6 @@ case $basic_machine in basic_machine=a29k-amd os=-udi ;; - sb1) - basic_machine=mipsisa64sb1-unknown - ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown - ;; sequent) basic_machine=i386-sequent ;; @@ -910,17 +869,9 @@ case $basic_machine in os=-dynix ;; t3e) - basic_machine=alphaev5-cray + basic_machine=t3e-cray os=-unicos ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tic4x | c4x*) - basic_machine=tic4x-unknown - os=-coff - ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff @@ -931,10 +882,6 @@ case $basic_machine in tx39el) basic_machine=mipstx39el-unknown ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; tower | tower-32) basic_machine=m68k-ncr ;; @@ -959,8 +906,8 @@ case $basic_machine in os=-vms ;; vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; + basic_machine=f301-fujitsu + ;; vxworks960) basic_machine=i960-wrs os=-vxworks @@ -981,13 +928,17 @@ case $basic_machine in basic_machine=hppa1.1-winbond os=-proelf ;; - xps | xps100) - basic_machine=xps100-honeywell + windows32) + basic_machine=i386-pc + os=-windows32-msvcrt ;; - ymp) - basic_machine=ymp-cray + xmp) + basic_machine=xmp-cray os=-unicos ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim @@ -1008,6 +959,13 @@ case $basic_machine in op60c) basic_machine=hppa1.1-oki ;; + mips) + if [ x$os = x-linux-gnu ]; then + basic_machine=mips-unknown + else + basic_machine=mips-mips + fi + ;; romp) basic_machine=romp-ibm ;; @@ -1027,16 +985,13 @@ case $basic_machine in we32k) basic_machine=we32k-att ;; - sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele) + sh3 | sh4 | sh3eb | sh4eb) basic_machine=sh-unknown ;; - sh64) - basic_machine=sh64-unknown - ;; sparc | sparcv9 | sparcv9b) basic_machine=sparc-sun ;; - cydra) + cydra) basic_machine=cydra-cydrome ;; orion) @@ -1051,6 +1006,10 @@ case $basic_machine in pmac | pmac-mpw) basic_machine=powerpc-apple ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; @@ -1113,12 +1072,10 @@ case $os in | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -microbsd*) + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1130,10 +1087,8 @@ case $os in ;; esac ;; - -nto-qnx*) - ;; -nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` + os=-nto-qnx ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ @@ -1181,11 +1136,8 @@ case $os in -ctix* | -uts*) os=-sysv ;; - -nova*) - os=-rtmk-nova - ;; -ns2 ) - os=-nextstep2 + os=-nextstep2 ;; -nsk*) os=-nsk @@ -1224,8 +1176,8 @@ case $os in -xenix) os=-xenix ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint ;; -none) ;; @@ -1258,11 +1210,10 @@ case $basic_machine in arm*-semi) os=-aout ;; - # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; - pdp11-*) + pdp11-*) os=-none ;; *-dec | vax-*) @@ -1289,9 +1240,6 @@ case $basic_machine in mips*-*) os=-elf ;; - or32-*) - os=-coff - ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; @@ -1355,19 +1303,19 @@ case $basic_machine in *-next) os=-nextstep3 ;; - *-gould) + *-gould) os=-sysv ;; - *-highlevel) + *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; - *-sgi) + *-sgi) os=-irix ;; - *-siemens) + *-siemens) os=-sysv4 ;; *-masscomp) @@ -1439,7 +1387,7 @@ case $basic_machine in -ptx*) vendor=sequent ;; - -vxsim* | -vxworks* | -windiss*) + -vxsim* | -vxworks*) vendor=wrs ;; -aux*) diff --git a/source/configure.in b/source/configure.in index 93cbb0a871b..64051381856 100644 --- a/source/configure.in +++ b/source/configure.in @@ -154,6 +154,7 @@ 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) @@ -171,11 +172,13 @@ AC_ARG_ENABLE(debug, AC_ARG_ENABLE(developer, [ --enable-developer Turn on developer warnings and debugging (default=no)], [if eval "test x$enable_developer = xyes"; then - CFLAGS="${CFLAGS} -g -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER" + developer=yes + CFLAGS="${CFLAGS} -g -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER" fi]) AC_ARG_ENABLE(krb5developer, [ --enable-krb5developer Turn on developer warnings and debugging, except -Wstrict-prototypes (default=no)], [if eval "test x$enable_krb5developer = xyes"; then + developer=yes CFLAGS="${CFLAGS} -g -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER" fi]) @@ -221,6 +224,30 @@ else fi AC_SUBST(BROKEN_CC) +dnl Check if the C compiler understands -Werror +AC_CACHE_CHECK([that the C compiler understands -Werror],samba_cv_HAVE_Werror, [ + AC_TRY_RUN_STRICT([ + int main(void) + { + return 0; + }],[-Werror],[$CPPFLAGS],[$LDFLAGS], + samba_cv_HAVE_Werror=yes,samba_cv_HAVE_Werror=no,samba_cv_HAVE_Werror=cross)]) +if test x"$samba_cv_HAVE_Werror" = x"yes"; then + Werror_FLAGS="-Werror" +else +dnl Check if the C compiler understands -w2 +AC_CACHE_CHECK([that the C compiler understands -w2],samba_cv_HAVE_w2, [ + AC_TRY_RUN_STRICT([ + int main(void) + { + return 0; + }],[-w2],[$CPPFLAGS],[$LDFLAGS], + samba_cv_HAVE_w2=yes,samba_cv_HAVE_w2=no,samba_cv_HAVE_w2=cross)]) +if test x"$samba_cv_HAVE_w2" = x"yes"; then + Werror_FLAGS="-w2" +fi +fi + dnl Check if the C compiler understands volatile (it should, being ANSI). AC_CACHE_CHECK([that the C compiler understands volatile],samba_cv_volatile, [ AC_TRY_COMPILE([#include <sys/types.h>],[volatile int i = 0], @@ -229,6 +256,21 @@ if test x"$samba_cv_volatile" = x"yes"; then AC_DEFINE(HAVE_VOLATILE, 1, [Whether the C compiler understands volatile]) fi +UNAME_S=`uname -s` +AC_MSG_CHECKING(uname -s) +AC_MSG_RESULT(${UNAME_S}) + +UNAME_R=`uname -r` +AC_MSG_CHECKING(uname -r) +AC_MSG_RESULT(${UNAME_R}) + +UNAME_M=`uname -m` +AC_MSG_CHECKING(uname -m) +AC_MSG_RESULT(${UNAME_M}) + +UNAME_P=`uname -p` +AC_MSG_CHECKING(uname -p) +AC_MSG_RESULT(${UNAME_P}) AC_CANONICAL_SYSTEM @@ -247,9 +289,9 @@ 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 idmap_winbind" dnl These are preferably build shared, and static if dlopen() is not available -default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_fake_perms vfs_netatalk" +default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms" -if test "x$enable_developer" = xyes; then +if test "x$developer" = xyes; then default_static_modules="$default_static_modules rpc_echo" default_shared_modules="$default_shared_modules charset_weird" fi @@ -509,18 +551,11 @@ 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 sys/cdefs.h glob.h) +AC_CHECK_HEADERS(sys/acl.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) -# For quotas on Veritas VxFS filesystems -AC_CHECK_HEADERS(sys/fs/vx_quota.h) - -# For quotas on Linux XFS filesystems -AC_CHECK_HEADERS(linux/xqm.h) -AC_CHECK_HEADERS(xfs/xqm.h) - AC_CHECK_SIZEOF(int,cross) AC_CHECK_SIZEOF(long,cross) AC_CHECK_SIZEOF(short,cross) @@ -903,6 +938,13 @@ AC_LIBTESTFUNC(sec, bigcrypt) AC_LIBTESTFUNC(security, getprpwnam) AC_LIBTESTFUNC(sec, getprpwnam) +############################################ +# Check if we have libattr +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) + # Assume non-shared by default and override below BLDSHARED="false" @@ -2173,6 +2215,7 @@ fi AC_CHECK_LIB(crypto, des_set_key, [LIBS="$LIBS -lcrypto"]) AC_CHECK_LIB(asn1, copy_Authenticator, [LIBS="$LIBS -lasn1"]) AC_CHECK_LIB(roken, roken_getaddrinfo_hostspec, [LIBS="$LIBS -lroken"]) + AC_CHECK_LIB(resolv, dn_expand, [LIBS="$LIBS -lresolv"]) # 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])]) @@ -2266,8 +2309,8 @@ AC_ARG_WITH(ldap, AC_MSG_RESULT($with_ldap_support) if test x"$with_ldap_support" = x"yes"; then -ac_save_LIBS="$LIBS" -LIBS="" + ac_save_LIBS="$LIBS" + LIBS="" ################################################################## # we might need the lber lib on some systems. To avoid link errors @@ -2277,10 +2320,17 @@ LIBS="" ######################################################## # now see if we can find the ldap libs in standard paths if test x$have_ldap != xyes; then - AC_CHECK_LIB(ldap, ldap_domain2hostlist, [LIBS="$LIBS -lldap"; - LDAP_OBJ=lib/ldap.o; - AC_DEFINE(HAVE_LDAP,1,[Whether ldap is available])]) - AC_CHECK_HEADERS([ldap.h lber.h], [default_static_modules="$default_static_modules pdb_ldap"]) + 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"]) + ]) + ]) + + ## we have ldap so build the list of files for the generic samba ldap library + SMBLDAP="lib/smbldap.o" ######################################################## # If we have LDAP, does it's rebind procedure take 2 or 3 arguments? @@ -2291,10 +2341,12 @@ LIBS="" #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 -LDAP_LIBS="$LIBS"; -LIBS="$ac_save_LIBS"; + AC_SUBST(SMBLDAP) + LDAP_LIBS="$LIBS"; + LIBS="$ac_save_LIBS"; else # Can't have ADS support without LDAP if test x"$with_ads_support" = x"yes"; then @@ -2485,27 +2537,6 @@ AC_ARG_WITH(ldapsam, AC_MSG_RESULT(no) ) -################################################# -# check for IDMAP - -AC_DEFINE(WITH_IDMAP,1, [Include IDMAP support]) - -AC_MSG_CHECKING(whether to use IDMAP only for [ug]id mapping) -AC_ARG_WITH(idmap, -[ --with-idmap Include experimental IDMAP support (default=yes)], -[ case "$withval" in - yes) - AC_MSG_RESULT(yes) - AC_DEFINE(WITH_IDMAP,1,[Whether to include experimental IDMAP support]) - ;; - no) - AC_MSG_RESULT(no) - AC_DEFINE(WITH_IDMAP,0,[Whether to include experimental IDMAP support]) - ;; - esac ], - AC_MSG_RESULT(yes) -) - ######################################################################################## ## ## END OF TESTS FOR SAM BACKENDS. @@ -2566,44 +2597,283 @@ AC_ARG_WITH(profiling-data, ################################################# # check for experimental disk-quotas support -QUOTAOBJS=smbd/noquotas.o -AC_MSG_CHECKING(whether to support disk-quotas) +samba_cv_WITH_QUOTAS=auto +samba_cv_TRY_QUOTAS=no +samba_cv_RUN_QUOTA_TESTS=auto +samba_cv_WITH_SYS_QUOTAS=auto +samba_cv_TRY_SYS_QUOTAS=no + +AC_MSG_CHECKING(whether to try disk-quotas support) AC_ARG_WITH(quotas, -[ --with-quotas Include experimental disk-quota support (default=no)], +[ --with-quotas Include disk-quota support (default=no)], [ case "$withval" in yes) AC_MSG_RESULT(yes) - case "$host_os" in - *linux*) - # Check for kernel 2.4.x quota braindamage... - AC_CACHE_CHECK([for linux 2.4.x quota braindamage..],samba_cv_linux_2_4_quota_braindamage, [ - AC_TRY_COMPILE([#include <stdio.h> -#include <sys/types.h> -#include <asm/types.h> -#include <linux/quota.h> -#include <mntent.h> -#include <linux/unistd.h>],[struct mem_dqblk D;], - samba_cv_linux_2_4_quota_braindamage=yes,samba_cv_linux_2_4_quota_braindamage=no)]) -if test x"$samba_cv_linux_2_4_quota_braindamage" = x"yes"; then - AC_DEFINE(LINUX_QUOTAS_2,1,[linux 2.4.x quota braindamage]) -else - AC_DEFINE(LINUX_QUOTAS_1,1,[linux quotas]) -fi - ;; - *) - ;; - esac - QUOTAOBJS=smbd/quotas.o - AC_DEFINE(WITH_QUOTAS,1,[Whether to include experimental quota support]) + samba_cv_WITH_QUOTAS=yes + samba_cv_TRY_QUOTAS=yes + samba_cv_RUN_QUOTA_TESTS=yes + #set sys quotas to auto in this case + samba_cv_TRY_SYS_QUOTAS=auto + ;; + auto) + AC_MSG_RESULT(auto) + samba_cv_WITH_QUOTAS=auto + samba_cv_TRY_QUOTAS=auto + samba_cv_RUN_QUOTA_TESTS=auto + #set sys quotas to auto in this case + samba_cv_TRY_SYS_QUOTAS=auto + ;; + no) + AC_MSG_RESULT(no) + samba_cv_WITH_QUOTAS=no + samba_cv_TRY_QUOTAS=no + samba_cv_RUN_QUOTA_TESTS=no ;; *) + AC_MSG_RESULT(${samba_cv_TRY_QUOTAS}) + ;; + esac ], + AC_MSG_RESULT(${samba_cv_TRY_QUOTAS}) +) + +AC_MSG_CHECKING(whether to try the new lib/sysquotas.c interface) +AC_ARG_WITH(sys-quotas, +[ --with-sys-quotas Include lib/sysquotas.c support (default=auto)], +[ case "$withval" in + yes) + AC_MSG_RESULT(yes) + samba_cv_WITH_SYS_QUOTAS=yes + samba_cv_TRY_SYS_QUOTAS=yes + samba_cv_RUN_QUOTA_TESTS=yes + ;; + auto) + AC_MSG_RESULT(auto) + samba_cv_WITH_SYS_QUOTAS=auto + samba_cv_TRY_SYS_QUOTAS=auto + samba_cv_RUN_QUOTA_TESTS=auto + ;; + no) AC_MSG_RESULT(no) + samba_cv_WITH_SYS_QUOTAS=no + samba_cv_TRY_SYS_QUOTAS=no + ;; + *) + AC_MSG_RESULT(${samba_cv_TRY_SYS_QUOTAS}) ;; esac ], - AC_MSG_RESULT(no) + AC_MSG_RESULT(${samba_cv_TRY_SYS_QUOTAS}) ) -AC_SUBST(QUOTAOBJS) + +if test x"$samba_cv_TRY_SYS_QUOTAS" = x"auto"; then +AC_MSG_CHECKING(whether to try the lib/sysquotas.c interface on ${host_os}) + case "$host_os" in + *linux*) + AC_MSG_RESULT(yes) + samba_cv_TRY_SYS_QUOTAS=yes + samba_cv_RUN_QUOTA_TESTS=yes + ;; + *) + AC_MSG_RESULT(no) + samba_cv_TRY_SYS_QUOTAS=no + ;; + esac +fi + +############################################# +# only check for quota stuff if --with-quotas +if test x"$samba_cv_RUN_QUOTA_TESTS" != x"no"; then + +# For quotas on Veritas VxFS filesystems +AC_CHECK_HEADERS(sys/fs/vx_quota.h) + +# For sys/quota.h and linux/quota.h +AC_CHECK_HEADERS(sys/quota.h) +AC_CHECK_HEADERS(asm/types.h linux/quota.h) + +# For quotas on Linux XFS filesystems +AC_CHECK_HEADERS(linux/xqm.h linux/xfs_fs.h) +AC_CHECK_HEADERS(xfs/libxfs.h xfs/xqm.h xfs/xfs_fs.h) +# For linux > 2.5.56 +AC_CHECK_HEADERS(linux/dqblk_xfs.h) + +# if we have struct if_dqblk in <linux/quota.h> we should use it +AC_CACHE_CHECK([for struct if_dqblk in <linux/quota.h>],samba_cv_HAVE_STRUCT_IF_DQBLK, [ +AC_TRY_COMPILE([ +#include "confdefs.h" +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#ifdef HAVE_ASM_TYPES_H +#include <asm/types.h> +#endif +#include <linux/quota.h> +],[struct if_dqblk D;], +samba_cv_HAVE_STRUCT_IF_DQBLK=yes,samba_cv_HAVE_STRUCT_IF_DQBLK=no)]) +if test "$samba_cv_HAVE_STRUCT_IF_DQBLK"x = "yes"x; then + AC_DEFINE(HAVE_STRUCT_IF_DQBLK,1,[struct if_dqblk]) +fi + +# if we have struct mem_dqblk in <linux/quota.h> we should use it +AC_CACHE_CHECK([for struct mem_dqblk in <linux/quota.h>],samba_cv_HAVE_STRUCT_MEM_DQBLK, [ +AC_TRY_COMPILE([ +#include "confdefs.h" +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#ifdef HAVE_ASM_TYPES_H +#include <asm/types.h> +#endif +#include <linux/quota.h> +],[struct mem_dqblk D;], +samba_cv_HAVE_STRUCT_MEM_DQBLK=yes,samba_cv_HAVE_STRUCT_MEM_DQBLK=no)]) +if test "$samba_cv_HAVE_STRUCT_MEM_DQBLK"x = "yes"x; then + AC_DEFINE(HAVE_STRUCT_MEM_DQBLK,1,[struct mem_dqblk]) +fi + +# if we have struct dqblk .dqb_fsoftlimit instead of .dqb_isoftlimit on IRIX +AC_CACHE_CHECK([if struct dqblk has .dqb_fsoftlimit],samba_cv_HAVE_DQB_FSOFTLIMIT, [ +AC_TRY_COMPILE([ +#include "confdefs.h" +#ifdef HAVE_SYS_QUOTA_H +#include <sys/quota.h> +#endif +],[ +struct dqblk D; +D.dqb_fsoftlimit = 0;], +samba_cv_HAVE_DQB_FSOFTLIMIT=yes,samba_cv_HAVE_DQB_FSOFTLIMIT=no)]) +if test "$samba_cv_HAVE_DQB_FSOFTLIMIT"x = "yes"x; then + AC_DEFINE(HAVE_DQB_FSOFTLIMIT,1,[struct dqblk .dqb_fsoftlimit]) +fi + +################## +# look for a working quota system +samba_cv_SYSQUOTA_FOUND=no; + +if test x"$samba_cv_SYSQUOTA_FOUND" != x"yes"; then +AC_CACHE_CHECK([for long quotactl(int cmd, char *special, qid_t id, caddr_t addr)],samba_cv_HAVE_QUOTACTL_4A,[ +AC_TRY_RUN_STRICT([ +#define HAVE_QUOTACTL_4A 1 +#define AUTOCONF_TEST 1 +#include "confdefs.h" +#include "${srcdir-.}/lib/sysquotas.c"],[$Werror_FLAGS],[$CPPFLAGS],[$LDFLAGS], + samba_cv_HAVE_QUOTACTL_4A=yes,samba_cv_HAVE_QUOTACTL_4A=no,samba_cv_HAVE_QUOTACTL_4A=cross)]) +if test x"$samba_cv_HAVE_QUOTACTL_4A" = x"yes"; then + samba_cv_SYSQUOTA_FOUND=yes;AC_DEFINE(HAVE_QUOTACTL_4A,1,[Whether long quotactl(int cmd, char *special, qid_t id, caddr_t addr) is available]) +fi +fi + +if test x"$samba_cv_SYSQUOTA_FOUND" != x"yes"; then +AC_CACHE_CHECK([for int quotactl(const char *path, int cmd, int id, char *addr)],samba_cv_HAVE_QUOTACTL_4B,[ +AC_TRY_RUN_STRICT([ +#define HAVE_QUOTACTL_4B 1 +#define AUTOCONF_TEST 1 +#include "confdefs.h" +#include "${srcdir-.}/lib/sysquotas.c"],[$Werror_FLAGS],[$CPPFLAGS],[$LDFLAGS], + samba_cv_HAVE_QUOTACTL_4B=yes,samba_cv_HAVE_QUOTACTL_4B=no,samba_cv_HAVE_QUOTACTL_4B=cross)]) +if test x"$samba_cv_HAVE_QUOTACTL_4B" = x"yes"; then + echo "int quotactl(const char *path, int cmd, int id, char *addr) is not reworked for the new sys_quota api" +# samba_cv_SYSQUOTA_FOUND=yes;AC_DEFINE(HAVE_QUOTACTL_4B,1,[Whether int quotactl(const char *path, int cmd, int id, char *addr) is available]) +fi +fi + +if test x"$samba_cv_SYSQUOTA_FOUND" != x"yes"; then +AC_CACHE_CHECK([for CRAY int quotactl (char *spec, int request, char *arg)],samba_cv_HAVE_QUOTACTL_3,[ +AC_TRY_RUN_STRICT([ +#define HAVE_QUOTACTL_3 1 +#define AUTOCONF_TEST 1 +#include "confdefs.h" +#include "${srcdir-.}/lib/sysquotas.c"],[$Werror_FLAGS],[$CPPFLAGS],[$LDFLAGS], + samba_cv_HAVE_QUOTACTL_3=yes,samba_cv_HAVE_QUOTACTL_3=no,samba_cv_HAVE_QUOTACTL_3=cross)]) +if test x"$samba_cv_HAVE_QUOTACTL_3" = x"yes"; then + echo "CRAY int quotactl (char *spec, int request, char *arg) is NOT reworked for the sys_quota api" +# samba_cv_SYSQUOTA_FOUND=yes;AC_DEFINE(HAVE_QUOTACTL_3,1,[Whether CRAY int quotactl (char *spec, int request, char *arg); is available]) +fi +fi + +################################################# +# check for mntent.h and struct mntent +AC_CHECK_HEADERS(mntent.h) +################################################# +# check for setmntent,getmntent,endmntent +AC_CHECK_FUNCS(setmntent getmntent endmntent) + +################################################# +# check for devnm.h and struct mntent +AC_CHECK_HEADERS(devnm.h) +################################################# +# check for devnm +AC_CHECK_FUNCS(devnm) + +if test x"$samba_cv_WITH_SYS_QUOTAS" = x"yes"; then + if test x"$samba_cv_SYSQUOTA_FOUND" != x"yes"; then + # if --with-sys-quotas=yes then build it + # you have can use the get/set quota command smb.conf + # options then + samba_cv_SYSQUOTA_FOUND=auto + fi + if test x"$samba_cv_TRY_SYS_QUOTAS" != x"yes"; then + # if --with-sys-quotas=yes then build it + # you have can use the get/set quota command smb.conf + # options then + samba_cv_TRY_SYS_QUOTAS=auto + fi +fi + +if test x"$samba_cv_SYSQUOTA_FOUND" != x"no"; then +AC_CACHE_CHECK([whether the sys_quota interface works],samba_cv_SYSQUOTA_WORKS,[ +SAVE_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I. -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/popt -I${srcdir-.}/smbwrapper -I${srcdir-.}/nsswitch" +AC_TRY_COMPILE([ +#include "confdefs.h" +#define NO_PROTO_H 1 +#define NO_CONFIG_H 1 +#define HAVE_SYS_QUOTAS 1 +#include "${srcdir-.}/lib/sysquotas.c" +],[],samba_cv_SYSQUOTA_WORKS=yes,samba_cv_SYSQUOTA_WORKS=no) +CPPFLAGS="$SAVE_CPPFLAGS" +]) +if test x"$samba_cv_SYSQUOTA_WORKS" = x"yes"; then +AC_MSG_CHECKING(whether to use the new lib/sysquotas.c interface) + if test x"$samba_cv_TRY_SYS_QUOTAS" != x"no"; then + AC_DEFINE(WITH_QUOTAS,1,[Whether to use disk quota support]) + AC_DEFINE(HAVE_SYS_QUOTAS,1,[Whether the new lib/sysquotas.c interface can be used]) + samba_cv_WE_USE_SYS_QUOTAS=yes + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi +fi +fi + +AC_CACHE_CHECK([whether the old quota support works],samba_cv_QUOTA_WORKS,[ +SAVE_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I. -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/popt -I${srcdir-.}/smbwrapper -I${srcdir-.}/nsswitch" +AC_TRY_COMPILE([ +#include "confdefs.h" +#define NO_PROTO_H 1 +#define NO_CONFIG_H 1 +#include "${srcdir-.}/smbd/quotas.c" +],[],samba_cv_QUOTA_WORKS=yes,samba_cv_QUOTA_WORKS=no) +CPPFLAGS="$SAVE_CPPFLAGS" +]) +if test x"$samba_cv_QUOTA_WORKS" = x"yes"; then +AC_MSG_CHECKING(whether to use the old quota support) + if test x"$samba_cv_WE_USE_SYS_QUOTAS" != x"yes"; then + if test x"$samba_cv_TRY_QUOTAS" != x"no"; then + AC_DEFINE(WITH_QUOTAS,1,[Whether to use disk quota support]) + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + else + AC_MSG_RESULT(no) + fi +fi + +#################### +# End of quota check samba_cv_RUN_QUOTA_TESTS +fi ################################################# # check for experimental utmp accounting @@ -2966,7 +3236,34 @@ AC_ARG_WITH(acl-support, AC_DEFINE(HAVE_POSIX_ACLS,1,[Whether FreeBSD POSIX ACLs are available]) AC_DEFINE(HAVE_ACL_GET_PERM_NP,1,[Whether acl_get_perm_np() is available]) ;; - *) + *linux*) + AC_CHECK_LIB(attr,getxattr,[ACLLIBS="$ACLLIBS -lattr"]) + AC_CHECK_LIB(acl,acl_get_file,[ACLLIBS="$ACLLIBS -lacl"]) + AC_CACHE_CHECK([for ACL support],samba_cv_HAVE_POSIX_ACLS,[ + acl_LIBS=$LIBS + LIBS="$LIBS -lacl" + AC_TRY_LINK([#include <sys/types.h> +#include <sys/acl.h>], +[ acl_t acl; int entry_id; acl_entry_t *entry_p; return acl_get_entry( acl, entry_id, entry_p);], +samba_cv_HAVE_POSIX_ACLS=yes,samba_cv_HAVE_POSIX_ACLS=no) + LIBS=$acl_LIBS]) + if test x"$samba_cv_HAVE_POSIX_ACLS" = x"yes"; then + AC_MSG_RESULT(Using posix ACLs) + AC_DEFINE(HAVE_POSIX_ACLS,1,[Whether POSIX ACLs are available]) + AC_CACHE_CHECK([for acl_get_perm_np],samba_cv_HAVE_ACL_GET_PERM_NP,[ + acl_LIBS=$LIBS + LIBS="$LIBS -lacl" + AC_TRY_LINK([#include <sys/types.h> +#include <sys/acl.h>], +[ acl_permset_t permset_d; acl_perm_t perm; return acl_get_perm_np( permset_d, perm);], +samba_cv_HAVE_ACL_GET_PERM_NP=yes,samba_cv_HAVE_ACL_GET_PERM_NP=no) + LIBS=$acl_LIBS]) + if test x"$samba_cv_HAVE_ACL_GET_PERM_NP" = x"yes"; then + AC_DEFINE(HAVE_ACL_GET_PERM_NP,1,[Whether acl_get_perm_np() is available]) + fi + fi + ;; + *) AC_CHECK_LIB(acl,acl_get_file,[ACLLIBS="$ACLLIBS -lacl"]) AC_CACHE_CHECK([for ACL support],samba_cv_HAVE_POSIX_ACLS,[ acl_LIBS=$LIBS @@ -3316,7 +3613,7 @@ if test x"$HAVE_WINBIND" = x"yes"; then EXTRA_BIN_PROGS="$EXTRA_BIN_PROGS bin/wbinfo\$(EXEEXT)" EXTRA_SBIN_PROGS="$EXTRA_SBIN_PROGS bin/winbindd\$(EXEEXT)" if test x"$BLDSHARED" = x"true"; then - SHLIB_PROGS="$SHLIB_PROGS nsswitch/$WINBIND_NSS" + SHLIB_PROGS="$SHLIB_PROGS nsswitch/$WINBIND_NSS" if test x"$with_pam" = x"yes"; then SHLIB_PROGS="$SHLIB_PROGS nsswitch/pam_winbind.$SHLIBEXT" @@ -3327,31 +3624,15 @@ else fi # Solaris has some extra fields in struct passwd that need to be -# initialised otherwise nscd crashes. Unfortunately autoconf < 2.50 -# doesn't have the AC_CHECK_MEMBER macro which would be handy for checking -# this. - -#AC_CHECK_MEMBER(struct passwd.pw_comment, -# AC_DEFINE(HAVE_PASSWD_PW_COMMENT, 1, [Defined if struct passwd has pw_comment field]), -# [#include <pwd.h>]) - -AC_CACHE_CHECK([whether struct passwd has pw_comment],samba_cv_passwd_pw_comment, [ - AC_TRY_COMPILE([#include <pwd.h>],[struct passwd p; p.pw_comment;], - samba_cv_passwd_pw_comment=yes,samba_cv_passwd_pw_comment=no)]) -if test x"$samba_cv_passwd_pw_comment" = x"yes"; then - AC_DEFINE(HAVE_PASSWD_PW_COMMENT,1,[Whether struct passwd has pw_comment]) -fi - -#AC_CHECK_MEMBER(struct passwd.pw_age, -# AC_DEFINE(HAVE_PASSWD_PW_AGE, 1, [Defined if struct passwd has pw_age field]), -# [#include <pwd.h>]) +# initialised otherwise nscd crashes. + +AC_CHECK_MEMBER(struct passwd.pw_comment, + AC_DEFINE(HAVE_PASSWD_PW_COMMENT, 1, [Defined if struct passwd has pw_comment field]),, + [#include <pwd.h>]) -AC_CACHE_CHECK([whether struct passwd has pw_age],samba_cv_passwd_pw_age, [ - AC_TRY_COMPILE([#include <pwd.h>],[struct passwd p; p.pw_age;], - samba_cv_passwd_pw_age=yes,samba_cv_passwd_pw_age=no)]) -if test x"$samba_cv_passwd_pw_age" = x"yes"; then - AC_DEFINE(HAVE_PASSWD_PW_AGE,1,[Whether struct passwd has pw_age]) -fi +AC_CHECK_MEMBER(struct passwd.pw_age, + AC_DEFINE(HAVE_PASSWD_PW_AGE, 1, [Defined if struct passwd has pw_age field]),, + [#include <pwd.h>]) ################################################# # Check to see if we should use the included popt @@ -3435,6 +3716,7 @@ dnl Always built these modules static MODULE_pdb_guest=STATIC MODULE_rpc_spoolss=STATIC MODULE_rpc_srv=STATIC +MODULE_idmap_tdb=STATIC AC_ARG_WITH(static-modules, [ --with-static-modules=MODULES Comma-seperated list of names of modules to statically link in], @@ -3484,7 +3766,12 @@ SMB_MODULE(rpc_samr, \$(RPC_SAMR_OBJ), "bin/librpc_samr.$SHLIBEXT", RPC) SMB_MODULE(rpc_echo, \$(RPC_ECHO_OBJ), "bin/librpc_echo.$SHLIBEXT", RPC) SMB_SUBSYSTEM(RPC) -SMB_MODULE(charset_weird, modules/developer.o, "bin/weird.$SHLIBEXT", CHARSET) +SMB_MODULE(idmap_winbind, sam/idmap_winbind.o, "bin/idmap_winbind.$SHLIBEXT", IDMAP) +SMB_MODULE(idmap_ldap, sam/idmap_ldap.o, "bin/idmap_ldap.$SHLIBEXT", IDMAP) +SMB_MODULE(idmap_tdb, sam/idmap_tdb.o, "bin/idmap_tdb.$SHLIBEXT", IDMAP) +SMB_SUBSYSTEM(IDMAP) + +SMB_MODULE(charset_weird, modules/weird.o, "bin/weird.$SHLIBEXT", CHARSET) SMB_SUBSYSTEM(CHARSET) SMB_MODULE(auth_rhosts, \$(AUTH_RHOSTS_OBJ), "bin/rhosts.$SHLIBEXT", AUTH) @@ -3499,8 +3786,8 @@ SMB_SUBSYSTEM(AUTH) SMB_MODULE(vfs_recycle, \$(VFS_RECYCLE_OBJ), "bin/recycle.$SHLIBEXT", VFS) 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_fake_perms, \$(VFS_FAKE_PERMS_OBJ), "bin/fake_perms.$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_SUBSYSTEM(VFS) AC_DEFINE_UNQUOTED(STRING_STATIC_MODULES, "$string_static_modules", [String list of builtin modules]) diff --git a/source/include/.cvsignore b/source/include/.cvsignore index 4bff170b3bf..bff248727f2 100644 --- a/source/include/.cvsignore +++ b/source/include/.cvsignore @@ -3,5 +3,4 @@ config.h stamp-h proto.h wrepld_proto.h -tdbsam2_parse_info.h config.h.in diff --git a/source/include/idmap.h b/source/include/idmap.h index 1e56519453a..4b38128c2f2 100644 --- a/source/include/idmap.h +++ b/source/include/idmap.h @@ -22,6 +22,9 @@ Boston, MA 02111-1307, USA. */ +#define SMB_IDMAP_INTERFACE_VERSION 1 + + #define ID_EMPTY 0x00 #define ID_USERID 0x01 #define ID_GROUPID 0x02 @@ -32,16 +35,11 @@ #define ID_NOMAP 0x10 #define ID_CACHE 0x20 -typedef union unid_t { - uid_t uid; - gid_t gid; -} unid_t; - /* Filled out by IDMAP backends */ struct idmap_methods { /* Called when backend is first loaded */ - NTSTATUS (*init)(void); + NTSTATUS (*init)( char *params ); NTSTATUS (*get_sid_from_id)(DOM_SID *sid, unid_t id, int id_type); NTSTATUS (*get_id_from_sid)(unid_t *id, int *id_type, const DOM_SID *sid); diff --git a/source/include/includes.h b/source/include/includes.h index 534bbfbf26c..7b4c8dbdff5 100644 --- a/source/include/includes.h +++ b/source/include/includes.h @@ -437,6 +437,10 @@ #include <com_err.h> #endif +#if HAVE_ATTR_XATTR_H +#include <attr/xattr.h> +#endif + /* Special macros that are no-ops except when run under Valgrind on * x86. They've moved a little bit from valgrind 1.0.4 to 1.9.4 */ #if HAVE_VALGRIND_MEMCHECK_H @@ -769,9 +773,6 @@ extern int errno; #include "version.h" #include "smb.h" -/* -#include "smbw.h" -*/ #include "nameserv.h" @@ -808,14 +809,12 @@ extern int errno; #include "auth.h" -#include "sam.h" - -#include "gums.h" - #include "idmap.h" #include "client.h" + #include "smbw.h" + #include "session.h" #include "asn_1.h" @@ -828,8 +827,6 @@ extern int errno; #include "nsswitch/winbind_client.h" -#include "genparser.h" - /* * Type for wide character dirent structure. * Only d_name is defined by POSIX. @@ -876,6 +873,10 @@ struct printjob; struct smb_ldap_privates; +/* forward declarations from smbldap.c */ + +#include "smbldap.h" + /***** automatically generated prototypes *****/ #ifndef NO_PROTO_H #include "proto.h" @@ -1283,7 +1284,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 krb5_get_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]); #endif /* HAVE_KRB5 */ /* TRUE and FALSE are part of the C99 standard and gcc, but diff --git a/source/include/ntioctl.h b/source/include/ntioctl.h index 4749842ddc5..17791fde18f 100644 --- a/source/include/ntioctl.h +++ b/source/include/ntioctl.h @@ -23,4 +23,46 @@ we only need the sparse flag */ -#define NTIOCTL_SET_SPARSE 0x900c4 + +/* IOCTL information */ +/* List of ioctl function codes that look to be of interest to remote clients like this. */ +/* Need to do some experimentation to make sure they all work remotely. */ +/* Some of the following such as the encryption/compression ones would be */ +/* invoked from tools via a specialized hook into the VFS rather than via the */ +/* standard vfs entry points */ +#define FSCTL_REQUEST_OPLOCK_LEVEL_1 0x00090000 +#define FSCTL_REQUEST_OPLOCK_LEVEL_2 0x00090004 +#define FSCTL_REQUEST_BATCH_OPLOCK 0x00090008 +#define FSCTL_LOCK_VOLUME 0x00090018 +#define FSCTL_UNLOCK_VOLUME 0x0009001C +#define FSCTL_GET_COMPRESSION 0x0009003C +#define FSCTL_SET_COMPRESSION 0x0009C040 +#define FSCTL_REQUEST_FILTER_OPLOCK 0x0009008C +#define FSCTL_FIND_FILES_BY_SID 0x0009008F +#define FSCTL_FILESYS_GET_STATISTICS 0x00090090 +#define FSCTL_SET_REPARSE_POINT 0x000900A4 +#define FSCTL_GET_REPARSE_POINT 0x000900A8 +#define FSCTL_DELETE_REPARSE_POINT 0x000900AC +#define FSCTL_0x000900C0 0x000900C0 +#define FSCTL_SET_SPARSE 0x000900C4 +#define FSCTL_SET_ZERO_DATA 0x000900C8 +#define FSCTL_SET_ENCRYPTION 0x000900D7 +#define FSCTL_ENCRYPTION_FSCTL_IO 0x000900DB +#define FSCTL_WRITE_RAW_ENCRYPTED 0x000900DF +#define FSCTL_READ_RAW_ENCRYPTED 0x000900E3 +#define FSCTL_SIS_COPYFILE 0x00090100 +#define FSCTL_SIS_LINK_FILES 0x0009C104 + +#if 0 +#define FSCTL_SECURITY_ID_CHECK +#define FSCTL_DISMOUNT_VOLUME +#define FSCTL_GET_NTFS_FILE_RECORD +#define FSCTL_ALLOW_EXTENDED_DASD_IO +#define FSCTL_RECALL_FILE +#define FSCTL_QUERY_ALLOCATED_RANGES + +#endif + +#define IO_REPARSE_TAG_MOUNT_POINT 0xA0000003 +#define IO_REPARSE_TAG_HSM 0xC0000004 +#define IO_REPARSE_TAG_SIS 0x80000007 diff --git a/source/include/ntlmssp.h b/source/include/ntlmssp.h index cfbbb00381a..067b2a58800 100644 --- a/source/include/ntlmssp.h +++ b/source/include/ntlmssp.h @@ -64,8 +64,8 @@ enum NTLM_MESSAGE_TYPE #define NTLMSSP_NAME_TYPE_SERVER 0x01 #define NTLMSSP_NAME_TYPE_DOMAIN 0x02 -#define NTLMSSP_NAME_TYPE_DOMAIN_DNS 0x03 -#define NTLMSSP_NAME_TYPE_SERVER_DNS 0x04 +#define NTLMSSP_NAME_TYPE_SERVER_DNS 0x03 +#define NTLMSSP_NAME_TYPE_DOMAIN_DNS 0x04 typedef struct ntlmssp_state { diff --git a/source/include/rpc_lsa.h b/source/include/rpc_lsa.h index d4136a9fde1..135fd76d6c9 100644 --- a/source/include/rpc_lsa.h +++ b/source/include/rpc_lsa.h @@ -237,7 +237,7 @@ typedef struct r_lsa_query_sec_obj_info typedef struct lsa_query_info { POLICY_HND pol; /* policy handle */ - uint16 info_class; /* info class */ + uint16 info_class; /* info class */ } LSA_Q_QUERY_INFO; @@ -537,6 +537,7 @@ typedef struct POLICY_HND pol; /* policy handle */ DOM_SID2 sid; UNISTR2_ARRAY rights; + uint32 count; } LSA_Q_ADD_ACCT_RIGHTS; /* LSA_R_ADD_ACCT_RIGHTS - LSA add account rights */ @@ -553,6 +554,7 @@ typedef struct DOM_SID2 sid; uint32 removeall; UNISTR2_ARRAY rights; + uint32 count; } LSA_Q_REMOVE_ACCT_RIGHTS; /* LSA_R_REMOVE_ACCT_RIGHTS - LSA remove account rights */ @@ -561,22 +563,6 @@ typedef struct NTSTATUS status; } LSA_R_REMOVE_ACCT_RIGHTS; -/* LSA_Q_ENUM_ACCT_WITH_RIGHT - LSA enum accounts with right */ -typedef struct -{ - POLICY_HND pol; - STRHDR right_hdr; - UNISTR2 right; -} LSA_Q_ENUM_ACCT_WITH_RIGHT; - -/* LSA_R_ENUM_ACCT_WITH_RIGHT - LSA enum accounts with right */ -typedef struct -{ - uint32 count; - SID_ARRAY sids; - NTSTATUS status; -} LSA_R_ENUM_ACCT_WITH_RIGHT; - /* LSA_Q_PRIV_GET_DISPNAME - LSA get privilege display name */ typedef struct lsa_q_priv_get_dispname diff --git a/source/include/rpc_secdes.h b/source/include/rpc_secdes.h index 1bb25e86511..fb7060cde3b 100644 --- a/source/include/rpc_secdes.h +++ b/source/include/rpc_secdes.h @@ -78,7 +78,8 @@ #define SEC_DESC_DACL_DEFAULTED 0x0008 #define SEC_DESC_SACL_PRESENT 0x0010 #define SEC_DESC_SACL_DEFAULTED 0x0020 -#define SEC_DESC_SELF_RELATIVE 0x8000 +#define SEC_DESC_DACL_TRUSTED 0x0040 +#define SEC_DESC_SERVER_SECURITY 0x0080 /* * New Windows 2000 bits. */ @@ -89,14 +90,28 @@ #define SE_DESC_DACL_PROTECTED 0x1000 #define SE_DESC_SACL_PROTECTED 0x2000 +/* Don't know what this means. */ +#define SEC_DESC_RM_CONTROL_VALID 0x4000 + +#define SEC_DESC_SELF_RELATIVE 0x8000 + /* security information */ #define OWNER_SECURITY_INFORMATION 0x00000001 #define GROUP_SECURITY_INFORMATION 0x00000002 #define DACL_SECURITY_INFORMATION 0x00000004 #define SACL_SECURITY_INFORMATION 0x00000008 +/* Extra W2K flags. */ +#define UNPROTECTED_SACL_SECURITY_INFORMATION 0x10000000 +#define UNPROTECTED_DACL_SECURITY_INFORMATION 0x20000000 +#define PROTECTED_SACL_SECURITY_INFORMATION 0x40000000 +#define PROTECTED_DACL_SECURITY_INFORMATION 0x80000000 #define ALL_SECURITY_INFORMATION (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|\ - DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION) + DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION|\ + UNPROTECTED_SACL_SECURITY_INFORMATION|\ + UNPROTECTED_DACL_SECURITY_INFORMATION|\ + PROTECTED_SACL_SECURITY_INFORMATION|\ + PROTECTED_DACL_SECURITY_INFORMATION) /* Globally Unique ID */ #define GUID_SIZE 16 diff --git a/source/include/safe_string.h b/source/include/safe_string.h index a6b352b02e8..df3633d91d9 100644 --- a/source/include/safe_string.h +++ b/source/include/safe_string.h @@ -113,24 +113,24 @@ size_t __unsafe_string_function_usage_here_char__(void); #endif /* HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS */ -/* the addition of the DEVELOPER checks in safe_strcpy means we must - * update a lot of code. To make this a little easier here are some - * functions that provide the lengths with less pain */ -#define pstrcpy_base(dest, src, pstring_base) \ - safe_strcpy(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1) - #define safe_strcpy_base(dest, src, base, size) \ safe_strcpy(dest, src, size-PTR_DIFF(dest,base)-1) -/* String copy functions - macro hell below adds 'type checking' - (limited, but the best we can do in C) and may tag with function - name/number to record the last 'clobber region' on that string */ +/* String copy functions - macro hell below adds 'type checking' (limited, + but the best we can do in C) and may tag with function name/number to + record the last 'clobber region' on that string */ #define pstrcpy(d,s) safe_strcpy((d), (s),sizeof(pstring)-1) #define pstrcat(d,s) safe_strcat((d), (s),sizeof(pstring)-1) #define fstrcpy(d,s) safe_strcpy((d),(s),sizeof(fstring)-1) #define fstrcat(d,s) safe_strcat((d),(s),sizeof(fstring)-1) +/* the addition of the DEVELOPER checks in safe_strcpy means we must + * update a lot of code. To make this a little easier here are some + * functions that provide the lengths with less pain */ +#define pstrcpy_base(dest, src, pstring_base) \ + safe_strcpy(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1) + /* Inside the _fn variants of these is a call to clobber_region(), - * which might destroy the stack on a buggy function. We help the diff --git a/source/include/smb.h b/source/include/smb.h index 0889abf0385..27c966914fb 100644 --- a/source/include/smb.h +++ b/source/include/smb.h @@ -66,6 +66,7 @@ typedef int BOOL; #define STR_ASCII 4 #define STR_UNICODE 8 #define STR_NOALIGN 16 +#define STR_TERMINATE_ASCII 128 /* how long to wait for secondary SMB packets (milli-seconds) */ #define SMB_SECONDARY_WAIT (60*1000) @@ -155,6 +156,11 @@ typedef int BOOL; #include "doserr.h" +typedef union unid_t { + uid_t uid; + gid_t gid; +} unid_t; + /* * SMB UCS2 (16-bit unicode) internal type. */ @@ -404,9 +410,11 @@ typedef struct files_struct BOOL is_stat; BOOL directory_delete_on_close; char *fsp_name; + FAKE_FILE_HANDLE *fake_file_handle; } files_struct; #include "ntquotas.h" +#include "sysquotas.h" /* used to hold an arbitrary blob of data */ typedef struct data_blob { @@ -442,18 +450,10 @@ typedef struct #include "smb_acls.h" #include "vfs.h" -typedef struct smb_vfs_handle_struct -{ - void *data; - /* Handle on dlopen() call */ - void *handle; - struct smb_vfs_handle_struct *next, *prev; - -} smb_vfs_handle_struct; - typedef struct connection_struct { struct connection_struct *next, *prev; + TALLOC_CTX *mem_ctx; unsigned cnum; /* an index passed over the wire */ int service; BOOL force_user; @@ -468,8 +468,9 @@ typedef struct connection_struct char *connectpath; char *origpath; - struct vfs_ops vfs_ops; /* Filesystem operations */ - struct smb_vfs_handle_struct *vfs_private; + struct vfs_ops vfs; /* Filesystem operations */ + struct vfs_ops vfs_opaque; /* OPAQUE Filesystem operations */ + struct vfs_handle_struct *vfs_handles; /* for the new plugins */ char *user; /* name of user who *opened* this connection */ uid_t uid; /* uid of user who *opened* this connection */ diff --git a/source/include/smb_macros.h b/source/include/smb_macros.h index 8e2cb1c8185..aae3b46f7a4 100644 --- a/source/include/smb_macros.h +++ b/source/include/smb_macros.h @@ -77,12 +77,15 @@ #define OPEN_CONN(conn) ((conn) && (conn)->open) #define IS_IPC(conn) ((conn) && (conn)->ipc) #define IS_PRINT(conn) ((conn) && (conn)->printer) -#define FNUM_OK(fsp,c) (OPEN_FSP(fsp) && (c)==(fsp)->conn) +#define FNUM_OK(fsp,c) (OPEN_FSP(fsp) && (c)==(fsp)->conn && current_user.vuid==(fsp)->vuid) -#define CHECK_FSP(fsp,conn) if (!FNUM_OK(fsp,conn)) \ +#define CHECK_FSP(fsp,conn) do {\ + extern struct current_user current_user;\ + if (!FNUM_OK(fsp,conn)) \ return(ERROR_DOS(ERRDOS,ERRbadfid)); \ else if((fsp)->fd == -1) \ - return(ERROR_DOS(ERRDOS,ERRbadaccess)) + return(ERROR_DOS(ERRDOS,ERRbadaccess));\ + } while(0) #define CHECK_READ(fsp) if (!(fsp)->can_read) \ return(ERROR_DOS(ERRDOS,ERRbadaccess)) @@ -244,52 +247,4 @@ copy an IP address from one buffer to another #define dos_format(fname) string_replace(fname,'/','\\') -/******************************************************************* - vfs stat wrapper that calls internal2unix. -********************************************************************/ - -#define vfs_stat(conn, fname, st) ((conn)->vfs_ops.stat((conn), fname,(st))) - -/******************************************************************* - vfs lstat wrapper that calls internal2unix. -********************************************************************/ - -#define vfs_lstat(conn, fname, st) ((conn)->vfs_ops.lstat((conn), fname,(st))) - -/******************************************************************* - vfs fstat wrapper -********************************************************************/ - -#define vfs_fstat(fsp, fd, st) ((fsp)->conn->vfs_ops.fstat((fsp),(fd),(st))) - -/******************************************************************* - vfs rmdir wrapper that calls internal2unix. -********************************************************************/ - -#define vfs_rmdir(conn,fname) ((conn)->vfs_ops.rmdir((conn),fname)) - -/******************************************************************* - vfs Unlink wrapper that calls internal2unix. -********************************************************************/ - -#define vfs_unlink(conn, fname) ((conn)->vfs_ops.unlink((conn),fname)) - -/******************************************************************* - vfs chmod wrapper that calls internal2unix. -********************************************************************/ - -#define vfs_chmod(conn,fname,mode) ((conn)->vfs_ops.chmod((conn),fname,(mode))) - -/******************************************************************* - vfs chown wrapper that calls internal2unix. -********************************************************************/ - -#define vfs_chown(conn,fname,uid,gid) ((conn)->vfs_ops.chown((conn),fname,(uid),(gid))) - -/******************************************************************* - A wrapper for vfs_chdir(). -********************************************************************/ - -#define vfs_chdir(conn,fname) ((conn)->vfs_ops.chdir((conn),fname)) - #endif /* _SMB_MACROS_H */ diff --git a/source/include/smbprofile.h b/source/include/smbprofile.h index e501de8c0e2..a64c2ce69ec 100644 --- a/source/include/smbprofile.h +++ b/source/include/smbprofile.h @@ -108,6 +108,10 @@ struct profile_stats { unsigned syscall_mknod_time; unsigned syscall_realpath_count; unsigned syscall_realpath_time; + unsigned syscall_get_quota_count; + unsigned syscall_get_quota_time; + unsigned syscall_set_quota_count; + unsigned syscall_set_quota_time; /* stat cache counters */ unsigned statcache_lookups; unsigned statcache_misses; @@ -326,6 +330,10 @@ struct profile_stats { unsigned NT_transact_rename_time; unsigned NT_transact_query_security_desc_count; unsigned NT_transact_query_security_desc_time; + unsigned NT_transact_get_user_quota_count; + unsigned NT_transact_get_user_quota_time; + unsigned NT_transact_set_user_quota_count; + unsigned NT_transact_set_user_quota_time; /* These are ACL manipulation calls */ unsigned get_nt_acl_count; unsigned get_nt_acl_time; diff --git a/source/include/trans2.h b/source/include/trans2.h index 2ccf83478be..eb5b1bc79f9 100644 --- a/source/include/trans2.h +++ b/source/include/trans2.h @@ -224,6 +224,7 @@ Byte offset Type name description #define SMB_QUERY_FILE_ALL_INFO 0x107 #define SMB_QUERY_FILE_ALT_NAME_INFO 0x108 #define SMB_QUERY_FILE_STREAM_INFO 0x109 +#define SMB_QUERY_COMPRESSION_INFO 0x10b #define SMB_FIND_FILE_DIRECTORY_INFO 0x101 #define SMB_FIND_FILE_FULL_DIRECTORY_INFO 0x102 diff --git a/source/include/version.h b/source/include/version.h index c0a1c702f29..b5b00c7859d 100644 --- a/source/include/version.h +++ b/source/include/version.h @@ -1 +1 @@ -#define VERSION "post3.0-HEAD" +#define VERSION "3.0beta1" diff --git a/source/include/vfs.h b/source/include/vfs.h index 756e417814d..924d7063217 100644 --- a/source/include/vfs.h +++ b/source/include/vfs.h @@ -1,8 +1,10 @@ /* Unix SMB/CIFS implementation. VFS structures and parameters + Copyright (C) Jeremy Allison 1999-2003 Copyright (C) Tim Potter 1999 Copyright (C) Alexander Bokovoy 2002 + Copyright (C) Stefan (metze) Metzmacher 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -45,150 +47,41 @@ /* Changed to version 3 for POSIX acl extensions. JRA. */ /* Changed to version 4 for cascaded VFS interface. Alexander Bokovoy. */ /* Changed to version 5 for sendfile addition. JRA. */ -#define SMB_VFS_INTERFACE_VERSION 5 +/* Changed to version 6 for the new module system, fixed cascading and quota functions. --metze */ +/* Changed to version 7 to include the get_nt_acl info parameter. JRA. */ +/* Changed to version 8 includes EA calls. JRA. */ +#define SMB_VFS_INTERFACE_VERSION 8 -/* Version of supported cascaded interface backward compatibility. - (version 5 corresponds to SMB_VFS_INTERFACE_VERSION 5) - It is used in vfs_init_custom() to detect VFS modules which conform to cascaded - VFS interface but implement elder version than current version of Samba uses. - This allows to use old modules with new VFS interface as far as combined VFS operation - set is coherent (will be in most cases). -*/ -#define SMB_VFS_INTERFACE_CASCADED 5 + +/* to bug old modules witch are trying to compile with the old functions */ +#define vfs_init __ERROR_please_port_this_module_to_SMB_VFS_INTERFACE_VERSION_8_donot_use_vfs_init_anymore(void) { __ERROR_please_port_this_module_to_SMB_VFS_INTERFACE_VERSION_8_donot_use_vfs_init_anymore }; +#define lp_parm_string __ERROR_please_port_lp_parm_string_to_lp_parm_const_string_or_lp_parm_talloc_string { \ + __ERROR_please_port_lp_parm_string_to_lp_parm_const_string_or_lp_parm_talloc_string }; +#define lp_vfs_options __ERROR_please_donot_use_lp_vfs_options_anymore_use_lp_parm_xxxx_functions_instead { \ + __ERROR_please_donot_use_lp_vfs_options_anymore_use_lp_parm_xxxx_functions_instead }; /* - Each VFS module must provide following global functions: - vfs_init -- initialization function - vfs_done -- finalization function - - vfs_init must return proper initialized vfs_op_tuple[] array - which describes all operations this module claims to intercept. This function - is called whenever module is loaded into smbd process using sys_dlopen(). - - vfs_init must store somewhere vfs_handle reference if module wants to store per-instance - private information for further usage. vfs_handle->data should be used to - store such information. Do not try to change other fields in this structure - or results likely to be unpredictable. - - vfs_done must perform finalization of the module. In particular, - this function must free vfs_ops structure returned to module from smb_vfs_get_opaque_ops() - function if it is used (see below). This function is called whenever module - is unloaded from smbd process using sys_dlclose(). - - Prototypes: - vfs_op_tuple *vfs_init(const struct vfs_ops *def_vfs_ops, - struct smb_vfs_handle_struct *vfs_handle); - void vfs_done(connection_struct *conn); - All intercepted VFS operations must be declared as static functions inside module source - in order to keep smbd namespace unpolluted. See source of skel, audit, and recycle bin + in order to keep smbd namespace unpolluted. See source of audit, extd_audit, fake_perms and recycle example VFS modules for more details. - */ /* VFS operations structure */ +struct vfs_handle_struct; struct connection_struct; struct files_struct; struct security_descriptor_info; -struct vfs_ops { - - /* Disk operations */ - - int (*connect)(struct connection_struct *conn, const char *service, const char *user); - void (*disconnect)(struct connection_struct *conn); - SMB_BIG_UINT (*disk_free)(struct connection_struct *conn, const char *path, BOOL small_query, SMB_BIG_UINT *bsize, - SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize); - - /* Directory operations */ - - DIR *(*opendir)(struct connection_struct *conn, const char *fname); - struct dirent *(*readdir)(struct connection_struct *conn, DIR *dirp); - int (*mkdir)(struct connection_struct *conn, const char *path, mode_t mode); - int (*rmdir)(struct connection_struct *conn, const char *path); - int (*closedir)(struct connection_struct *conn, DIR *dir); - - /* File operations */ - - int (*open)(struct connection_struct *conn, const char *fname, int flags, mode_t mode); - int (*close)(struct files_struct *fsp, int fd); - ssize_t (*read)(struct files_struct *fsp, int fd, void *data, size_t n); - ssize_t (*write)(struct files_struct *fsp, int fd, const void *data, size_t n); - SMB_OFF_T (*lseek)(struct files_struct *fsp, int filedes, SMB_OFF_T offset, int whence); - ssize_t (*sendfile)(int tofd, files_struct *fsp, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count); - int (*rename)(struct connection_struct *conn, const char *old, const char *new); - int (*fsync)(struct files_struct *fsp, int fd); - int (*stat)(struct connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf); - int (*fstat)(struct files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf); - int (*lstat)(struct connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf); - int (*unlink)(struct connection_struct *conn, const char *path); - int (*chmod)(struct connection_struct *conn, const char *path, mode_t mode); - int (*fchmod)(struct files_struct *fsp, int fd, mode_t mode); - int (*chown)(struct connection_struct *conn, const char *path, uid_t uid, gid_t gid); - int (*fchown)(struct files_struct *fsp, int fd, uid_t uid, gid_t gid); - int (*chdir)(struct connection_struct *conn, const char *path); - char *(*getwd)(struct connection_struct *conn, char *buf); - int (*utime)(struct connection_struct *conn, const char *path, struct utimbuf *times); - int (*ftruncate)(struct files_struct *fsp, int fd, SMB_OFF_T offset); - BOOL (*lock)(struct files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type); - int (*symlink)(struct connection_struct *conn, const char *oldpath, const char *newpath); - int (*readlink)(struct connection_struct *conn, const char *path, char *buf, size_t bufsiz); - int (*link)(struct connection_struct *conn, const char *oldpath, const char *newpath); - int (*mknod)(struct connection_struct *conn, const char *path, mode_t mode, SMB_DEV_T dev); - char *(*realpath)(struct connection_struct *conn, const char *path, char *resolved_path); - - /* NT ACL operations. */ - - size_t (*fget_nt_acl)(struct files_struct *fsp, int fd, struct security_descriptor_info **ppdesc); - size_t (*get_nt_acl)(struct files_struct *fsp, const char *name, struct security_descriptor_info **ppdesc); - BOOL (*fset_nt_acl)(struct files_struct *fsp, int fd, uint32 security_info_sent, struct security_descriptor_info *psd); - BOOL (*set_nt_acl)(struct files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor_info *psd); - - /* POSIX ACL operations. */ - - int (*chmod_acl)(struct connection_struct *conn, const char *name, mode_t mode); - int (*fchmod_acl)(struct files_struct *fsp, int fd, mode_t mode); - - int (*sys_acl_get_entry)(struct connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p); - int (*sys_acl_get_tag_type)(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p); - int (*sys_acl_get_permset)(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p); - void * (*sys_acl_get_qualifier)(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d); - SMB_ACL_T (*sys_acl_get_file)(struct connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type); - SMB_ACL_T (*sys_acl_get_fd)(struct files_struct *fsp, int fd); - int (*sys_acl_clear_perms)(struct connection_struct *conn, SMB_ACL_PERMSET_T permset); - int (*sys_acl_add_perm)(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm); - char * (*sys_acl_to_text)(struct connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen); - SMB_ACL_T (*sys_acl_init)(struct connection_struct *conn, int count); - int (*sys_acl_create_entry)(struct connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry); - int (*sys_acl_set_tag_type)(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype); - int (*sys_acl_set_qualifier)(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual); - int (*sys_acl_set_permset)(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset); - int (*sys_acl_valid)(struct connection_struct *conn, SMB_ACL_T theacl ); - int (*sys_acl_set_file)(struct connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl); - int (*sys_acl_set_fd)(struct files_struct *fsp, int fd, SMB_ACL_T theacl); - int (*sys_acl_delete_def_file)(struct connection_struct *conn, const char *path); - int (*sys_acl_get_perm)(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm); - int (*sys_acl_free_text)(struct connection_struct *conn, char *text); - int (*sys_acl_free_acl)(struct connection_struct *conn, SMB_ACL_T posix_acl); - int (*sys_acl_free_qualifier)(struct connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype); -}; - -struct vfs_options { - struct vfs_options *prev, *next; - char *name; - char *value; -}; - /* - Available VFS operations. These values must be in sync with vfs_ops struct. + Available VFS operations. These values must be in sync with vfs_ops struct + (struct vfs_fn_pointers and struct vfs_handle_pointers inside of struct vfs_ops). In particular, if new operations are added to vfs_ops, appropriate constants should be added to vfs_op_type so that order of them kept same as in vfs_ops. */ typedef enum _vfs_op_type { - SMB_VFS_OP_NOOP = -1, /* Disk operations */ @@ -196,6 +89,8 @@ typedef enum _vfs_op_type { SMB_VFS_OP_CONNECT = 0, SMB_VFS_OP_DISCONNECT, SMB_VFS_OP_DISK_FREE, + SMB_VFS_OP_GET_QUOTA, + SMB_VFS_OP_SET_QUOTA, /* Directory operations */ @@ -269,12 +164,225 @@ typedef enum _vfs_op_type { SMB_VFS_OP_SYS_ACL_FREE_ACL, SMB_VFS_OP_SYS_ACL_FREE_QUALIFIER, + /* EA operations. */ + SMB_VFS_OP_GETXATTR, + SMB_VFS_OP_LGETXATTR, + SMB_VFS_OP_FGETXATTR, + SMB_VFS_OP_LISTXATTR, + SMB_VFS_OP_LLISTXATTR, + SMB_VFS_OP_FLISTXATTR, + SMB_VFS_OP_REMOVEXATTR, + SMB_VFS_OP_LREMOVEXATTR, + SMB_VFS_OP_FREMOVEXATTR, + SMB_VFS_OP_SETXATTR, + SMB_VFS_OP_LSETXATTR, + SMB_VFS_OP_FSETXATTR, + /* This should always be last enum value */ SMB_VFS_OP_LAST } vfs_op_type; /* + Please keep vfs_op_type, struct vfs_fn_pointers and struct vfs_handles_pointers in sync. +*/ +struct vfs_ops { + struct vfs_fn_pointers { + /* Disk operations */ + + int (*connect)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *service, const char *user); + void (*disconnect)(struct vfs_handle_struct *handle, struct connection_struct *conn); + SMB_BIG_UINT (*disk_free)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, BOOL small_query, SMB_BIG_UINT *bsize, + SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize); + int (*get_quota)(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt); + int (*set_quota)(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt); + + /* Directory operations */ + + DIR *(*opendir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname); + struct dirent *(*readdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dirp); + int (*mkdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, mode_t mode); + int (*rmdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path); + int (*closedir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dir); + + /* File operations */ + + int (*open)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname, int flags, mode_t mode); + int (*close)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd); + ssize_t (*read)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, void *data, size_t n); + ssize_t (*write)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, const void *data, size_t n); + SMB_OFF_T (*lseek)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_OFF_T offset, int whence); + ssize_t (*sendfile)(struct vfs_handle_struct *handle, int tofd, files_struct *fsp, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count); + int (*rename)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *old, const char *new); + int (*fsync)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd); + int (*stat)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf); + int (*fstat)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf); + int (*lstat)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf); + int (*unlink)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path); + int (*chmod)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, mode_t mode); + int (*fchmod)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, mode_t mode); + int (*chown)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, uid_t uid, gid_t gid); + int (*fchown)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, uid_t uid, gid_t gid); + int (*chdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path); + char *(*getwd)(struct vfs_handle_struct *handle, struct connection_struct *conn, char *buf); + int (*utime)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, struct utimbuf *times); + int (*ftruncate)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_OFF_T offset); + BOOL (*lock)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type); + int (*symlink)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *oldpath, const char *newpath); + int (*readlink)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, char *buf, size_t bufsiz); + int (*link)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *oldpath, const char *newpath); + int (*mknod)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, mode_t mode, SMB_DEV_T dev); + char *(*realpath)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, char *resolved_path); + + /* NT ACL operations. */ + + size_t (*fget_nt_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, uint32 security_info, struct security_descriptor_info **ppdesc); + size_t (*get_nt_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, uint32 security_info, struct security_descriptor_info **ppdesc); + BOOL (*fset_nt_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, uint32 security_info_sent, struct security_descriptor_info *psd); + BOOL (*set_nt_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor_info *psd); + + /* POSIX ACL operations. */ + + int (*chmod_acl)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *name, mode_t mode); + int (*fchmod_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, mode_t mode); + + int (*sys_acl_get_entry)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p); + int (*sys_acl_get_tag_type)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p); + int (*sys_acl_get_permset)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p); + void * (*sys_acl_get_qualifier)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d); + SMB_ACL_T (*sys_acl_get_file)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type); + SMB_ACL_T (*sys_acl_get_fd)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd); + int (*sys_acl_clear_perms)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_PERMSET_T permset); + int (*sys_acl_add_perm)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm); + char * (*sys_acl_to_text)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen); + SMB_ACL_T (*sys_acl_init)(struct vfs_handle_struct *handle, struct connection_struct *conn, int count); + int (*sys_acl_create_entry)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry); + int (*sys_acl_set_tag_type)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype); + int (*sys_acl_set_qualifier)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual); + int (*sys_acl_set_permset)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset); + int (*sys_acl_valid)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T theacl ); + int (*sys_acl_set_file)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl); + int (*sys_acl_set_fd)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_ACL_T theacl); + int (*sys_acl_delete_def_file)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path); + int (*sys_acl_get_perm)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm); + int (*sys_acl_free_text)(struct vfs_handle_struct *handle, struct connection_struct *conn, char *text); + int (*sys_acl_free_acl)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T posix_acl); + int (*sys_acl_free_qualifier)(struct vfs_handle_struct *handle, struct connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype); + + /* EA operations. */ + ssize_t (*getxattr)(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size); + ssize_t (*lgetxattr)(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size); + ssize_t (*fgetxattr)(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, void *value, size_t size); + ssize_t (*listxattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size); + ssize_t (*llistxattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size); + ssize_t (*flistxattr)(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, char *list, size_t size); + int (*removexattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name); + int (*lremovexattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name); + int (*fremovexattr)(struct vfs_handle_struct *handle, struct files_struct *fsp,int filedes, const char *name); + int (*setxattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags); + int (*lsetxattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags); + int (*fsetxattr)(struct vfs_handle_struct *handle, struct files_struct *fsp,int filedes, const char *name, const void *value, size_t size, int flags); + + } ops; + + struct vfs_handles_pointers { + /* Disk operations */ + + struct vfs_handle_struct *connect; + struct vfs_handle_struct *disconnect; + struct vfs_handle_struct *disk_free; + struct vfs_handle_struct *get_quota; + struct vfs_handle_struct *set_quota; + + /* Directory operations */ + + struct vfs_handle_struct *opendir; + struct vfs_handle_struct *readdir; + struct vfs_handle_struct *mkdir; + struct vfs_handle_struct *rmdir; + struct vfs_handle_struct *closedir; + + /* File operations */ + + struct vfs_handle_struct *open; + struct vfs_handle_struct *close; + struct vfs_handle_struct *read; + struct vfs_handle_struct *write; + struct vfs_handle_struct *lseek; + struct vfs_handle_struct *sendfile; + struct vfs_handle_struct *rename; + struct vfs_handle_struct *fsync; + struct vfs_handle_struct *stat; + struct vfs_handle_struct *fstat; + struct vfs_handle_struct *lstat; + struct vfs_handle_struct *unlink; + struct vfs_handle_struct *chmod; + struct vfs_handle_struct *fchmod; + struct vfs_handle_struct *chown; + struct vfs_handle_struct *fchown; + struct vfs_handle_struct *chdir; + struct vfs_handle_struct *getwd; + struct vfs_handle_struct *utime; + struct vfs_handle_struct *ftruncate; + struct vfs_handle_struct *lock; + struct vfs_handle_struct *symlink; + struct vfs_handle_struct *readlink; + struct vfs_handle_struct *link; + struct vfs_handle_struct *mknod; + struct vfs_handle_struct *realpath; + + /* NT ACL operations. */ + + struct vfs_handle_struct *fget_nt_acl; + struct vfs_handle_struct *get_nt_acl; + struct vfs_handle_struct *fset_nt_acl; + struct vfs_handle_struct *set_nt_acl; + + /* POSIX ACL operations. */ + + struct vfs_handle_struct *chmod_acl; + struct vfs_handle_struct *fchmod_acl; + + struct vfs_handle_struct *sys_acl_get_entry; + struct vfs_handle_struct *sys_acl_get_tag_type; + struct vfs_handle_struct *sys_acl_get_permset; + struct vfs_handle_struct *sys_acl_get_qualifier; + struct vfs_handle_struct *sys_acl_get_file; + struct vfs_handle_struct *sys_acl_get_fd; + struct vfs_handle_struct *sys_acl_clear_perms; + struct vfs_handle_struct *sys_acl_add_perm; + struct vfs_handle_struct *sys_acl_to_text; + struct vfs_handle_struct *sys_acl_init; + struct vfs_handle_struct *sys_acl_create_entry; + struct vfs_handle_struct *sys_acl_set_tag_type; + struct vfs_handle_struct *sys_acl_set_qualifier; + struct vfs_handle_struct *sys_acl_set_permset; + struct vfs_handle_struct *sys_acl_valid; + struct vfs_handle_struct *sys_acl_set_file; + struct vfs_handle_struct *sys_acl_set_fd; + struct vfs_handle_struct *sys_acl_delete_def_file; + struct vfs_handle_struct *sys_acl_get_perm; + struct vfs_handle_struct *sys_acl_free_text; + struct vfs_handle_struct *sys_acl_free_acl; + struct vfs_handle_struct *sys_acl_free_qualifier; + + /* EA operations. */ + struct vfs_handle_struct *getxattr; + struct vfs_handle_struct *lgetxattr; + struct vfs_handle_struct *fgetxattr; + struct vfs_handle_struct *listxattr; + struct vfs_handle_struct *llistxattr; + struct vfs_handle_struct *flistxattr; + struct vfs_handle_struct *removexattr; + struct vfs_handle_struct *lremovexattr; + struct vfs_handle_struct *fremovexattr; + struct vfs_handle_struct *setxattr; + struct vfs_handle_struct *lsetxattr; + struct vfs_handle_struct *fsetxattr; + } handles; +}; + +/* Possible VFS operation layers (per-operation) These values are used by VFS subsystem when building vfs_ops for connection @@ -300,7 +408,7 @@ typedef enum _vfs_op_layer { SMB_VFS_LAYER_OPAQUE = 0, /* - Final level, does not call anything beyond itself */ SMB_VFS_LAYER_TRANSPARENT, /* - Normal operation, calls underlying layer after */ /* possibly changing passed data */ - SMB_VFS_LAYER_LOGGER, /* - Logs data, calls underlying layer, logging does not */ + SMB_VFS_LAYER_LOGGER, /* - Logs data, calls underlying layer, logging may not */ /* use Samba VFS */ SMB_VFS_LAYER_SPLITTER, /* - Splits operation, calls underlying layer _and_ own facility, */ /* then combines result */ @@ -309,10 +417,10 @@ typedef enum _vfs_op_layer { } vfs_op_layer; /* - VFS operation description. Each VFS module initialization function returns to VFS subsystem - an array of vfs_op_tuple which describes all operations this module is willing to intercept. - VFS subsystem initializes then vfs_ops using this information and passes it - to next VFS module as underlying vfs_ops and to connection after all VFS modules are initialized. + VFS operation description. Each VFS module registers an array of vfs_op_tuple to VFS subsystem, + which describes all operations this module is willing to intercept. + VFS subsystem initializes then the conn->vfs_ops and conn->vfs_opaque_ops structs + using this information. */ typedef struct _vfs_op_tuple { @@ -321,18 +429,46 @@ typedef struct _vfs_op_tuple { vfs_op_layer layer; } vfs_op_tuple; -/* - Return vfs_ops filled with current opaque VFS operations. This function is designed to - be called from VFS module initialization function for those modules which needs 'direct' VFS - access (loggers or initiators of file operations other than connection asks for). - - Returned vfs_ops must be cleaned up in VFS module's finalizer function (vfs_done_<module_name>) - using safe_free(). - - Prototype: - struct vfs_ops *smb_vfs_get_opaque_ops(); - - This prototype will be available via include/proto.h -*/ + +typedef struct vfs_handle_struct { + struct vfs_handle_struct *next, *prev; + const char *param; + struct vfs_ops vfs_next; + struct connection_struct *conn; + void *data; + void (*free_data)(void **data); +} vfs_handle_struct; + + +#define SMB_VFS_HANDLE_GET_DATA(handle, datap, type, ret) { \ + if (!(handle)||((datap=(type *)(handle)->data)==NULL)) { \ + DEBUG(0,("%s() failed to get vfs_handle->data!\n",FUNCTION_MACRO)); \ + ret; \ + } \ +} + +#define SMB_VFS_HANDLE_SET_DATA(handle, datap, free_fn, type, ret) { \ + if (!(handle)) { \ + DEBUG(0,("%s() failed to set handle->data!\n",FUNCTION_MACRO)); \ + ret; \ + } else { \ + if ((handle)->free_data) { \ + (handle)->free_data(&(handle)->data); \ + } \ + (handle)->data = (void *)datap; \ + (handle)->free_data = free_fn; \ + } \ +} + +#define SMB_VFS_HANDLE_FREE_DATA(handle) { \ + if ((handle) && (handle)->free_data) { \ + (handle)->free_data(&(handle)->data); \ + } \ +} + +#define SMB_VFS_OP(x) ((void *) x) + + +#include "vfs_macros.h" #endif /* _VFS_H */ diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c index eb427cc0fce..708ef343e1a 100644 --- a/source/lib/charcnv.c +++ b/source/lib/charcnv.c @@ -367,7 +367,7 @@ size_t push_ascii(void *dest, const char *src, size_t dest_len, int flags) src = tmpbuf; } - if (flags & STR_TERMINATE) + if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII)) src_len++; return convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len); @@ -723,8 +723,21 @@ size_t pull_utf8_allocate(void **dest, const char *src) size_t push_string_fn(const char *function, unsigned int line, const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags) { +#ifdef DEVELOPER + /* We really need to zero fill here, not clobber + * region, as we want to ensure that valgrind thinks + * all of the outgoing buffer has been written to + * so a send() or write() won't trap an error. + * JRA. + */ +#if 0 if (dest_len != (size_t)-1) clobber_region(function, line, dest, dest_len); +#else + if (dest_len != (size_t)-1) + memset(dest, '\0', dest_len); +#endif +#endif if (!(flags & STR_ASCII) && \ ((flags & STR_UNICODE || \ diff --git a/source/lib/module.c b/source/lib/module.c index 4437d085f9c..ac4fe57a2c8 100644 --- a/source/lib/module.c +++ b/source/lib/module.c @@ -130,29 +130,6 @@ void init_modules(void) } -/************************************************************************* - * This functions /path/to/foobar.so -> foobar - ************************************************************************/ -void module_path_get_name(const char *path, pstring name) -{ - char *s; - - /* First, make the path relative */ - s = strrchr(path, '/'); - if(s) pstrcpy(name, s+1); - else pstrcpy(name, path); - - if (dyn_SHLIBEXT && *dyn_SHLIBEXT && strlen(dyn_SHLIBEXT) < strlen(name)) { - int n = strlen(name) - strlen(dyn_SHLIBEXT); - - /* Remove extension if necessary */ - if (name[n-1] == '.' && !strcmp(name+n, dyn_SHLIBEXT)) { - name[n-1] = '\0'; - } - } -} - - /*************************************************************************** * This Function registers a idle event * diff --git a/source/lib/system.c b/source/lib/system.c index 6ff97b88da3..a7024c852df 100644 --- a/source/lib/system.c +++ b/source/lib/system.c @@ -1253,3 +1253,128 @@ int sys_dup2(int oldfd, int newfd) #endif SAFE_FREE(msgbuf); } + +/************************************************************************** + Wrappers for extented attribute calls. Based on the Linux package with + support for IRIX also. Expand as other systems have them. +****************************************************************************/ + +ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t size) +{ +#if defined(HAVE_GETXATTR) + return getxattr(path, name, value, size); +#else + errno = ENOSYS; + return -1; +#endif +} + +ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t size) +{ +#if defined(HAVE_LGETXATTR) + return lgetxattr(path, name, value, size); +#else + errno = ENOSYS; + return -1; +#endif +} + +ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size) +{ +#if defined(HAVE_FGETXATTR) + return fgetxattr(filedes, name, value, size); +#else + errno = ENOSYS; + return -1; +#endif +} + +ssize_t sys_listxattr (const char *path, char *list, size_t size) +{ +#if defined(HAVE_LISTXATTR) + return listxattr(path, list, size); +#else + errno = ENOSYS; + return -1; +#endif +} + +ssize_t sys_llistxattr (const char *path, char *list, size_t size) +{ +#if defined(HAVE_GETXATTR) + return llistxattr(path, list, size); +#else + errno = ENOSYS; + return -1; +#endif +} + +ssize_t sys_flistxattr (int filedes, char *list, size_t size) +{ +#if defined(HAVE_FLISTXATTR) + return flistxattr(filedes, list, size); +#else + errno = ENOSYS; + return -1; +#endif +} + +int sys_removexattr (const char *path, const char *name) +{ +#if defined(HAVE_REMOVEXATTR) + return removexattr(path, name); +#else + errno = ENOSYS; + return -1; +#endif +} + +int sys_lremovexattr (const char *path, const char *name) +{ +#if defined(HAVE_LREMOVEXATTR) + return lremovexattr(path, name); +#else + errno = ENOSYS; + return -1; +#endif +} + +int sys_fremovexattr (int filedes, const char *name) +{ +#if defined(HAVE_FREMOVEXATTR) + return fremovexattr(filedes, name); +#else + errno = ENOSYS; + return -1; +#endif +} + +int sys_setxattr (const char *path, const char *name, const void *value, size_t size, int flags) +{ +#if defined(HAVE_SETXATTR) + return setxattr(path, name, value, size, flags); +#else + errno = ENOSYS; + return -1; +#endif +} + +int sys_lsetxattr (const char *path, const char *name, const void *value, size_t size, int flags) +{ +#if defined(HAVE_LSETXATTR) + return lsetxattr(path, name, value, size, flags); +#else + errno = ENOSYS; + return -1; +#endif +} + +int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags) +{ +#if defined(HAVE_FSETXATTR) + return fsetxattr(filedes, name, value, size, flags); +#else + errno = ENOSYS; + return -1; +#endif +} diff --git a/source/lib/util.c b/source/lib/util.c index e1ddd578839..95d3403a7cd 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -937,6 +937,19 @@ void *Realloc(void *p,size_t size) return(ret); } +void *Realloc_zero(void *ptr, size_t size) +{ + void *tptr = NULL; + + tptr = Realloc(ptr, size); + if(tptr == NULL) + return NULL; + + memset((char *)tptr,'\0',size); + + return tptr; +} + /**************************************************************************** Free memory, checks for NULL. Use directly SAFE_FREE() diff --git a/source/lib/util_sid.c b/source/lib/util_sid.c index 9dc0c8ca18d..00f14d7d26b 100644 --- a/source/lib/util_sid.c +++ b/source/lib/util_sid.c @@ -391,6 +391,9 @@ BOOL sid_peek_check_rid(const DOM_SID *exp_dom_sid, const DOM_SID *sid, uint32 * if (!exp_dom_sid || !sid || !rid) return False; + if (sid->num_auths != (exp_dom_sid->num_auths+1)) { + return False; + } if (sid_compare_domain(exp_dom_sid, sid)!=0){ *rid=(-1); @@ -642,8 +645,9 @@ DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, DOM_SID *src) if(!src) return NULL; - if((dst = talloc_zero(ctx, sizeof(DOM_SID))) != NULL) + if((dst = talloc_zero(ctx, sizeof(DOM_SID))) != NULL) { sid_copy( dst, src); + } return dst; } diff --git a/source/lib/util_sock.c b/source/lib/util_sock.c index c974050b43e..8c171852abb 100644 --- a/source/lib/util_sock.c +++ b/source/lib/util_sock.c @@ -764,6 +764,19 @@ char *client_addr(void) return get_socket_addr(client_fd); } +struct in_addr *client_inaddr(struct sockaddr *sa) +{ + struct sockaddr_in *sockin = (struct sockaddr_in *) (sa); + int length = sizeof(*sa); + + if (getpeername(client_fd, sa, &length) < 0) { + DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) )); + return NULL; + } + + return &sockin->sin_addr; +} + /******************************************************************* matchname - determine if host name matches IP address. Used to confirm a hostname lookup to prevent spoof attacks diff --git a/source/lib/util_str.c b/source/lib/util_str.c index e561d15f61b..87a8ea2eb19 100644 --- a/source/lib/util_str.c +++ b/source/lib/util_str.c @@ -1713,3 +1713,25 @@ char * base64_encode_data_blob(DATA_BLOB data) return result; } +/* read a SMB_BIG_UINT from a string */ +SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr) +{ + + SMB_BIG_UINT val = -1; + const char *p = nptr; + + while (p && *p && isspace(*p)) + p++; +#ifdef LARGE_SMB_OFF_T + sscanf(p,"%llu",&val); +#else /* LARGE_SMB_OFF_T */ + sscanf(p,"%lu",&val); +#endif /* LARGE_SMB_OFF_T */ + if (entptr) { + while (p && *p && isdigit(*p)) + p++; + *entptr = p; + } + + return val; +} diff --git a/source/libads/ads_utils.c b/source/libads/ads_utils.c index c56e7385a41..1aad0bed547 100644 --- a/source/libads/ads_utils.c +++ b/source/libads/ads_utils.c @@ -89,52 +89,6 @@ uint32 ads_uf2atype(uint32 uf) } /* -translated the GROUP_CTRL Flags to GroupType (groupType) -*/ -uint32 ads_gcb2gtype(uint16 gcb) -{ - uint32 gtype = 0x00000000; - - if (gcb & GCB_ALIAS_GROUP) gtype |= GTYPE_SECURITY_BUILTIN_LOCAL_GROUP; - else if(gcb & GCB_LOCAL_GROUP) gtype |= GTYPE_SECURITY_DOMAIN_LOCAL_GROUP; - if (gcb & GCB_GLOBAL_GROUP) gtype |= GTYPE_SECURITY_GLOBAL_GROUP; - - return gtype; -} - -/* -translated the GroupType (groupType) to GROUP_CTRL Flags -*/ -uint16 ads_gtype2gcb(uint32 gtype) -{ - uint16 gcb = 0x0000; - - switch(gtype) { - case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP: - gcb = GCB_ALIAS_GROUP; - break; - case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP: - gcb = GCB_LOCAL_GROUP; - break; - case GTYPE_SECURITY_GLOBAL_GROUP: - gcb = GCB_GLOBAL_GROUP; - break; - - case GTYPE_DISTRIBUTION_GLOBAL_GROUP: - gcb = GCB_GLOBAL_GROUP; - break; - case GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP: - gcb = GCB_LOCAL_GROUP; - break; - case GTYPE_DISTRIBUTION_UNIVERSAL_GROUP: - gcb = GCB_GLOBAL_GROUP; - break; - } - - return gcb; -} - -/* get the accountType from the groupType */ uint32 ads_gtype2atype(uint32 gtype) diff --git a/source/libads/kerberos_verify.c b/source/libads/kerberos_verify.c index 35d429ca2ab..65b557af574 100644 --- a/source/libads/kerberos_verify.c +++ b/source/libads/kerberos_verify.c @@ -138,9 +138,11 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, *ap_rep = data_blob(packet.data, packet.length); free(packet.data); - krb5_get_smb_session_key(context, auth_context, session_key); - DEBUG(0,("SMB session key (from ticket) follows:\n")); - dump_data(0, session_key, 16); + get_krb5_smb_session_key(context, auth_context, session_key); +#ifdef DEBUG_PASSWORD + DEBUG(10,("SMB session key (from ticket) follows:\n")); + dump_data(10, session_key, 16); +#endif #if 0 file_save("/tmp/ticket.dat", ticket->data, ticket->length); diff --git a/source/libads/krb5_setpw.c b/source/libads/krb5_setpw.c index 214871b3fb5..df749d04d36 100644 --- a/source/libads/krb5_setpw.c +++ b/source/libads/krb5_setpw.c @@ -195,9 +195,9 @@ static const struct kpasswd_errors { {0, NULL} }; -static krb5_error_code krb5_setpw_result_code_string(krb5_context context, - int result_code, - const char **code_string) +static krb5_error_code setpw_result_code_string(krb5_context context, + int result_code, + const char **code_string) { unsigned int idx = 0; @@ -311,7 +311,7 @@ static krb5_error_code parse_setpw_reply(krb5_context context, return 0; else { const char *errstr; - krb5_setpw_result_code_string(context, res_code, &errstr); + setpw_result_code_string(context, res_code, &errstr); DEBUG(1, ("Error changing password: %s\n", errstr)); switch(res_code) { @@ -457,8 +457,8 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, return ADS_SUCCESS; } -ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char *newpw, - int time_offset) +ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, + const char *newpw, int time_offset) { ADS_STATUS aret; @@ -570,11 +570,11 @@ kerb_prompter(krb5_context ctx, void *data, return 0; } -static ADS_STATUS krb5_chg_password(const char *kdc_host, - const char *principal, - const char *oldpw, - const char *newpw, - int time_offset) +static ADS_STATUS ads_krb5_chg_password(const char *kdc_host, + const char *principal, + const char *oldpw, + const char *newpw, + int time_offset) { ADS_STATUS aret; krb5_error_code ret; @@ -648,11 +648,11 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, } if (!strcmp(auth_principal, target_principal)) - return krb5_chg_password(kpasswd_server, target_principal, - auth_password, new_password, time_offset); + return ads_krb5_chg_password(kpasswd_server, target_principal, + auth_password, new_password, time_offset); else - return krb5_set_password(kpasswd_server, target_principal, - new_password, time_offset); + return ads_krb5_set_password(kpasswd_server, target_principal, + new_password, time_offset); } @@ -677,9 +677,10 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, we need to use the '$' form of the name here, as otherwise the server might end up setting the password for a user instead */ - asprintf(&principal, "%s$@%s", host, ads->auth.realm); + asprintf(&principal, "%s$@%s", host, ads->config.realm); - status = krb5_set_password(ads->auth.kdc_server, principal, password, ads->auth.time_offset); + status = ads_krb5_set_password(ads->auth.kdc_server, principal, + password, ads->auth.time_offset); free(host); free(principal); diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c index 32397173da1..8ebac7bae7b 100644 --- a/source/libsmb/cliconnect.c +++ b/source/libsmb/cliconnect.c @@ -270,14 +270,23 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, if (passlen != 24) { if (lp_client_ntlmv2_auth()) { DATA_BLOB server_chal; - + DATA_BLOB names_blob; server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8)); - if (!SMBNTLMv2encrypt(user, workgroup, pass, server_chal, + /* note that the 'workgroup' here is a best guess - we don't know + the server's domain at this point. The 'server name' is also + dodgy... + */ + names_blob = NTLMv2_generate_names_blob(cli->called.name, workgroup); + + if (!SMBNTLMv2encrypt(user, workgroup, pass, &server_chal, + &names_blob, &lm_response, &nt_response, &session_key)) { + data_blob_free(&names_blob); data_blob_free(&server_chal); return False; } + data_blob_free(&names_blob); data_blob_free(&server_chal); } else { @@ -823,9 +832,6 @@ BOOL cli_send_tconX(struct cli_state *cli, clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, STR_TERMINATE|STR_ASCII); - if (strcasecmp(share,"IPC$")==0) - fstrcpy(cli->dev, "IPC"); - if (cli->protocol >= PROTOCOL_NT1 && smb_buflen(cli->inbuf) == 3) { /* almost certainly win95 - enable bug fixes */ diff --git a/source/libsmb/clikrb5.c b/source/libsmb/clikrb5.c index 5edc56daa9b..df6043a618b 100644 --- a/source/libsmb/clikrb5.c +++ b/source/libsmb/clikrb5.c @@ -235,12 +235,12 @@ krb5_error_code get_kerberos_allowed_etypes(krb5_context context, /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ -static krb5_error_code krb5_mk_req2(krb5_context context, - krb5_auth_context *auth_context, - const krb5_flags ap_req_options, - const char *principal, - krb5_ccache ccache, - krb5_data *outbuf) +static krb5_error_code ads_krb5_mk_req(krb5_context context, + krb5_auth_context *auth_context, + const krb5_flags ap_req_options, + const char *principal, + krb5_ccache ccache, + krb5_data *outbuf) { krb5_error_code retval; krb5_principal server; @@ -305,7 +305,7 @@ cleanup_princ: /* get a kerberos5 ticket for the given service */ -DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) +DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset) { krb5_error_code retval; krb5_data packet; @@ -344,11 +344,11 @@ DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) goto failed; } - if ((retval = krb5_mk_req2(context, - &auth_context, - 0, - principal, - ccdef, &packet))) { + if ((retval = ads_krb5_mk_req(context, + &auth_context, + 0, + principal, + ccdef, &packet))) { goto failed; } @@ -365,7 +365,7 @@ failed: return data_blob(NULL, 0); } - BOOL krb5_get_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]) { #ifdef ENCTYPE_ARCFOUR_HMAC krb5_keyblock *skey; @@ -390,7 +390,7 @@ failed: } #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ -DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) +DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset) { DEBUG(0,("NO KERBEROS SUPPORT\n")); return data_blob(NULL, 0); diff --git a/source/libsmb/clispnego.c b/source/libsmb/clispnego.c index 53f7eb6e7d9..bb48f579151 100644 --- a/source/libsmb/clispnego.c +++ b/source/libsmb/clispnego.c @@ -329,7 +329,7 @@ DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset) const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; /* get a kerberos ticket for the service */ - tkt = krb5_get_ticket(principal, time_offset); + tkt = cli_krb5_get_ticket(principal, time_offset); /* wrap that up in a nice GSS-API wrapping */ tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); diff --git a/source/libsmb/namequery_dc.c b/source/libsmb/namequery_dc.c index ffc64139e9b..e98b728963e 100644 --- a/source/libsmb/namequery_dc.c +++ b/source/libsmb/namequery_dc.c @@ -25,15 +25,149 @@ #include "includes.h" -/* - find the DC for a domain using methods appropriate for a RPC domain -*/ +#define FAILED_CONNECTION_CACHE_TIMEOUT 30 /* Seconds between attempts */ + +struct failed_connection_cache { + fstring domain_name; + fstring controller; + time_t lookup_time; + NTSTATUS nt_status; + struct failed_connection_cache *prev, *next; +}; + +static struct failed_connection_cache *failed_connection_cache; + +/********************************************************************** + Check for a previously failed connection +**********************************************************************/ + +static NTSTATUS check_negative_conn_cache( const char *domain, const char *server ) +{ + struct failed_connection_cache *fcc; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + + /* can't check if we don't have strings */ + + if ( !domain || !server ) + return NT_STATUS_OK; + + for (fcc = failed_connection_cache; fcc; fcc = fcc->next) { + + /* + * we have a match IFF the domain and server name matches + * (a) the domain matches, + * (b) the IP address matches (if we have one) + * (c) the server name (if specified) matches + */ + + if ( !strequal(domain, fcc->domain_name) || !strequal(server, fcc->controller) ) + continue; /* no match; check the next entry */ + + /* we have a match so see if it is still current */ + + if ((time(NULL) - fcc->lookup_time) > FAILED_CONNECTION_CACHE_TIMEOUT) + { + /* Cache entry has expired, delete it */ + + DEBUG(10, ("check_negative_conn_cache: cache entry expired for %s, %s\n", + domain, server )); + + DLIST_REMOVE(failed_connection_cache, fcc); + SAFE_FREE(fcc); + + return NT_STATUS_OK; + } + + /* The timeout hasn't expired yet so return false */ + + DEBUG(10, ("check_negative_conn_cache: returning negative entry for %s, %s\n", + domain, server )); + + result = fcc->nt_status; + return result; + } + + /* end of function means no cache entry */ + return NT_STATUS_OK; +} + +/********************************************************************** + Add an entry to the failed conneciton cache +**********************************************************************/ + +void add_failed_connection_entry(const char *domain, const char *server, NTSTATUS result) +{ + struct failed_connection_cache *fcc; + + SMB_ASSERT(!NT_STATUS_IS_OK(result)); + + /* Check we already aren't in the cache. We always have to have + a domain, but maybe not a specific DC name. */ + + for (fcc = failed_connection_cache; fcc; fcc = fcc->next) { + if ( strequal(fcc->domain_name, domain) && strequal(fcc->controller, server) ) + { + DEBUG(10, ("add_failed_connection_entry: domain %s (%s) already tried and failed\n", + domain, server )); + return; + } + } + + /* Create negative lookup cache entry for this domain and controller */ + + if ( !(fcc = (struct failed_connection_cache *)malloc(sizeof(struct failed_connection_cache))) ) + { + DEBUG(0, ("malloc failed in add_failed_connection_entry!\n")); + return; + } + + ZERO_STRUCTP(fcc); + + fstrcpy( fcc->domain_name, domain ); + fstrcpy( fcc->controller, server ); + fcc->lookup_time = time(NULL); + fcc->nt_status = result; + + DEBUG(10,("add_failed_connection_entry: added domain %s (%s) to failed conn cache\n", + domain, server )); + + DLIST_ADD(failed_connection_cache, fcc); +} + +/**************************************************************************** +****************************************************************************/ + +void flush_negative_conn_cache( void ) +{ + struct failed_connection_cache *fcc; + + fcc = failed_connection_cache; + + while (fcc) { + struct failed_connection_cache *fcc_next; + + fcc_next = fcc->next; + DLIST_REMOVE(failed_connection_cache, fcc); + free(fcc); + + fcc = fcc_next; + } + +} + +/**************************************************************************** + Utility function to return the name of a DC using RPC. The name is + guaranteed to be valid since we have already done a name_status_find on it + and we have checked our negative connection cache + ***************************************************************************/ + BOOL rpc_find_dc(const char *domain, fstring srv_name, struct in_addr *ip_out) { struct in_addr *ip_list = NULL, dc_ip, exclude_ip; int count, i; BOOL list_ordered; BOOL use_pdc_only; + NTSTATUS result; zero_ip(&exclude_ip); @@ -41,11 +175,15 @@ BOOL rpc_find_dc(const char *domain, fstring srv_name, struct in_addr *ip_out) /* Lookup domain controller name */ - if ( use_pdc_only && get_pdc_ip(domain, &dc_ip) ) { + if ( use_pdc_only && get_pdc_ip(domain, &dc_ip) ) + { DEBUG(10,("rpc_find_dc: Atempting to lookup PDC to avoid sam sync delays\n")); if (name_status_find(domain, 0x1c, 0x20, dc_ip, srv_name)) { - goto done; + /* makre we we haven't tried this on previously and failed */ + result = check_negative_conn_cache( domain, srv_name ); + if ( NT_STATUS_IS_OK(result) ) + goto done; } /* Didn't get name, remember not to talk to this DC. */ exclude_ip = dc_ip; @@ -77,8 +215,11 @@ BOOL rpc_find_dc(const char *domain, fstring srv_name, struct in_addr *ip_out) continue; if (name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) { - dc_ip = ip_list[i]; - goto done; + result = check_negative_conn_cache( domain, srv_name ); + if ( NT_STATUS_IS_OK(result) ) { + dc_ip = ip_list[i]; + goto done; + } } } diff --git a/source/libsmb/nmblib.c b/source/libsmb/nmblib.c index 30ce5b6b10c..b96111240f1 100644 --- a/source/libsmb/nmblib.c +++ b/source/libsmb/nmblib.c @@ -295,7 +295,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) if (name->scope[0]) { /* XXXX this scope handling needs testing */ ret += strlen(name->scope) + 1; - pstrcpy(&buf[offset+1],name->scope); + safe_strcpy(&buf[offset+1],name->scope,sizeof(name->scope)); p = &buf[offset+1]; while ((p = strchr_m(p,'.'))) { diff --git a/source/libsmb/ntlmssp.c b/source/libsmb/ntlmssp.c index d54655d17f7..636e384e657 100644 --- a/source/libsmb/ntlmssp.c +++ b/source/libsmb/ntlmssp.c @@ -487,9 +487,8 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st } SAFE_FREE(server_domain); - data_blob_free(&struct_blob); - if (challenge_blob.length != 8) { + data_blob_free(&struct_blob); return NT_STATUS_INVALID_PARAMETER; } @@ -500,9 +499,11 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st if (!SMBNTLMv2encrypt(ntlmssp_state->user, ntlmssp_state->domain, - ntlmssp_state->password, challenge_blob, + ntlmssp_state->password, &challenge_blob, + &struct_blob, &lm_response, &nt_response, &session_key)) { data_blob_free(&challenge_blob); + data_blob_free(&struct_blob); return NT_STATUS_NO_MEMORY; } } else { @@ -522,6 +523,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st session_key = data_blob(NULL, 16); SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); } + data_blob_free(&struct_blob); /* this generates the actual auth packet */ if (!msrpc_gen(next_request, auth_gen_string, diff --git a/source/libsmb/smb_signing.c b/source/libsmb/smb_signing.c index 4e9b895a1b3..eedf7f401f9 100644 --- a/source/libsmb/smb_signing.c +++ b/source/libsmb/smb_signing.c @@ -111,6 +111,9 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli) /* * Firstly put the sequence number into the first 4 bytes. * and zero out the next 4 bytes. + * + * We put the sequence into the packet, because we are going + * to copy over it anyway. */ SIVAL(cli->outbuf, smb_ss_field, data->send_seq_num); @@ -132,7 +135,7 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli) memcpy(&cli->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 signitures...*/ + Uncomment this to test if the remote server actually verifies signatures...*/ data->send_seq_num++; data->reply_seq_num = data->send_seq_num; data->send_seq_num++; @@ -155,6 +158,8 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) /* * Firstly put the sequence number into the first 4 bytes. * and zero out the next 4 bytes. + * + * We do this here, to avoid modifying the packet. */ SIVAL(sequence_buf, 0, data->reply_seq_num); @@ -163,15 +168,28 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) /* get a copy of the server-sent mac */ memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); - /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ + /* 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. + */ MD5Init(&md5_ctx); + + /* intialise with the key */ MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length); + + /* copy in the first bit of the SMB header */ MD5Update(&md5_ctx, cli->inbuf + 4, smb_ss_field - 4); + + /* copy in the sequence number, instead of the signature */ MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf)); - + + /* copy in the rest of the packet in, skipping the signature */ MD5Update(&md5_ctx, cli->inbuf + offset_end_of_sig, smb_len(cli->inbuf) - (offset_end_of_sig - 4)); + + /* caclulate the MD5 sig */ MD5Final(calc_md5_mac, &md5_ctx); good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); @@ -219,10 +237,10 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ data = smb_xmalloc(sizeof(*data)); cli->sign_info.signing_context = data; - data->mac_key = data_blob(NULL, MIN(response.length + 16, 40)); + 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, MIN(response.length, 40 - 16)); + memcpy(&data->mac_key.data[16],response.data, response.length); /* Initialise the sequence number */ data->send_seq_num = 0; diff --git a/source/libsmb/smbencrypt.c b/source/libsmb/smbencrypt.c index 28160d96094..c1b38802996 100644 --- a/source/libsmb/smbencrypt.c +++ b/source/libsmb/smbencrypt.c @@ -76,10 +76,9 @@ void E_deshash(const char *passwd, uchar p16[16]) { fstring dospwd; ZERO_STRUCT(dospwd); - ZERO_STRUCTP(p16); /* Password must be converted to DOS charset - null terminated, uppercase. */ - push_ascii(dospwd, (const char *)passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); + push_ascii(dospwd, passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); /* Only the fisrt 14 chars are considered, password need not be null terminated. */ E_P16(dospwd, p16); @@ -250,21 +249,21 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ /* Does the md5 encryption from the NT hash for NTLMv2. */ void SMBOWFencrypt_ntv2(const uchar kr[16], - const DATA_BLOB srv_chal, - const DATA_BLOB cli_chal, + const DATA_BLOB *srv_chal, + const DATA_BLOB *cli_chal, uchar resp_buf[16]) { HMACMD5Context ctx; hmac_md5_init_limK_to_64(kr, 16, &ctx); - hmac_md5_update(srv_chal.data, srv_chal.length, &ctx); - hmac_md5_update(cli_chal.data, cli_chal.length, &ctx); + hmac_md5_update(srv_chal->data, srv_chal->length, &ctx); + hmac_md5_update(cli_chal->data, cli_chal->length, &ctx); hmac_md5_final(resp_buf, &ctx); #ifdef DEBUG_PASSWORD DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n")); - dump_data(100, srv_chal.data, srv_chal.length); - dump_data(100, cli_chal.data, cli_chal.length); + dump_data(100, srv_chal->data, srv_chal->length); + dump_data(100, cli_chal->data, cli_chal->length); dump_data(100, resp_buf, 16); #endif } @@ -295,36 +294,99 @@ void SMBsesskeygen_ntv1(const uchar kr[16], #endif } -static DATA_BLOB NTLMv2_generate_response(uchar ntlm_v2_hash[16], - DATA_BLOB server_chal, size_t client_chal_length) +DATA_BLOB NTLMv2_generate_names_blob(const char *hostname, + const char *domain) +{ + DATA_BLOB names_blob = data_blob(NULL, 0); + + msrpc_gen(&names_blob, "aaa", + True, NTLMSSP_NAME_TYPE_DOMAIN, domain, + True, NTLMSSP_NAME_TYPE_SERVER, hostname, + True, 0, ""); + return names_blob; +} + +static DATA_BLOB NTLMv2_generate_client_data(const DATA_BLOB *names_blob) +{ + uchar client_chal[8]; + DATA_BLOB response = data_blob(NULL, 0); + char long_date[8]; + + generate_random_buffer(client_chal, sizeof(client_chal), False); + + put_long_date(long_date, time(NULL)); + + /* See http://www.ubiqx.org/cifs/SMB.html#SMB.8.5 */ + + msrpc_gen(&response, "ddbbdb", + 0x00000101, /* Header */ + 0, /* 'Reserved' */ + long_date, 8, /* Timestamp */ + client_chal, 8, /* client challenge */ + 0, /* Unknown */ + names_blob->data, names_blob->length); /* End of name list */ + + return response; +} + +static DATA_BLOB NTLMv2_generate_response(const uchar ntlm_v2_hash[16], + const DATA_BLOB *server_chal, + const DATA_BLOB *names_blob) { uchar ntlmv2_response[16]; DATA_BLOB ntlmv2_client_data; DATA_BLOB final_response; /* NTLMv2 */ + /* generate some data to pass into the response function - including + the hostname and domain name of the server */ + ntlmv2_client_data = NTLMv2_generate_client_data(names_blob); - /* We also get to specify some random data */ - ntlmv2_client_data = data_blob(NULL, client_chal_length); - generate_random_buffer(ntlmv2_client_data.data, ntlmv2_client_data.length, False); - /* Given that data, and the challenge from the server, generate a response */ - SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, ntlmv2_client_data, ntlmv2_response); + SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &ntlmv2_client_data, ntlmv2_response); - /* put it into nt_response, for the code below to put into the packet */ - final_response = data_blob(NULL, ntlmv2_client_data.length + sizeof(ntlmv2_response)); + final_response = data_blob(NULL, sizeof(ntlmv2_response) + ntlmv2_client_data.length); + memcpy(final_response.data, ntlmv2_response, sizeof(ntlmv2_response)); - /* after the first 16 bytes is the random data we generated above, so the server can verify us with it */ - memcpy(final_response.data + sizeof(ntlmv2_response), ntlmv2_client_data.data, ntlmv2_client_data.length); + + memcpy(final_response.data+sizeof(ntlmv2_response), + ntlmv2_client_data.data, ntlmv2_client_data.length); + data_blob_free(&ntlmv2_client_data); return final_response; } +static DATA_BLOB LMv2_generate_response(const uchar ntlm_v2_hash[16], + const DATA_BLOB *server_chal) +{ + uchar lmv2_response[16]; + DATA_BLOB lmv2_client_data = data_blob(NULL, 8); + DATA_BLOB final_response = data_blob(NULL, 24); + + /* LMv2 */ + /* client-supplied random data */ + generate_random_buffer(lmv2_client_data.data, lmv2_client_data.length, False); + + /* Given that data, and the challenge from the server, generate a response */ + SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &lmv2_client_data, lmv2_response); + memcpy(final_response.data, lmv2_response, sizeof(lmv2_response)); + + /* after the first 16 bytes is the random data we generated above, + so the server can verify us with it */ + memcpy(final_response.data+sizeof(lmv2_response), + lmv2_client_data.data, lmv2_client_data.length); + + data_blob_free(&lmv2_client_data); + + return final_response; +} + BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password, - const DATA_BLOB server_chal, + const DATA_BLOB *server_chal, + const DATA_BLOB *names_blob, DATA_BLOB *lm_response, DATA_BLOB *nt_response, - DATA_BLOB *session_key) + DATA_BLOB *nt_session_key) { uchar nt_hash[16]; uchar ntlm_v2_hash[16]; @@ -338,18 +400,24 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password return False; } - *nt_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, 64 /* pick a number, > 8 */); + if (nt_response) { + *nt_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, + names_blob); + if (nt_session_key) { + *nt_session_key = data_blob(NULL, 16); + + /* The NTLMv2 calculations also provide a session key, for signing etc later */ + /* use only the first 16 bytes of nt_response for session key */ + SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, nt_session_key->data); + } + } /* LMv2 */ - *lm_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, 8); - - *session_key = data_blob(NULL, 16); + if (lm_response) { + *lm_response = LMv2_generate_response(ntlm_v2_hash, server_chal); + } - /* The NTLMv2 calculations also provide a session key, for signing etc later */ - /* use only the first 16 bytes of nt_response for session key */ - SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, session_key->data); - return True; } diff --git a/source/locking/posix.c b/source/locking/posix.c index 2b64631d39a..6173c80b2fd 100644 --- a/source/locking/posix.c +++ b/source/locking/posix.c @@ -205,7 +205,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp) /* * No POSIX to worry about, just close. */ - ret = conn->vfs_ops.close(fsp,fsp->fd); + ret = SMB_VFS_CLOSE(fsp,fsp->fd); fsp->fd = -1; return ret; } @@ -259,7 +259,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp) DEBUG(10,("fd_close_posix: doing close on %u fd's.\n", (unsigned int)count )); for(i = 0; i < count; i++) { - if (conn->vfs_ops.close(fsp,fd_array[i]) == -1) { + if (SMB_VFS_CLOSE(fsp,fd_array[i]) == -1) { saved_errno = errno; } } @@ -278,7 +278,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp) * Finally close the fd associated with this fsp. */ - ret = conn->vfs_ops.close(fsp,fsp->fd); + ret = SMB_VFS_CLOSE(fsp,fsp->fd); if (saved_errno != 0) { errno = saved_errno; @@ -646,11 +646,10 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out, static BOOL posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type) { int ret; - struct connection_struct *conn = fsp->conn; DEBUG(8,("posix_fcntl_lock %d %d %.0f %.0f %d\n",fsp->fd,op,(double)offset,(double)count,type)); - ret = conn->vfs_ops.lock(fsp,fsp->fd,op,offset,count,type); + ret = SMB_VFS_LOCK(fsp,fsp->fd,op,offset,count,type); if (!ret && ((errno == EFBIG) || (errno == ENOLCK) || (errno == EINVAL))) { @@ -674,7 +673,7 @@ static BOOL posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OF DEBUG(0,("Count greater than 31 bits - retrying with 31 bit truncated length.\n")); errno = 0; count &= 0x7fffffff; - ret = conn->vfs_ops.lock(fsp,fsp->fd,op,offset,count,type); + ret = SMB_VFS_LOCK(fsp,fsp->fd,op,offset,count,type); } } diff --git a/source/modules/vfs_audit.c b/source/modules/vfs_audit.c index 4f9dc1b1e40..550d918b43c 100644 --- a/source/modules/vfs_audit.c +++ b/source/modules/vfs_audit.c @@ -2,8 +2,9 @@ * Auditing VFS module for samba. Log selected file operations to syslog * facility. * - * Copyright (C) Tim Potter, 1999-2000 - * Copyright (C) Alexander Bokovoy, 2002 + * Copyright (C) Tim Potter 1999-2000 + * Copyright (C) Alexander Bokovoy 2002 + * Copyright (C) Stefan (metze) Metzmacher 2002 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,118 +21,111 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "config.h" -#include <stdio.h> -#include <sys/stat.h> -#ifdef HAVE_UTIME_H -#include <utime.h> -#endif -#ifdef HAVE_DIRENT_H -#include <dirent.h> -#endif -#include <syslog.h> -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif -#include <errno.h> -#include <string.h> -#include <includes.h> -#include <vfs.h> - -#ifndef SYSLOG_FACILITY -#define SYSLOG_FACILITY LOG_USER -#endif - -#ifndef SYSLOG_PRIORITY -#define SYSLOG_PRIORITY LOG_NOTICE -#endif + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_VFS /* Function prototypes */ -static int audit_connect(struct connection_struct *conn, const char *svc, const char *user); -static void audit_disconnect(struct connection_struct *conn); -static DIR *audit_opendir(struct connection_struct *conn, const char *fname); -static int audit_mkdir(struct connection_struct *conn, const char *path, mode_t mode); -static int audit_rmdir(struct connection_struct *conn, const char *path); -static int audit_open(struct connection_struct *conn, const char *fname, int flags, mode_t mode); -static int audit_close(struct files_struct *fsp, int fd); -static int audit_rename(struct connection_struct *conn, const char *old, const char *new); -static int audit_unlink(struct connection_struct *conn, const char *path); -static int audit_chmod(struct connection_struct *conn, const char *path, mode_t mode); -static int audit_chmod_acl(struct connection_struct *conn, const char *name, mode_t mode); -static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode); -static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode); +static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user); +static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn); +static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname); +static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode); +static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path); +static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode); +static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd); +static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new); +static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path); +static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode); +static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode); +static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode); +static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode); /* VFS operations */ -static struct vfs_ops default_vfs_ops; /* For passthrough operation */ -static struct smb_vfs_handle_struct *audit_handle; - -static vfs_op_tuple audit_ops[] = { +static vfs_op_tuple audit_op_tuples[] = { /* Disk operations */ - {audit_connect, SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_LOGGER}, - {audit_disconnect, SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_disconnect), SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_LOGGER}, /* Directory operations */ - {audit_opendir, SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_LOGGER}, - {audit_mkdir, SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_LOGGER}, - {audit_rmdir, SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_mkdir), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_LOGGER}, /* File operations */ - {audit_open, SMB_VFS_OP_OPEN, SMB_VFS_LAYER_LOGGER}, - {audit_close, SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_LOGGER}, - {audit_rename, SMB_VFS_OP_RENAME, SMB_VFS_LAYER_LOGGER}, - {audit_unlink, SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_LOGGER}, - {audit_chmod, SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_LOGGER}, - {audit_fchmod, SMB_VFS_OP_FCHMOD, SMB_VFS_LAYER_LOGGER}, - {audit_chmod_acl, SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_LOGGER}, - {audit_fchmod_acl, SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_open), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_close), SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_fchmod), SMB_VFS_OP_FCHMOD, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_chmod_acl), SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_fchmod_acl), SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_LOGGER}, /* Finish VFS operations definition */ - {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} + {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} }; -/* VFS initialisation function. Return vfs_op_tuple array back to SAMBA. */ -static vfs_op_tuple *audit_init(const struct vfs_ops *def_vfs_ops, - struct smb_vfs_handle_struct *vfs_handle) +static int audit_syslog_facility(vfs_handle_struct *handle) { - memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops)); - - audit_handle = vfs_handle; + /* fix me: let this be configurable by: + * lp_param_enum(SNUM(handle->conn),(handle->param?handle->param:"audit"),"syslog facility", + * audit_enum_facility,LOG_USER); + */ + return LOG_USER; +} - openlog("smbd_audit", LOG_PID, SYSLOG_FACILITY); - syslog(SYSLOG_PRIORITY, "VFS_INIT: vfs_ops loaded\n"); - return audit_ops; + +static int audit_syslog_priority(vfs_handle_struct *handle) +{ + /* fix me: let this be configurable by: + * lp_param_enum(SNUM(handle->conn),(handle->param?handle->param:"audit"),"syslog priority", + * audit_enum_priority,LOG_NOTICE); + */ + return LOG_NOTICE; } /* Implementation of vfs_ops. Pass everything on to the default operation but log event first. */ -static int audit_connect(struct connection_struct *conn, const char *svc, const char *user) +static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user) { - syslog(SYSLOG_PRIORITY, "connect to service %s by user %s\n", + int result; + + openlog("smbd_audit", LOG_PID, audit_syslog_facility(handle)); + + syslog(audit_syslog_priority(handle), "connect to service %s by user %s\n", svc, user); - return default_vfs_ops.connect(conn, svc, user); + result = SMB_VFS_NEXT_CONNECT(handle, conn, svc, user); + + return result; } -static void audit_disconnect(struct connection_struct *conn) +static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn) { - syslog(SYSLOG_PRIORITY, "disconnected\n"); - default_vfs_ops.disconnect(conn); + syslog(audit_syslog_priority(handle), "disconnected\n"); + SMB_VFS_NEXT_DISCONNECT(handle, conn); + + return; } -static DIR *audit_opendir(struct connection_struct *conn, const char *fname) +static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname) { - DIR *result = default_vfs_ops.opendir(conn, fname); + DIR *result; + + result = SMB_VFS_NEXT_OPENDIR(handle, conn, fname); - syslog(SYSLOG_PRIORITY, "opendir %s %s%s\n", + syslog(audit_syslog_priority(handle), "opendir %s %s%s\n", fname, (result == NULL) ? "failed: " : "", (result == NULL) ? strerror(errno) : ""); @@ -139,11 +133,13 @@ static DIR *audit_opendir(struct connection_struct *conn, const char *fname) return result; } -static int audit_mkdir(struct connection_struct *conn, const char *path, mode_t mode) +static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) { - int result = default_vfs_ops.mkdir(conn, path, mode); - - syslog(SYSLOG_PRIORITY, "mkdir %s %s%s\n", + int result; + + result = SMB_VFS_NEXT_MKDIR(handle, conn, path, mode); + + syslog(audit_syslog_priority(handle), "mkdir %s %s%s\n", path, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -151,11 +147,13 @@ static int audit_mkdir(struct connection_struct *conn, const char *path, mode_t return result; } -static int audit_rmdir(struct connection_struct *conn, const char *path) +static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path) { - int result = default_vfs_ops.rmdir(conn, path); + int result; + + result = SMB_VFS_NEXT_RMDIR(handle, conn, path); - syslog(SYSLOG_PRIORITY, "rmdir %s %s%s\n", + syslog(audit_syslog_priority(handle), "rmdir %s %s%s\n", path, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -163,11 +161,13 @@ static int audit_rmdir(struct connection_struct *conn, const char *path) return result; } -static int audit_open(struct connection_struct *conn, const char *fname, int flags, mode_t mode) +static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode) { - int result = default_vfs_ops.open(conn, fname, flags, mode); + int result; + + result = SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode); - syslog(SYSLOG_PRIORITY, "open %s (fd %d) %s%s%s\n", + syslog(audit_syslog_priority(handle), "open %s (fd %d) %s%s%s\n", fname, result, ((flags & O_WRONLY) || (flags & O_RDWR)) ? "for writing " : "", (result < 0) ? "failed: " : "", @@ -176,11 +176,13 @@ static int audit_open(struct connection_struct *conn, const char *fname, int fla return result; } -static int audit_close(struct files_struct *fsp, int fd) +static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd) { - int result = default_vfs_ops.close(fsp, fd); + int result; + + result = SMB_VFS_NEXT_CLOSE(handle, fsp, fd); - syslog(SYSLOG_PRIORITY, "close fd %d %s%s\n", + syslog(audit_syslog_priority(handle), "close fd %d %s%s\n", fd, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -188,11 +190,13 @@ static int audit_close(struct files_struct *fsp, int fd) return result; } -static int audit_rename(struct connection_struct *conn, const char *old, const char *new) +static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new) { - int result = default_vfs_ops.rename(conn, old, new); + int result; + + result = SMB_VFS_NEXT_RENAME(handle, conn, old, new); - syslog(SYSLOG_PRIORITY, "rename %s -> %s %s%s\n", + syslog(audit_syslog_priority(handle), "rename %s -> %s %s%s\n", old, new, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -200,11 +204,13 @@ static int audit_rename(struct connection_struct *conn, const char *old, const c return result; } -static int audit_unlink(struct connection_struct *conn, const char *path) +static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path) { - int result = default_vfs_ops.unlink(conn, path); + int result; + + result = SMB_VFS_NEXT_UNLINK(handle, conn, path); - syslog(SYSLOG_PRIORITY, "unlink %s %s%s\n", + syslog(audit_syslog_priority(handle), "unlink %s %s%s\n", path, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -212,11 +218,13 @@ static int audit_unlink(struct connection_struct *conn, const char *path) return result; } -static int audit_chmod(struct connection_struct *conn, const char *path, mode_t mode) +static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) { - int result = default_vfs_ops.chmod(conn, path, mode); + int result; + + result = SMB_VFS_NEXT_CHMOD(handle, conn, path, mode); - syslog(SYSLOG_PRIORITY, "chmod %s mode 0x%x %s%s\n", + syslog(audit_syslog_priority(handle), "chmod %s mode 0x%x %s%s\n", path, mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -224,16 +232,13 @@ static int audit_chmod(struct connection_struct *conn, const char *path, mode_t return result; } -static int audit_chmod_acl(struct connection_struct *conn, const char *path, mode_t mode) +static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) { int result; - if ( !default_vfs_ops.chmod_acl ) - return 0; + result = SMB_VFS_NEXT_CHMOD_ACL(handle, conn, path, mode); - result = default_vfs_ops.chmod_acl(conn, path, mode); - - syslog(SYSLOG_PRIORITY, "chmod_acl %s mode 0x%x %s%s\n", + syslog(audit_syslog_priority(handle), "chmod_acl %s mode 0x%x %s%s\n", path, mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -241,11 +246,13 @@ static int audit_chmod_acl(struct connection_struct *conn, const char *path, mod return result; } -static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode) +static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode) { - int result = default_vfs_ops.fchmod(fsp, fd, mode); + int result; - syslog(SYSLOG_PRIORITY, "fchmod %s mode 0x%x %s%s\n", + result = SMB_VFS_NEXT_FCHMOD(handle, fsp, fd, mode); + + syslog(audit_syslog_priority(handle), "fchmod %s mode 0x%x %s%s\n", fsp->fsp_name, mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -253,16 +260,13 @@ static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode) return result; } -static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode) +static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode) { int result; - if ( !default_vfs_ops.fchmod_acl ) - return 0; - - result = default_vfs_ops.fchmod_acl(fsp, fd, mode); + result = SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, fd, mode); - syslog(SYSLOG_PRIORITY, "fchmod_acl %s mode 0x%x %s%s\n", + syslog(audit_syslog_priority(handle), "fchmod_acl %s mode 0x%x %s%s\n", fsp->fsp_name, mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -272,5 +276,5 @@ static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode) NTSTATUS vfs_audit_init(void) { - return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "audit", audit_init); + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "audit", audit_op_tuples); } diff --git a/source/modules/vfs_extd_audit.c b/source/modules/vfs_extd_audit.c index ef30ca70272..e677552eeae 100644 --- a/source/modules/vfs_extd_audit.c +++ b/source/modules/vfs_extd_audit.c @@ -5,6 +5,7 @@ * Copyright (C) Tim Potter, 1999-2000 * Copyright (C) Alexander Bokovoy, 2002 * Copyright (C) John H Terpstra, 2003 + * Copyright (C) Stefan (metze) Metzmacher, 2003 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,127 +22,120 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "config.h" -#include <stdio.h> -#include <sys/stat.h> -#ifdef HAVE_UTIME_H -#include <utime.h> -#endif -#ifdef HAVE_DIRENT_H -#include <dirent.h> -#endif -#include <syslog.h> -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif -#include <errno.h> -#include <string.h> -#include <includes.h> -#include <vfs.h> - -#ifndef SYSLOG_FACILITY -#define SYSLOG_FACILITY LOG_USER -#endif - -#ifndef SYSLOG_PRIORITY -#define SYSLOG_PRIORITY LOG_NOTICE -#endif + +#include "includes.h" + +static int vfs_extd_audit_debug_level = DBGC_VFS; + +#undef DBGC_CLASS +#define DBGC_CLASS vfs_extd_audit_debug_level /* Function prototypes */ -static int audit_connect(struct connection_struct *conn, const char *svc, const char *user); -static void audit_disconnect(struct connection_struct *conn); -static DIR *audit_opendir(struct connection_struct *conn, const char *fname); -static int audit_mkdir(struct connection_struct *conn, const char *path, mode_t mode); -static int audit_rmdir(struct connection_struct *conn, const char *path); -static int audit_open(struct connection_struct *conn, const char *fname, int flags, mode_t mode); -static int audit_close(struct files_struct *fsp, int fd); -static int audit_rename(struct connection_struct *conn, const char *old, const char *new); -static int audit_unlink(struct connection_struct *conn, const char *path); -static int audit_chmod(struct connection_struct *conn, const char *path, mode_t mode); -static int audit_chmod_acl(struct connection_struct *conn, const char *name, mode_t mode); -static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode); -static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode); +static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user); +static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn); +static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname); +static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode); +static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path); +static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode); +static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd); +static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new); +static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path); +static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode); +static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode); +static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode); +static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode); /* VFS operations */ -static struct vfs_ops default_vfs_ops; /* For passthrough operation */ -static struct smb_vfs_handle_struct *audit_handle; - -static vfs_op_tuple audit_ops[] = { +static vfs_op_tuple audit_op_tuples[] = { /* Disk operations */ - {audit_connect, SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_LOGGER}, - {audit_disconnect, SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_disconnect), SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_LOGGER}, /* Directory operations */ - {audit_opendir, SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_LOGGER}, - {audit_mkdir, SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_LOGGER}, - {audit_rmdir, SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_mkdir), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_LOGGER}, /* File operations */ - {audit_open, SMB_VFS_OP_OPEN, SMB_VFS_LAYER_LOGGER}, - {audit_close, SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_LOGGER}, - {audit_rename, SMB_VFS_OP_RENAME, SMB_VFS_LAYER_LOGGER}, - {audit_unlink, SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_LOGGER}, - {audit_chmod, SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_LOGGER}, - {audit_fchmod, SMB_VFS_OP_FCHMOD, SMB_VFS_LAYER_LOGGER}, - {audit_chmod_acl, SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_LOGGER}, - {audit_fchmod_acl, SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_open), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_close), SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_fchmod), SMB_VFS_OP_FCHMOD, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_chmod_acl), SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(audit_fchmod_acl), SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_LOGGER}, /* Finish VFS operations definition */ - {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} + {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} }; -/* VFS initialisation function. Return vfs_op_tuple array back to SAMBA. */ -static vfs_op_tuple *audit_init(const struct vfs_ops *def_vfs_ops, - struct smb_vfs_handle_struct *vfs_handle) +static int audit_syslog_facility(vfs_handle_struct *handle) { - memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops)); - - audit_handle = vfs_handle; + /* fix me: let this be configurable by: + * lp_param_enum(SNUM(handle->conn),(handle->param?handle->param:"extd_audit"),"syslog facility", + * audit_enum_facility,LOG_USER); + */ + return LOG_USER; +} - openlog("smbd_audit", LOG_PID, SYSLOG_FACILITY); - syslog(SYSLOG_PRIORITY, "VFS_INIT: vfs_ops loaded\n"); - return audit_ops; +static int audit_syslog_priority(vfs_handle_struct *handle) +{ + /* fix me: let this be configurable by: + * lp_param_enum(SNUM(handle->conn),(handle->param?handle->param:"extd_audit"),"syslog priority", + * audit_enum_priority,LOG_NOTICE); + */ + return LOG_NOTICE; } /* Implementation of vfs_ops. Pass everything on to the default operation but log event first. */ -static int audit_connect(struct connection_struct *conn, const char *svc, const char *user) +static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user) { - syslog(SYSLOG_PRIORITY, "connect to service %s by user %s\n", + int result; + + openlog("smbd_audit", LOG_PID, audit_syslog_facility(handle)); + + syslog(audit_syslog_priority(handle), "connect to service %s by user %s\n", svc, user); DEBUG(10, ("Connected to service %s as user %s\n", svc, user)); - return default_vfs_ops.connect(conn, svc, user); + result = SMB_VFS_NEXT_CONNECT(handle, conn, svc, user); + + return result; } -static void audit_disconnect(struct connection_struct *conn) +static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn) { - syslog(SYSLOG_PRIORITY, "disconnected\n"); + syslog(audit_syslog_priority(handle), "disconnected\n"); DEBUG(10, ("Disconnected from VFS module extd_audit\n")); + SMB_VFS_NEXT_DISCONNECT(handle, conn); - default_vfs_ops.disconnect(conn); + return; } -static DIR *audit_opendir(struct connection_struct *conn, const char *fname) +static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname) { - DIR *result = default_vfs_ops.opendir(conn, fname); + DIR *result; + + result = SMB_VFS_NEXT_OPENDIR(handle, conn, fname); - syslog(SYSLOG_PRIORITY, "opendir %s %s%s\n", + syslog(audit_syslog_priority(handle), "opendir %s %s%s\n", fname, (result == NULL) ? "failed: " : "", (result == NULL) ? strerror(errno) : ""); - DEBUG(1, ("vfs_extd_audit: opendir %s %s %s", + DEBUG(1, ("vfs_extd_audit: opendir %s %s %s\n", fname, (result == NULL) ? "failed: " : "", (result == NULL) ? strerror(errno) : "")); @@ -149,11 +143,13 @@ static DIR *audit_opendir(struct connection_struct *conn, const char *fname) return result; } -static int audit_mkdir(struct connection_struct *conn, const char *path, mode_t mode) +static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) { - int result = default_vfs_ops.mkdir(conn, path, mode); - - syslog(SYSLOG_PRIORITY, "mkdir %s %s%s\n", + int result; + + result = SMB_VFS_NEXT_MKDIR(handle, conn, path, mode); + + syslog(audit_syslog_priority(handle), "mkdir %s %s%s\n", path, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -165,11 +161,13 @@ static int audit_mkdir(struct connection_struct *conn, const char *path, mode_t return result; } -static int audit_rmdir(struct connection_struct *conn, const char *path) +static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path) { - int result = default_vfs_ops.rmdir(conn, path); + int result; + + result = SMB_VFS_NEXT_RMDIR(handle, conn, path); - syslog(SYSLOG_PRIORITY, "rmdir %s %s%s\n", + syslog(audit_syslog_priority(handle), "rmdir %s %s%s\n", path, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -181,11 +179,13 @@ static int audit_rmdir(struct connection_struct *conn, const char *path) return result; } -static int audit_open(struct connection_struct *conn, const char *fname, int flags, mode_t mode) +static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode) { - int result = default_vfs_ops.open(conn, fname, flags, mode); + int result; + + result = SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode); - syslog(SYSLOG_PRIORITY, "open %s (fd %d) %s%s%s\n", + syslog(audit_syslog_priority(handle), "open %s (fd %d) %s%s%s\n", fname, result, ((flags & O_WRONLY) || (flags & O_RDWR)) ? "for writing " : "", (result < 0) ? "failed: " : "", @@ -198,11 +198,13 @@ static int audit_open(struct connection_struct *conn, const char *fname, int fla return result; } -static int audit_close(struct files_struct *fsp, int fd) +static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd) { - int result = default_vfs_ops.close(fsp, fd); + int result; + + result = SMB_VFS_NEXT_CLOSE(handle, fsp, fd); - syslog(SYSLOG_PRIORITY, "close fd %d %s%s\n", + syslog(audit_syslog_priority(handle), "close fd %d %s%s\n", fd, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -214,11 +216,13 @@ static int audit_close(struct files_struct *fsp, int fd) return result; } -static int audit_rename(struct connection_struct *conn, const char *old, const char *new) +static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new) { - int result = default_vfs_ops.rename(conn, old, new); + int result; + + result = SMB_VFS_NEXT_RENAME(handle, conn, old, new); - syslog(SYSLOG_PRIORITY, "rename %s -> %s %s%s\n", + syslog(audit_syslog_priority(handle), "rename %s -> %s %s%s\n", old, new, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -230,11 +234,13 @@ static int audit_rename(struct connection_struct *conn, const char *old, const c return result; } -static int audit_unlink(struct connection_struct *conn, const char *path) +static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path) { - int result = default_vfs_ops.unlink(conn, path); + int result; + + result = SMB_VFS_NEXT_UNLINK(handle, conn, path); - syslog(SYSLOG_PRIORITY, "unlink %s %s%s\n", + syslog(audit_syslog_priority(handle), "unlink %s %s%s\n", path, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -246,11 +252,13 @@ static int audit_unlink(struct connection_struct *conn, const char *path) return result; } -static int audit_chmod(struct connection_struct *conn, const char *path, mode_t mode) +static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) { - int result = default_vfs_ops.chmod(conn, path, mode); + int result; - syslog(SYSLOG_PRIORITY, "chmod %s mode 0x%x %s%s\n", + result = SMB_VFS_NEXT_CHMOD(handle, conn, path, mode); + + syslog(audit_syslog_priority(handle), "chmod %s mode 0x%x %s%s\n", path, mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -262,11 +270,13 @@ static int audit_chmod(struct connection_struct *conn, const char *path, mode_t return result; } -static int audit_chmod_acl(struct connection_struct *conn, const char *path, mode_t mode) +static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) { - int result = default_vfs_ops.chmod_acl(conn, path, mode); + int result; + + result = SMB_VFS_NEXT_CHMOD_ACL(handle, conn, path, mode); - syslog(SYSLOG_PRIORITY, "chmod_acl %s mode 0x%x %s%s\n", + syslog(audit_syslog_priority(handle), "chmod_acl %s mode 0x%x %s%s\n", path, mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -278,11 +288,13 @@ static int audit_chmod_acl(struct connection_struct *conn, const char *path, mod return result; } -static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode) +static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode) { - int result = default_vfs_ops.fchmod(fsp, fd, mode); + int result; + + result = SMB_VFS_NEXT_FCHMOD(handle, fsp, fd, mode); - syslog(SYSLOG_PRIORITY, "fchmod %s mode 0x%x %s%s\n", + syslog(audit_syslog_priority(handle), "fchmod %s mode 0x%x %s%s\n", fsp->fsp_name, mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -294,11 +306,13 @@ static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode) return result; } -static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode) +static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode) { - int result = default_vfs_ops.fchmod_acl(fsp, fd, mode); + int result; + + result = SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, fd, mode); - syslog(SYSLOG_PRIORITY, "fchmod_acl %s mode 0x%x %s%s\n", + syslog(audit_syslog_priority(handle), "fchmod_acl %s mode 0x%x %s%s\n", fsp->fsp_name, mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -312,5 +326,18 @@ static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode) NTSTATUS vfs_extd_audit_init(void) { - return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "extd_audit", audit_init); + NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "extd_audit", audit_op_tuples); + + if (NT_STATUS_IS_ERR(ret)) + return ret; + + vfs_extd_audit_debug_level = debug_add_class("extd_audit"); + if (vfs_extd_audit_debug_level == -1) { + vfs_extd_audit_debug_level = DBGC_VFS; + DEBUG(0, ("vfs_extd_audit: Couldn't register custom debugging class!\n")); + } else { + DEBUG(10, ("vfs_extd_audit: Debug class number of 'extd_audit': %d\n", vfs_extd_audit_debug_level)); + } + + return ret; } diff --git a/source/modules/vfs_fake_perms.c b/source/modules/vfs_fake_perms.c index 3a18fbb730c..740218dcd41 100644 --- a/source/modules/vfs_fake_perms.c +++ b/source/modules/vfs_fake_perms.c @@ -22,31 +22,16 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "config.h" +#include "includes.h" -#include <stdio.h> -#include <sys/stat.h> -#ifdef HAVE_UTIME_H -#include <utime.h> -#endif -#ifdef HAVE_DIRENT_H -#include <dirent.h> -#endif -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif -#include <errno.h> -#include <string.h> +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_VFS -#include <includes.h> -#include <vfs.h> - -static struct vfs_ops default_vfs_ops; /* For passthrough operation */ -static struct smb_vfs_handle_struct *fake_perms_handle; /* use fake_perms_handle->data for storing per-instance private data */ - -static int fake_perms_stat(struct connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf) +static int fake_perms_stat(vfs_handle_struct *handle, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf) { - int ret = default_vfs_ops.stat(conn, fname, sbuf); + int ret = -1; + + ret = SMB_VFS_NEXT_STAT(handle, conn, fname, sbuf); if (ret == 0) { extern struct current_user current_user; @@ -58,12 +43,15 @@ static int fake_perms_stat(struct connection_struct *conn, const char *fname, SM sbuf->st_uid = current_user.uid; sbuf->st_gid = current_user.gid; } + return ret; } -static int fake_perms_fstat(struct files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf) +static int fake_perms_fstat(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf) { - int ret = default_vfs_ops.fstat(fsp, fd, sbuf); + int ret = -1; + + ret = SMB_VFS_NEXT_FSTAT(handle, fsp, fd, sbuf); if (ret == 0) { extern struct current_user current_user; @@ -78,210 +66,16 @@ static int fake_perms_fstat(struct files_struct *fsp, int fd, SMB_STRUCT_STAT *s return ret; } -#if 0 -static size_t fake_perms_fget_nt_acl(struct files_struct *fsp, int fd, struct security_descriptor_info **ppdesc) -{ - return default_vfs_ops.fget_nt_acl(fsp, fd, ppdesc); -} - -static size_t fake_perms_get_nt_acl(struct files_struct *fsp, const char *name, struct security_descriptor_info **ppdesc) -{ - return default_vfs_ops.get_nt_acl(fsp, name, ppdesc); -} - -static BOOL fake_perms_fset_nt_acl(struct files_struct *fsp, int fd, uint32 security_info_sent, struct security_descriptor_info *psd) -{ - return default_vfs_ops.fset_nt_acl(fsp, fd, security_info_sent, psd); -} - -static BOOL fake_perms_set_nt_acl(struct files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor_info *psd) -{ - return default_vfs_ops.set_nt_acl(fsp, name, security_info_sent, psd); -} - -static BOOL fake_perms_chmod_acl(struct connection_struct *conn, const char *name, mode_t mode) -{ - return default_vfs_ops.chmod_acl(conn, name, mode); -} - -static BOOL fake_perms_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode) -{ - return default_vfs_ops.fchmod_acl(fsp, fd, mode); -} - -static int fake_perms_sys_acl_get_entry(struct connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p) -{ - return default_vfs_ops.sys_acl_get_entry(conn, theacl, entry_id, entry_p); -} - -static int fake_perms_sys_acl_get_tag_type(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p) -{ - return default_vfs_ops.sys_acl_get_tag_type(conn, entry_d, tag_type_p); -} - -static int fake_perms_sys_acl_get_permset(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p) -{ - return default_vfs_ops.sys_acl_get_permset(conn, entry_d, permset_p); -} - -static void *fake_perms_sys_acl_get_qualifier(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d) -{ - return default_vfs_ops.sys_acl_get_qualifier(conn, entry_d); -} - -static SMB_ACL_T fake_perms_sys_acl_get_file(struct connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type) -{ - return default_vfs_ops.sys_acl_get_file(conn, path_p, type); -} - -static SMB_ACL_T fake_perms_sys_acl_get_fd(struct files_struct *fsp, int fd) -{ - return default_vfs_ops.sys_acl_get_fd(fsp, fd); -} - -static int fake_perms_sys_acl_clear_perms(struct connection_struct *conn, SMB_ACL_PERMSET_T permset) -{ - return default_vfs_ops.sys_acl_clear_perms(conn, permset); -} - -static int fake_perms_sys_acl_add_perm(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) -{ - return default_vfs_ops.sys_acl_add_perm(conn, permset, perm); -} - -static char *fake_perms_sys_acl_to_text(struct connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen) -{ - return default_vfs_ops.sys_acl_to_text(conn, theacl, plen); -} - -static SMB_ACL_T fake_perms_sys_acl_init(struct connection_struct *conn, int count) -{ - return default_vfs_ops.sys_acl_init(conn, count); -} - -static int fake_perms_sys_acl_create_entry(struct connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry) -{ - return default_vfs_ops.sys_acl_create_entry(conn, pacl, pentry); -} - -static int fake_perms_sys_acl_set_tag_type(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype) -{ - return default_vfs_ops.sys_acl_set_tag_type(conn, entry, tagtype); -} - -static int fake_perms_sys_acl_set_qualifier(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual) -{ - return default_vfs_ops.sys_acl_set_qualifier(conn, entry, qual); -} - -static int fake_perms_sys_acl_set_permset(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset) -{ - return default_vfs_ops.sys_acl_set_permset(conn, entry, permset); -} - -static int fake_perms_sys_acl_valid(struct connection_struct *conn, SMB_ACL_T theacl ) -{ - return default_vfs_ops.sys_acl_valid(conn, theacl ); -} - -static int fake_perms_sys_acl_set_file(struct connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) -{ - return default_vfs_ops.sys_acl_set_file(conn, name, acltype, theacl); -} - -static int fake_perms_sys_acl_set_fd(struct files_struct *fsp, int fd, SMB_ACL_T theacl) -{ - return default_vfs_ops.sys_acl_set_fd(fsp, fd, theacl); -} - -static int fake_perms_sys_acl_delete_def_file(struct connection_struct *conn, const char *path) -{ - return default_vfs_ops.sys_acl_delete_def_file(conn, path); -} - -static int fake_perms_sys_acl_get_perm(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) -{ - return default_vfs_ops.sys_acl_get_perm(conn, permset, perm); -} - -static int fake_perms_sys_acl_free_text(struct connection_struct *conn, char *text) -{ - return default_vfs_ops.sys_acl_free_text(conn, text); -} - -static int fake_perms_sys_acl_free_acl(struct connection_struct *conn, SMB_ACL_T posix_acl) -{ - return default_vfs_ops.sys_acl_free_acl(conn, posix_acl); -} - -static int fake_perms_sys_acl_free_qualifier(struct connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype) -{ - return default_vfs_ops.sys_acl_free_qualifier(conn, qualifier, tagtype); -} -#endif - /* VFS operations structure */ -static vfs_op_tuple fake_perms_ops[] = { - - /* NT File ACL operations */ -#if 0 - {fake_perms_fget_nt_acl, SMB_VFS_OP_FGET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_get_nt_acl, SMB_VFS_OP_GET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_fset_nt_acl, SMB_VFS_OP_FSET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_set_nt_acl, SMB_VFS_OP_SET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT}, - - /* POSIX ACL operations */ +static vfs_op_tuple fake_perms_ops[] = { + {SMB_VFS_OP(fake_perms_stat), SMB_VFS_OP_STAT, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(fake_perms_fstat), SMB_VFS_OP_FSTAT, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_chmod_acl, SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_fchmod_acl, SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_TRANSPARENT}, - - {fake_perms_sys_acl_get_entry, SMB_VFS_OP_SYS_ACL_GET_ENTRY, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_get_tag_type, SMB_VFS_OP_SYS_ACL_GET_TAG_TYPE, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_get_permset, SMB_VFS_OP_SYS_ACL_GET_PERMSET, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_get_qualifier, SMB_VFS_OP_SYS_ACL_GET_QUALIFIER, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_get_file, SMB_VFS_OP_SYS_ACL_GET_FILE, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_get_fd, SMB_VFS_OP_SYS_ACL_GET_FD, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_clear_perms, SMB_VFS_OP_SYS_ACL_CLEAR_PERMS, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_add_perm, SMB_VFS_OP_SYS_ACL_ADD_PERM, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_to_text, SMB_VFS_OP_SYS_ACL_TO_TEXT, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_init, SMB_VFS_OP_SYS_ACL_INIT, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_create_entry, SMB_VFS_OP_SYS_ACL_CREATE_ENTRY, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_set_tag_type, SMB_VFS_OP_SYS_ACL_SET_TAG_TYPE, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_set_qualifier, SMB_VFS_OP_SYS_ACL_SET_QUALIFIER, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_set_permset, SMB_VFS_OP_SYS_ACL_SET_PERMSET, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_valid, SMB_VFS_OP_SYS_ACL_VALID, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_set_file, SMB_VFS_OP_SYS_ACL_SET_FILE, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_set_fd, SMB_VFS_OP_SYS_ACL_SET_FD, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_delete_def_file, SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_get_perm, SMB_VFS_OP_SYS_ACL_GET_PERM, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_free_text, SMB_VFS_OP_SYS_ACL_FREE_TEXT, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_free_acl, SMB_VFS_OP_SYS_ACL_FREE_ACL, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_free_qualifier, SMB_VFS_OP_SYS_ACL_FREE_QUALIFIER, SMB_VFS_LAYER_TRANSPARENT}, -#endif - - {fake_perms_stat, SMB_VFS_OP_STAT, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_fstat, SMB_VFS_OP_FSTAT, SMB_VFS_LAYER_TRANSPARENT}, - {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} + {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} }; -/* VFS initialisation - return initialized vfs_op_tuple array back to Samba */ - -static vfs_op_tuple *fake_perms_init(const struct vfs_ops *def_vfs_ops, - struct smb_vfs_handle_struct *vfs_handle) -{ - DEBUG(3, ("Initialising default vfs hooks\n")); - - memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops)); - - /* Remember vfs_handle for further allocation and referencing of private - information in vfs_handle->data - */ - fake_perms_handle = vfs_handle; - return fake_perms_ops; -} - NTSTATUS vfs_fake_perms_init(void) { - return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "fake_perms", fake_perms_init); + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "fake_perms", fake_perms_ops); } diff --git a/source/modules/vfs_netatalk.c b/source/modules/vfs_netatalk.c index 718bc2a35ca..ae6286e292d 100644 --- a/source/modules/vfs_netatalk.c +++ b/source/modules/vfs_netatalk.c @@ -2,6 +2,7 @@ * AppleTalk VFS module for Samba-3.x * * Copyright (C) Alexei Kotovich, 2002 + * Copyright (C) Stefan (metze) Metzmacher, 2003 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,22 +19,10 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "config.h" -#include <stdio.h> -#include <sys/stat.h> -#ifdef HAVE_UTIME_H -#include <utime.h> -#endif -#ifdef HAVE_DIRENT_H -#include <dirent.h> -#endif -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif -#include <errno.h> -#include <string.h> -#include <includes.h> -#include <vfs.h> +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_VFS #define APPLEDOUBLE ".AppleDouble" #define ADOUBLEMODE 0777 @@ -46,9 +35,6 @@ static int atalk_build_paths(TALLOC_CTX *ctx, const char *path, static int atalk_unlink_file(const char *path); -static struct vfs_ops default_vfs_ops; /* For passthrough operation */ -static struct smb_vfs_handle_struct *atalk_handle; - static int atalk_get_path_ptr(char *path) { int i = 0; @@ -187,11 +173,11 @@ static void atalk_rrmdir(TALLOC_CTX *ctx, char *path) /* Directory operations */ -DIR *atalk_opendir(struct connection_struct *conn, const char *fname) +DIR *atalk_opendir(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname) { DIR *ret = 0; - - ret = default_vfs_ops.opendir(conn, fname); + + ret = SMB_VFS_NEXT_OPENDIR(handle, conn, fname); /* * when we try to perform delete operation upon file which has fork @@ -208,7 +194,7 @@ DIR *atalk_opendir(struct connection_struct *conn, const char *fname) return ret; } -static int atalk_rmdir(struct connection_struct *conn, const char *path) +static int atalk_rmdir(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path) { BOOL add = False; TALLOC_CTX *ctx = 0; @@ -233,12 +219,12 @@ static int atalk_rmdir(struct connection_struct *conn, const char *path) exit_rmdir: talloc_destroy(ctx); - return default_vfs_ops.rmdir(conn, path); + return SMB_VFS_NEXT_RMDIR(handle, conn, path); } /* File operations */ -static int atalk_rename(struct connection_struct *conn, const char *old, const char *new) +static int atalk_rename(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *old, const char *new) { int ret = 0; char *adbl_path = 0; @@ -247,7 +233,7 @@ static int atalk_rename(struct connection_struct *conn, const char *old, const c SMB_STRUCT_STAT orig_info; TALLOC_CTX *ctx; - ret = default_vfs_ops.rename(conn, old, new); + ret = SMB_VFS_NEXT_RENAME(handle, conn, old, new); if (!conn || !old) return ret; @@ -270,7 +256,7 @@ exit_rename: return ret; } -static int atalk_unlink(struct connection_struct *conn, const char *path) +static int atalk_unlink(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path) { int ret = 0, i; char *adbl_path = 0; @@ -279,7 +265,7 @@ static int atalk_unlink(struct connection_struct *conn, const char *path) SMB_STRUCT_STAT orig_info; TALLOC_CTX *ctx; - ret = default_vfs_ops.unlink(conn, path); + ret = SMB_VFS_NEXT_UNLINK(handle, conn, path); if (!conn || !path) return ret; @@ -326,7 +312,7 @@ exit_unlink: return ret; } -static int atalk_chmod(struct connection_struct *conn, const char *path, mode_t mode) +static int atalk_chmod(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, mode_t mode) { int ret = 0; char *adbl_path = 0; @@ -335,7 +321,7 @@ static int atalk_chmod(struct connection_struct *conn, const char *path, mode_t SMB_STRUCT_STAT orig_info; TALLOC_CTX *ctx; - ret = default_vfs_ops.chmod(conn, path, mode); + ret = SMB_VFS_NEXT_CHMOD(handle, conn, path, mode); if (!conn || !path) return ret; @@ -358,7 +344,7 @@ exit_chmod: return ret; } -static int atalk_chown(struct connection_struct *conn, const char *path, uid_t uid, gid_t gid) +static int atalk_chown(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, uid_t uid, gid_t gid) { int ret = 0; char *adbl_path = 0; @@ -367,7 +353,7 @@ static int atalk_chown(struct connection_struct *conn, const char *path, uid_t u SMB_STRUCT_STAT orig_info; TALLOC_CTX *ctx; - ret = default_vfs_ops.chown(conn, path, uid, gid); + ret = SMB_VFS_NEXT_CHOWN(handle, conn, path, uid, gid); if (!conn || !path) return ret; @@ -394,34 +380,22 @@ static vfs_op_tuple atalk_ops[] = { /* Directory operations */ - {atalk_opendir, SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT}, - {atalk_rmdir, SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(atalk_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(atalk_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT}, /* File operations */ - {atalk_rename, SMB_VFS_OP_RENAME, SMB_VFS_LAYER_TRANSPARENT}, - {atalk_unlink, SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT}, - {atalk_chmod, SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_TRANSPARENT}, - {atalk_chown, SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(atalk_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(atalk_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(atalk_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(atalk_chown), SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_TRANSPARENT}, /* Finish VFS operations definition */ - {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} + {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} }; -/* VFS initialisation function. Return vfs_op_tuple array back to SAMBA. */ -static vfs_op_tuple *netatalk_init(const struct vfs_ops *def_vfs_ops, - struct smb_vfs_handle_struct *vfs_handle) -{ - memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops)); - - atalk_handle = vfs_handle; - - DEBUG(3, ("ATALK: vfs module loaded\n")); - return atalk_ops; -} - NTSTATUS vfs_netatalk_init(void) { - return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "netatalk", netatalk_init); + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "netatalk", atalk_ops); } diff --git a/source/modules/vfs_recycle.c b/source/modules/vfs_recycle.c index 87dea944ac0..45c661edb7a 100644 --- a/source/modules/vfs_recycle.c +++ b/source/modules/vfs_recycle.c @@ -6,6 +6,7 @@ * Copyright (C) 2002, Alexander Bokovoy - cascaded VFS adoption, * Copyright (C) 2002, Juergen Hasch - added some options. * Copyright (C) 2002, Simo Sorce + * Copyright (C) 2002, Stefan (metze) Metzmacher * * 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 @@ -30,231 +31,133 @@ static int vfs_recycle_debug_level = DBGC_VFS; #undef DBGC_CLASS #define DBGC_CLASS vfs_recycle_debug_level - -static const char *delimiter = "|"; /* delimiter for options */ - -/* One per connection */ - -typedef struct recycle_bin_struct -{ - TALLOC_CTX *mem_ctx; - char *repository; /* name of the recycle bin directory */ - BOOL keep_dir_tree; /* keep directory structure of deleted file in recycle bin */ - BOOL versions; /* create versions of deleted files with identical name */ - BOOL touch; /* touch access date of deleted file */ - char *exclude; /* which files to exclude */ - char *exclude_dir; /* which directories to exclude */ - char *noversions; /* which files to exclude from versioning */ - SMB_OFF_T maxsize; /* maximum file size to be saved */ -} recycle_bin_struct; - -typedef struct recycle_bin_connections { - int conn; - recycle_bin_struct *data; - struct recycle_bin_connections *next; -} recycle_bin_connections; - -typedef struct recycle_bin_private_data { - TALLOC_CTX *mem_ctx; - recycle_bin_connections *conns; -} recycle_bin_private_data; - -struct smb_vfs_handle_struct *recycle_bin_private_handle; - -/* VFS operations */ -static struct vfs_ops default_vfs_ops; /* For passthrough operation */ - -static int recycle_connect(struct connection_struct *conn, const char *service, const char *user); -static void recycle_disconnect(struct connection_struct *conn); -static int recycle_unlink(connection_struct *, const char *); - -#define VFS_OP(x) ((void *) x) + +static int recycle_connect(vfs_handle_struct *handle, connection_struct *conn, const char *service, const char *user); +static void recycle_disconnect(vfs_handle_struct *handle, connection_struct *conn); +static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *name); static vfs_op_tuple recycle_ops[] = { /* Disk operations */ - {VFS_OP(recycle_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT}, - {VFS_OP(recycle_disconnect), SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(recycle_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(recycle_disconnect), SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_TRANSPARENT}, /* File operations */ - {VFS_OP(recycle_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(recycle_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT}, - {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} + {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} }; -/** - * VFS initialisation function. - * - * @retval initialised vfs_op_tuple array - **/ -static vfs_op_tuple *recycle_init(const struct vfs_ops *def_vfs_ops, - struct smb_vfs_handle_struct *vfs_handle) +static int recycle_connect(vfs_handle_struct *handle, connection_struct *conn, const char *service, const char *user) { - TALLOC_CTX *mem_ctx = NULL; + DEBUG(10,("recycle_connect() connect to service[%s] as user[%s].\n", + service,user)); - DEBUG(10, ("Initializing VFS module recycle\n")); - memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops)); - vfs_recycle_debug_level = debug_add_class("vfs_recycle_bin"); - if (vfs_recycle_debug_level == -1) { - vfs_recycle_debug_level = DBGC_VFS; - DEBUG(0, ("vfs_recycle: Couldn't register custom debugging class!\n")); - } else { - DEBUG(0, ("vfs_recycle: Debug class number of 'vfs_recycle': %d\n", vfs_recycle_debug_level)); - } - - recycle_bin_private_handle = vfs_handle; - if (!(mem_ctx = talloc_init("recycle bin data"))) { - DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n")); - return NULL; - } + return SMB_VFS_NEXT_CONNECT(handle, conn, service, user); +} - recycle_bin_private_handle->data = talloc(mem_ctx, sizeof(recycle_bin_private_data)); - if (recycle_bin_private_handle->data == NULL) { - DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n")); - return NULL; - } - ((recycle_bin_private_data *)(recycle_bin_private_handle->data))->mem_ctx = mem_ctx; - ((recycle_bin_private_data *)(recycle_bin_private_handle->data))->conns = NULL; +static void recycle_disconnect(vfs_handle_struct *handle, connection_struct *conn) +{ + DEBUG(10,("recycle_disconnect() connect to service[%s].\n", + lp_servicename(SNUM(conn)))); - return recycle_ops; + SMB_VFS_NEXT_DISCONNECT(handle, conn); } -static int recycle_connect(struct connection_struct *conn, const char *service, const char *user) +static const char *recycle_repository(vfs_handle_struct *handle) { - TALLOC_CTX *ctx = NULL; - recycle_bin_struct *recbin; - recycle_bin_connections *recconn; - recycle_bin_connections *recconnbase; - recycle_bin_private_data *recdata; - const char *tmp_str; + const char *tmp_str = NULL; + - DEBUG(10, ("Called for service %s (%d) as user %s\n", service, SNUM(conn), user)); + tmp_str = lp_parm_const_string(SNUM(handle->conn), "recycle", "repository",".recycle"); - if (recycle_bin_private_handle) - recdata = (recycle_bin_private_data *)(recycle_bin_private_handle->data); - else { - DEBUG(0, ("Recycle bin not initialized!\n")); - return -1; - } + DEBUG(10, ("recycle: repository = %s\n", tmp_str)); + + return tmp_str; +} - if (!(ctx = talloc_init("recycle bin connection"))) { - DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n")); - return -1; - } +static BOOL recycle_keep_dir_tree(vfs_handle_struct *handle) +{ + BOOL ret; + + ret = lp_parm_bool(SNUM(handle->conn), "recycle", "keeptree", False); - recbin = talloc_zero(ctx, sizeof(recycle_bin_struct)); - if (recbin == NULL) { - DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n")); - return -1; - } - recbin->mem_ctx = ctx; - - /* parse configuration options */ - if ((tmp_str = lp_parm_const_string(SNUM(conn), "vfs_recycle_bin", "repository", ".recycle")) != NULL) { - recbin->repository = talloc_sub_conn(recbin->mem_ctx, conn, tmp_str); - ALLOC_CHECK(recbin->repository, error); - trim_string(recbin->repository, "/", "/"); - DEBUG(5, ("recycle.bin: repository = %s\n", recbin->repository)); - } else { - DEBUG(0,("recycle.bin: no repository found (fail) !\n")); - goto error; - } + DEBUG(10, ("recycle_bin: keeptree = %s\n", ret?"True":"False")); - recbin->keep_dir_tree = lp_parm_bool(SNUM(conn), "vfs_recycle_bin", "keeptree", False); - DEBUG(5, ("recycle.bin: keeptree = %d\n", recbin->keep_dir_tree)); + return ret; +} + +static BOOL recycle_versions(vfs_handle_struct *handle) +{ + BOOL ret; + + ret = lp_parm_bool(SNUM(handle->conn), "recycle", "versions", False); + + DEBUG(10, ("recycle: versions = %s\n", ret?"True":"False")); - recbin->versions = lp_parm_bool(SNUM(conn), "vfs_recycle_bin", "versions", False); - DEBUG(5, ("recycle.bin: versions = %d\n", recbin->versions)); + return ret; +} + +static BOOL recycle_touch(vfs_handle_struct *handle) +{ + BOOL ret; + + ret = lp_parm_bool(SNUM(handle->conn), "recycle", "touch", False); + + DEBUG(10, ("recycle: touch = %s\n", ret?"True":"False")); - recbin->touch = lp_parm_bool(SNUM(conn), "vfs_recycle_bin", "touch", False); - DEBUG(5, ("recycle.bin: touch = %d\n", recbin->touch)); + return ret; +} - recbin->maxsize = lp_parm_ulong(SNUM(conn), "vfs_recycle_bin", "maxsize" , 0); - if (recbin->maxsize == 0) { - recbin->maxsize = -1; - DEBUG(5, ("recycle.bin: maxsize = -infinite-\n")); - } else { - DEBUG(5, ("recycle.bin: maxsize = %ld\n", (long int)recbin->maxsize)); - } +static const char **recycle_exclude(vfs_handle_struct *handle) +{ + const char **tmp_lp; + + tmp_lp = lp_parm_string_list(SNUM(handle->conn), "recycle", "exclude", NULL); - if ((tmp_str = lp_parm_const_string(SNUM(conn), "vfs_recycle_bin", "exclude", "")) != NULL) { - recbin->exclude = talloc_strdup(recbin->mem_ctx, tmp_str); - ALLOC_CHECK(recbin->exclude, error); - DEBUG(5, ("recycle.bin: exclude = %s\n", recbin->exclude)); - } - if ((tmp_str = lp_parm_const_string(SNUM(conn), "vfs_recycle_bin", "exclude_dir", "")) != NULL) { - recbin->exclude_dir = talloc_strdup(recbin->mem_ctx, tmp_str); - ALLOC_CHECK(recbin->exclude_dir, error); - DEBUG(5, ("recycle.bin: exclude_dir = %s\n", recbin->exclude_dir)); - } - if ((tmp_str = lp_parm_const_string(SNUM(conn), "vfs_recycle_bin", "noversions", "")) != NULL) { - recbin->noversions = talloc_strdup(recbin->mem_ctx, tmp_str); - ALLOC_CHECK(recbin->noversions, error); - DEBUG(5, ("recycle.bin: noversions = %s\n", recbin->noversions)); - } + DEBUG(10, ("recycle: exclude = %s ...\n", tmp_lp?*tmp_lp:"")); + + return tmp_lp; +} - recconn = talloc(recdata->mem_ctx, sizeof(recycle_bin_connections)); - if (recconn == NULL) { - DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n")); - goto error; - } - recconn->conn = SNUM(conn); - recconn->data = recbin; - recconn->next = NULL; - if (recdata->conns) { - recconnbase = recdata->conns; - while (recconnbase->next != NULL) recconnbase = recconnbase->next; - recconnbase->next = recconn; - } else { - recdata->conns = recconn; - } - return default_vfs_ops.connect(conn, service, user); +static const char **recycle_exclude_dir(vfs_handle_struct *handle) +{ + const char **tmp_lp; + + tmp_lp = lp_parm_string_list(SNUM(handle->conn), "recycle", "exclude_dir", NULL); -error: - talloc_destroy(ctx); - return -1; + DEBUG(10, ("recycle: exclude_dir = %s ...\n", tmp_lp?*tmp_lp:"")); + + return tmp_lp; } -static void recycle_disconnect(struct connection_struct *conn) +static const char **recycle_noversions(vfs_handle_struct *handle) { - recycle_bin_private_data *recdata; - recycle_bin_connections *recconn; + const char **tmp_lp; + + tmp_lp = lp_parm_string_list(SNUM(handle->conn), "recycle", "noversions", NULL); - DEBUG(10, ("Disconnecting VFS module recycle bin\n")); + DEBUG(10, ("recycle: noversions = %s\n", tmp_lp?*tmp_lp:"")); + + return tmp_lp; +} - if (recycle_bin_private_handle) - recdata = (recycle_bin_private_data *)(recycle_bin_private_handle->data); - else { - DEBUG(0, ("Recycle bin not initialized!\n")); - return; - } +static int recycle_maxsize(vfs_handle_struct *handle) +{ + int maxsize; + + maxsize = lp_parm_int(SNUM(handle->conn), "recycle", "maxsize", -1); - if (recdata) { - if (recdata->conns) { - if (recdata->conns->conn == SNUM(conn)) { - talloc_destroy(recdata->conns->data->mem_ctx); - recdata->conns = recdata->conns->next; - } else { - recconn = recdata->conns; - while (recconn->next) { - if (recconn->next->conn == SNUM(conn)) { - talloc_destroy(recconn->next->data->mem_ctx); - recconn->next = recconn->next->next; - break; - } - recconn = recconn->next; - } - } - } - } - default_vfs_ops.disconnect(conn); + DEBUG(10, ("recycle: maxsize = %d\n", maxsize)); + + return maxsize; } -static BOOL recycle_directory_exist(connection_struct *conn, const char *dname) +static BOOL recycle_directory_exist(vfs_handle_struct *handle, const char *dname) { SMB_STRUCT_STAT st; - if (default_vfs_ops.stat(conn, dname, &st) == 0) { + if (SMB_VFS_NEXT_STAT(handle, handle->conn, dname, &st) == 0) { if (S_ISDIR(st.st_mode)) { return True; } @@ -263,11 +166,11 @@ static BOOL recycle_directory_exist(connection_struct *conn, const char *dname) return False; } -static BOOL recycle_file_exist(connection_struct *conn, const char *fname) +static BOOL recycle_file_exist(vfs_handle_struct *handle, const char *fname) { SMB_STRUCT_STAT st; - if (default_vfs_ops.stat(conn, fname, &st) == 0) { + if (SMB_VFS_NEXT_STAT(handle, handle->conn, fname, &st) == 0) { if (S_ISREG(st.st_mode)) { return True; } @@ -282,13 +185,15 @@ static BOOL recycle_file_exist(connection_struct *conn, const char *fname) * @param fname file name * @return size in bytes **/ -static SMB_OFF_T recycle_get_file_size(connection_struct *conn, const char *fname) +static SMB_OFF_T recycle_get_file_size(vfs_handle_struct *handle, const char *fname) { SMB_STRUCT_STAT st; - if (default_vfs_ops.stat(conn, fname, &st) != 0) { - DEBUG(0,("recycle.bin: stat for %s returned %s\n", fname, strerror(errno))); + + if (SMB_VFS_NEXT_STAT(handle, handle->conn, fname, &st) != 0) { + DEBUG(0,("recycle: stat for %s returned %s\n", fname, strerror(errno))); return (SMB_OFF_T)0; } + return(st.st_size); } @@ -298,7 +203,7 @@ static SMB_OFF_T recycle_get_file_size(connection_struct *conn, const char *fnam * @param dname Directory tree to be created * @return Returns True for success **/ -static BOOL recycle_create_dir(connection_struct *conn, const char *dname) +static BOOL recycle_create_dir(vfs_handle_struct *handle, const char *dname) { int len; mode_t mode; @@ -322,18 +227,18 @@ static BOOL recycle_create_dir(connection_struct *conn, const char *dname) /* Create directory tree if neccessary */ for(token = strtok(tok_str, "/"); token; token = strtok(NULL, "/")) { safe_strcat(new_dir, token, len); - if (recycle_directory_exist(conn, new_dir)) - DEBUG(10, ("recycle.bin: dir %s already exists\n", new_dir)); + if (recycle_directory_exist(handle, new_dir)) + DEBUG(10, ("recycle: dir %s already exists\n", new_dir)); else { - DEBUG(5, ("recycle.bin: creating new dir %s\n", new_dir)); - if (default_vfs_ops.mkdir(conn, new_dir, mode) != 0) { - DEBUG(1,("recycle.bin: mkdir failed for %s with error: %s\n", new_dir, strerror(errno))); + DEBUG(5, ("recycle: creating new dir %s\n", new_dir)); + if (SMB_VFS_NEXT_MKDIR(handle, handle->conn, new_dir, mode) != 0) { + DEBUG(1,("recycle: mkdir failed for %s with error: %s\n", new_dir, strerror(errno))); ret = False; goto done; } } safe_strcat(new_dir, "/", len); - } + } ret = True; done: @@ -348,30 +253,22 @@ done: * @param needle string to be matched exactly to haystack * @return True if found **/ -static BOOL checkparam(const char *haystack, const char *needle) +static BOOL checkparam(const char **haystack_list, const char *needle) { - char *token; - char *tok_str; - char *tmp_str; - BOOL ret = False; + int i; - if (haystack == NULL || strlen(haystack) == 0 || needle == NULL || strlen(needle) == 0) { + if (haystack_list == NULL || haystack_list[0] == NULL || + *haystack_list[0] == '\0' || needle == NULL || *needle == '\0') { return False; } - tmp_str = strdup(haystack); - ALLOC_CHECK(tmp_str, done); - token = tok_str = tmp_str; - - for(token = strtok(tok_str, delimiter); token; token = strtok(NULL, delimiter)) { - if(strcmp(token, needle) == 0) { - ret = True; - goto done; + for(i=0; haystack_list[i] ; i++) { + if(strequal(haystack_list[i], needle)) { + return True; } } -done: - SAFE_FREE(tmp_str); - return ret; + + return False; } /** @@ -380,110 +277,87 @@ done: * @param needle string to be matched exectly to haystack including pattern matching * @return True if found **/ -static BOOL matchparam(const char *haystack, const char *needle) +static BOOL matchparam(const char **haystack_list, const char *needle) { - char *token; - char *tok_str; - char *tmp_str; - BOOL ret = False; + int i; - if (haystack == NULL || strlen(haystack) == 0 || needle == NULL || strlen(needle) == 0) { + if (haystack_list == NULL || haystack_list[0] == NULL || + *haystack_list[0] == '\0' || needle == NULL || *needle == '\0') { return False; } - tmp_str = strdup(haystack); - ALLOC_CHECK(tmp_str, done); - token = tok_str = tmp_str; - - for(token = strtok(tok_str, delimiter); token; token = strtok(NULL, delimiter)) { - if (!unix_wild_match(token, needle)) { - ret = True; - goto done; + for(i=0; haystack_list[i] ; i++) { + if(!unix_wild_match((char *)haystack_list[i], (char *)needle)) { + return True; } } -done: - SAFE_FREE(tmp_str); - return ret; + + return False; } /** * Touch access date **/ -static void recycle_touch(connection_struct *conn, const char *fname) +static void recycle_do_touch(vfs_handle_struct *handle, const char *fname) { SMB_STRUCT_STAT st; struct utimbuf tb; time_t currtime; - - if (default_vfs_ops.stat(conn, fname, &st) != 0) { - DEBUG(0,("recycle.bin: stat for %s returned %s\n", fname, strerror(errno))); + + if (SMB_VFS_NEXT_STAT(handle, handle->conn, fname, &st) != 0) { + DEBUG(0,("recycle: stat for %s returned %s\n", fname, strerror(errno))); return; } currtime = time(&currtime); tb.actime = currtime; tb.modtime = st.st_mtime; - if (default_vfs_ops.utime(conn, fname, &tb) == -1 ) - DEBUG(0, ("recycle.bin: touching %s failed, reason = %s\n", fname, strerror(errno))); + if (SMB_VFS_NEXT_UTIME(handle, handle->conn, fname, &tb) == -1 ) { + DEBUG(0, ("recycle: touching %s failed, reason = %s\n", fname, strerror(errno))); } +} /** * Check if file should be recycled **/ -static int recycle_unlink(connection_struct *conn, const char *file_name) +static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *file_name) { - recycle_bin_private_data *recdata; - recycle_bin_connections *recconn; - recycle_bin_struct *recbin; char *path_name = NULL; char *temp_name = NULL; char *final_name = NULL; const char *base; - int i; -/* SMB_BIG_UINT dfree, dsize, bsize; */ + char *repository = NULL; + int i = 1; + int maxsize; SMB_OFF_T file_size; /* space_avail; */ BOOL exist; int rc = -1; - recbin = NULL; - if (recycle_bin_private_handle) { - recdata = (recycle_bin_private_data *)(recycle_bin_private_handle->data); - if (recdata) { - if (recdata->conns) { - recconn = recdata->conns; - while (recconn && recconn->conn != SNUM(conn)) recconn = recconn->next; - if (recconn != NULL) { - recbin = recconn->data; - } - } - } - } - if (recbin == NULL) { - DEBUG(0, ("Recycle bin not initialized!\n")); - rc = default_vfs_ops.unlink(conn, file_name); - goto done; - } - - if(!recbin->repository || *(recbin->repository) == '\0') { - DEBUG(3, ("Recycle path not set, purging %s...\n", file_name)); - rc = default_vfs_ops.unlink(conn, file_name); + repository = alloc_sub_conn(conn, (char *)recycle_repository(handle)); + ALLOC_CHECK(repository, done); + /* shouldn't we allow absolute path names here? --metze */ + trim_string(repository, "/", "/"); + + if(!repository || *(repository) == '\0') { + DEBUG(3, ("recycle: repository path not set, purging %s...\n", file_name)); + rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name); goto done; } /* we don't recycle the recycle bin... */ - if (strncmp(file_name, recbin->repository, strlen(recbin->repository)) == 0) { - DEBUG(3, ("File is within recycling bin, unlinking ...\n")); - rc = default_vfs_ops.unlink(conn, file_name); + if (strncmp(file_name, repository, strlen(repository)) == 0) { + DEBUG(3, ("recycle: File is within recycling bin, unlinking ...\n")); + rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name); goto done; } - file_size = recycle_get_file_size(conn, file_name); + file_size = recycle_get_file_size(handle, file_name); /* it is wrong to purge filenames only because they are empty imho * --- simo * if(fsize == 0) { - DEBUG(3, ("File %s is empty, purging...\n", file_name)); - rc = default_vfs_ops.unlink(conn,file_name); + DEBUG(3, ("recycle: File %s is empty, purging...\n", file_name)); + rc = SMB_VFS_NEXT_UNLINK(handle,conn,file_name); goto done; } */ @@ -492,20 +366,21 @@ static int recycle_unlink(connection_struct *conn, const char *file_name) * not greater then maxsize, not the size of the single file, also it is better * to remove older files */ - if(recbin->maxsize > 0 && file_size > recbin->maxsize) { - DEBUG(3, ("File %s exceeds maximum recycle size, purging... \n", file_name)); - rc = default_vfs_ops.unlink(conn, file_name); + maxsize = recycle_maxsize(handle); + if(maxsize > 0 && file_size > maxsize) { + DEBUG(3, ("recycle: File %s exceeds maximum recycle size, purging... \n", file_name)); + rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name); goto done; } /* FIXME: this is wrong: moving files with rename does not change the disk space * allocation * - space_avail = default_vfs_ops.disk_free(conn, ".", True, &bsize, &dfree, &dsize) * 1024L; + space_avail = SMB_VFS_NEXT_DISK_FREE(handle, conn, ".", True, &bsize, &dfree, &dsize) * 1024L; DEBUG(5, ("space_avail = %Lu, file_size = %Lu\n", space_avail, file_size)); if(space_avail < file_size) { - DEBUG(3, ("Not enough diskspace, purging file %s\n", file_name)); - rc = default_vfs_ops.unlink(conn, file_name); + DEBUG(3, ("recycle: Not enough diskspace, purging file %s\n", file_name)); + rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name); goto done; } */ @@ -524,13 +399,13 @@ static int recycle_unlink(connection_struct *conn, const char *file_name) base++; } - DEBUG(10, ("recycle.bin: fname = %s\n", file_name)); /* original filename with path */ - DEBUG(10, ("recycle.bin: fpath = %s\n", path_name)); /* original path */ - DEBUG(10, ("recycle.bin: base = %s\n", base)); /* filename without path */ + DEBUG(10, ("recycle: fname = %s\n", file_name)); /* original filename with path */ + DEBUG(10, ("recycle: fpath = %s\n", path_name)); /* original path */ + DEBUG(10, ("recycle: base = %s\n", base)); /* filename without path */ - if (matchparam(recbin->exclude, base)) { - DEBUG(3, ("recycle.bin: file %s is excluded \n", base)); - rc = default_vfs_ops.unlink(conn, file_name); + if (matchparam(recycle_exclude(handle), base)) { + DEBUG(3, ("recycle: file %s is excluded \n", base)); + rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name); goto done; } @@ -538,72 +413,85 @@ static int recycle_unlink(connection_struct *conn, const char *file_name) * we shoud check for every level 1, 1/2, 1/2/3, 1/2/3/4 .... * ---simo */ - if (checkparam(recbin->exclude_dir, path_name)) { - DEBUG(3, ("recycle.bin: directory %s is excluded \n", path_name)); - rc = default_vfs_ops.unlink(conn, file_name); + if (checkparam(recycle_exclude_dir(handle), path_name)) { + DEBUG(3, ("recycle: directory %s is excluded \n", path_name)); + rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name); goto done; } - /* see if we need to recreate the original directory structure in the recycle bin */ - if (recbin->keep_dir_tree == True) { - asprintf(&temp_name, "%s/%s", recbin->repository, path_name); + if (recycle_keep_dir_tree(handle) == True) { + asprintf(&temp_name, "%s/%s", repository, path_name); } else { - temp_name = strdup(recbin->repository); + temp_name = strdup(repository); } ALLOC_CHECK(temp_name, done); - exist = recycle_directory_exist(conn, temp_name); + exist = recycle_directory_exist(handle, temp_name); if (exist) { - DEBUG(10, ("recycle.bin: Directory already exists\n")); + DEBUG(10, ("recycle: Directory already exists\n")); } else { - DEBUG(10, ("recycle.bin: Creating directory %s\n", temp_name)); - if (recycle_create_dir(conn, temp_name) == False) { - DEBUG(3, ("Could not create directory, purging %s...\n", file_name)); - rc = default_vfs_ops.unlink(conn, file_name); + DEBUG(10, ("recycle: Creating directory %s\n", temp_name)); + if (recycle_create_dir(handle, temp_name) == False) { + DEBUG(3, ("recycle: Could not create directory, purging %s...\n", file_name)); + rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name); goto done; } } asprintf(&final_name, "%s/%s", temp_name, base); ALLOC_CHECK(final_name, done); - DEBUG(10, ("recycle.bin: recycled file name: %s\n", temp_name)); /* new filename with path */ + DEBUG(10, ("recycle: recycled file name: %s\n", final_name)); /* new filename with path */ /* check if we should delete file from recycle bin */ - if (recycle_file_exist(conn, final_name)) { - if (recbin->versions == False || matchparam(recbin->noversions, base) == True) { - DEBUG(3, ("recycle.bin: Removing old file %s from recycle bin\n", final_name)); - if (default_vfs_ops.unlink(conn, final_name) != 0) { - DEBUG(1, ("recycle.bin: Error deleting old file: %s\n", strerror(errno))); + if (recycle_file_exist(handle, final_name)) { + if (recycle_versions(handle) == False || matchparam(recycle_noversions(handle), base) == True) { + DEBUG(3, ("recycle: Removing old file %s from recycle bin\n", final_name)); + if (SMB_VFS_NEXT_UNLINK(handle, conn, final_name) != 0) { + DEBUG(1, ("recycle: Error deleting old file: %s\n", strerror(errno))); } } } /* rename file we move to recycle bin */ i = 1; - while (recycle_file_exist(conn, final_name)) { - snprintf(final_name, PATH_MAX, "%s/Copy #%d of %s", temp_name, i++, base); + while (recycle_file_exist(handle, final_name)) { + snprintf(final_name, PATH_MAX -1, "%s/Copy #%d of %s", temp_name, i++, base); } - DEBUG(10, ("recycle.bin: Moving %s to %s\n", file_name, final_name)); - rc = default_vfs_ops.rename(conn, file_name, final_name); + DEBUG(10, ("recycle: Moving %s to %s\n", file_name, final_name)); + rc = SMB_VFS_NEXT_RENAME(handle, conn, file_name, final_name); if (rc != 0) { - DEBUG(3, ("recycle.bin: Move error %d (%s), purging file %s (%s)\n", errno, strerror(errno), file_name, final_name)); - rc = default_vfs_ops.unlink(conn, file_name); + DEBUG(3, ("recycle: Move error %d (%s), purging file %s (%s)\n", errno, strerror(errno), file_name, final_name)); + rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name); goto done; } /* touch access date of moved file */ - if (recbin->touch == True ) - recycle_touch(conn, final_name); + if (recycle_touch(handle) == True ) + recycle_do_touch(handle, final_name); done: SAFE_FREE(path_name); SAFE_FREE(temp_name); SAFE_FREE(final_name); + SAFE_FREE(repository); return rc; } NTSTATUS vfs_recycle_init(void) -{ - return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "recycle", recycle_init); +{ + NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "recycle", recycle_ops); + + if (NT_STATUS_IS_ERR(ret)) + return ret; + + vfs_recycle_debug_level = debug_add_class("recycle"); + if (vfs_recycle_debug_level == -1) { + vfs_recycle_debug_level = DBGC_VFS; + DEBUG(0, ("vfs_recycle: Couldn't register custom debugging class!\n")); + } else { + DEBUG(10, ("vfs_recycle: Debug class number of 'recycle': %d\n", vfs_recycle_debug_level)); + } + + return ret; } diff --git a/source/msdfs/msdfs.c b/source/msdfs/msdfs.c index 69a315d4e40..d4ec0b830fd 100644 --- a/source/msdfs/msdfs.c +++ b/source/msdfs/msdfs.c @@ -169,14 +169,14 @@ BOOL is_msdfs_link(connection_struct* conn, char* path, if (sbufp == NULL) sbufp = &st; - if (conn->vfs_ops.lstat(conn, path, sbufp) != 0) { + if (SMB_VFS_LSTAT(conn, path, sbufp) != 0) { DEBUG(5,("is_msdfs_link: %s does not exist.\n",path)); return False; } if (S_ISLNK(sbufp->st_mode)) { /* open the link and read it */ - referral_len = conn->vfs_ops.readlink(conn, path, referral, + referral_len = SMB_VFS_READLINK(conn, path, referral, sizeof(pstring)); if (referral_len == -1) { DEBUG(0,("is_msdfs_link: Error reading msdfs link %s: %s\n", path, strerror(errno))); @@ -785,10 +785,10 @@ BOOL create_msdfs_link(struct junction_map* jn, BOOL exists) DEBUG(5,("create_msdfs_link: Creating new msdfs link: %s -> %s\n", path, msdfs_link)); if(exists) - if(conn->vfs_ops.unlink(conn,path)!=0) + if(SMB_VFS_UNLINK(conn,path)!=0) return False; - if(conn->vfs_ops.symlink(conn, msdfs_link, path) < 0) { + if(SMB_VFS_SYMLINK(conn, msdfs_link, path) < 0) { DEBUG(1,("create_msdfs_link: symlink failed %s -> %s\nError: %s\n", path, msdfs_link, strerror(errno))); return False; @@ -805,7 +805,7 @@ BOOL remove_msdfs_link(struct junction_map* jn) if(!junction_to_local_path(jn, path, sizeof(path), conn)) return False; - if(conn->vfs_ops.unlink(conn, path)!=0) + if(SMB_VFS_UNLINK(conn, path)!=0) return False; return True; @@ -862,7 +862,7 @@ static BOOL form_junctions(int snum, struct junction_map* jn, int* jn_count) cnt++; /* Now enumerate all dfs links */ - dirp = conn->vfs_ops.opendir(conn, connect_path); + dirp = SMB_VFS_OPENDIR(conn, connect_path); if(!dirp) return False; @@ -881,7 +881,7 @@ static BOOL form_junctions(int snum, struct junction_map* jn, int* jn_count) } } - conn->vfs_ops.closedir(conn,dirp); + SMB_VFS_CLOSEDIR(conn,dirp); *jn_count = cnt; return True; } diff --git a/source/nmbd/nmbd.c b/source/nmbd/nmbd.c index ad5ab4d734d..d9300f4668f 100644 --- a/source/nmbd/nmbd.c +++ b/source/nmbd/nmbd.c @@ -573,8 +573,10 @@ static BOOL open_sockets(BOOL isdaemon, int port) **************************************************************************** */ int main(int argc, const char *argv[]) { - static BOOL opt_interactive = False; + pstring logfile; + static BOOL opt_interactive; poptContext pc; + int opt; struct poptOption long_options[] = { POPT_AUTOHELP {"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon(default)" }, @@ -586,46 +588,47 @@ static BOOL open_sockets(BOOL isdaemon, int port) POPT_COMMON_SAMBA { NULL } }; - pstring logfile; - - global_nmb_port = NMB_PORT; - global_in_nmbd = True; - - StartupTime = time(NULL); - - sys_srandom(time(NULL) ^ sys_getpid()); - slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", dyn_LOGFILEBASE); - lp_set_logfile(logfile); + global_nmb_port = NMB_PORT; - fault_setup((void (*)(void *))fault_continue ); - - /* POSIX demands that signals are inherited. If the invoking process has - * these signals masked, we will have problems, as we won't receive them. */ - BlockSignals(False, SIGHUP); - BlockSignals(False, SIGUSR1); - BlockSignals(False, SIGTERM); - - CatchSignal( SIGHUP, SIGNAL_CAST sig_hup ); - CatchSignal( SIGTERM, SIGNAL_CAST sig_term ); + pc = poptGetContext("nmbd", argc, argv, long_options, 0); + while ((opt = poptGetNextOpt(pc)) != -1) ; + poptFreeContext(pc); + global_in_nmbd = True; + + StartupTime = time(NULL); + + sys_srandom(time(NULL) ^ sys_getpid()); + + slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", dyn_LOGFILEBASE); + lp_set_logfile(logfile); + + fault_setup((void (*)(void *))fault_continue ); + + /* POSIX demands that signals are inherited. If the invoking process has + * these signals masked, we will have problems, as we won't receive them. */ + BlockSignals(False, SIGHUP); + BlockSignals(False, SIGUSR1); + BlockSignals(False, SIGTERM); + + CatchSignal( SIGHUP, SIGNAL_CAST sig_hup ); + CatchSignal( SIGTERM, SIGNAL_CAST sig_term ); + #if defined(SIGFPE) - /* we are never interested in SIGFPE */ - BlockSignals(True,SIGFPE); + /* we are never interested in SIGFPE */ + BlockSignals(True,SIGFPE); #endif - /* We no longer use USR2... */ + /* We no longer use USR2... */ #if defined(SIGUSR2) - BlockSignals(True, SIGUSR2); + BlockSignals(True, SIGUSR2); #endif - pc = poptGetContext("nmbd", argc, argv, long_options, 0); - - poptFreeContext(pc); - if ( opt_interactive ) { - Fork = False; - log_stdout = True; - } + if ( opt_interactive ) { + Fork = False; + log_stdout = True; + } if ( log_stdout && Fork ) { DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n")); diff --git a/source/nmbd/nmbd_become_lmb.c b/source/nmbd/nmbd_become_lmb.c index 6f8e7efb1ae..d390bf72e95 100644 --- a/source/nmbd/nmbd_become_lmb.c +++ b/source/nmbd/nmbd_become_lmb.c @@ -600,6 +600,5 @@ local_master_browser_name for workgroup %s to workgroup name.\n", } #endif - StrnCpy(work->local_master_browser_name, newname, - sizeof(work->local_master_browser_name)-1); + fstrcpy(work->local_master_browser_name, newname); } diff --git a/source/nmbd/nmbd_browserdb.c b/source/nmbd/nmbd_browserdb.c index a4ef98e265e..d7c852605e2 100644 --- a/source/nmbd/nmbd_browserdb.c +++ b/source/nmbd/nmbd_browserdb.c @@ -107,8 +107,8 @@ struct browse_cache_record *create_browser_in_lmb_cache( char *work_name, /* Allow the new lmb to miss an announce period before we remove it. */ browc->death_time = now + ( (CHECK_TIME_MST_ANNOUNCE + 2) * 60 ); - StrnCpy( browc->lmb_name, browser_name, sizeof(browc->lmb_name)-1 ); - StrnCpy( browc->work_group, work_name, sizeof(browc->work_group)-1 ); + pstrcpy( browc->lmb_name, browser_name); + pstrcpy( browc->work_group, work_name); strupper( browc->lmb_name ); strupper( browc->work_group ); diff --git a/source/nmbd/nmbd_browsesync.c b/source/nmbd/nmbd_browsesync.c index adfefc9f27a..381f65e0c85 100644 --- a/source/nmbd/nmbd_browsesync.c +++ b/source/nmbd/nmbd_browsesync.c @@ -106,6 +106,7 @@ As a local master browser, send an announce packet to the domain master browser. static void announce_local_master_browser_to_domain_master_browser( struct work_record *work) { pstring outbuf; + fstring myname; char *p; if(ismyip(work->dmb_addr)) @@ -125,8 +126,11 @@ static void announce_local_master_browser_to_domain_master_browser( struct work_ SCVAL(p,0,ANN_MasterAnnouncement); p++; - StrnCpy(p,global_myname(),15); - strupper(p); + fstrcpy(myname, global_myname()); + strupper(myname); + myname[15]='\0'; + push_pstring_base(p, myname, outbuf); + p = skip_string(p,1); if( DEBUGLVL( 4 ) ) diff --git a/source/nmbd/nmbd_incomingdgrams.c b/source/nmbd/nmbd_incomingdgrams.c index cd6954fc62a..16fecbccd95 100644 --- a/source/nmbd/nmbd_incomingdgrams.c +++ b/source/nmbd/nmbd_incomingdgrams.c @@ -172,7 +172,7 @@ void process_host_announce(struct subnet_record *subrec, struct packet_struct *p /* Update the record. */ servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY; update_server_ttl( servrec, ttl); - StrnCpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment)-1); + fstrcpy(servrec->serv.comment,comment); } } else @@ -343,7 +343,7 @@ a local master browser for workgroup %s and we think we are master. Forcing elec /* Update the record. */ servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY; update_server_ttl(servrec, ttl); - StrnCpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment)-1); + fstrcpy(servrec->serv.comment,comment); } set_workgroup_local_master_browser_name( work, server_name ); @@ -520,7 +520,7 @@ originate from OS/2 Warp client. Ignoring packet.\n")); /* Update the record. */ servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY; update_server_ttl( servrec, ttl); - StrnCpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment)-1); + fstrcpy(servrec->serv.comment,comment); } } else @@ -559,6 +559,7 @@ static void send_backup_list_response(struct subnet_record *subrec, #if 0 struct server_record *servrec; #endif + fstring myname; memset(outbuf,'\0',sizeof(outbuf)); @@ -578,8 +579,11 @@ static void send_backup_list_response(struct subnet_record *subrec, /* We always return at least one name - our own. */ count = 1; - StrnCpy(p,global_myname(),15); - strupper(p); + fstrcpy(myname, global_myname()); + strupper(myname); + myname[15]='\0'; + push_pstring_base(p, myname, outbuf); + p = skip_string(p,1); /* Look for backup browsers in this workgroup. */ diff --git a/source/nmbd/nmbd_processlogon.c b/source/nmbd/nmbd_processlogon.c index a702fc30156..42edcc871fa 100644 --- a/source/nmbd/nmbd_processlogon.c +++ b/source/nmbd/nmbd_processlogon.c @@ -304,19 +304,19 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", pstring hostname; char *component, *dc, *q1; uint8 size; + char *q_orig = q; + int str_offset; get_mydomname(domain); get_myname(hostname); if (SVAL(uniuser, 0) == 0) { - SSVAL(q, 0, SAMLOGON_AD_UNK_R); /* user unknown */ + SIVAL(q, 0, SAMLOGON_AD_UNK_R); /* user unknown */ } else { - SSVAL(q, 0, SAMLOGON_AD_R); + SIVAL(q, 0, SAMLOGON_AD_R); } - q += 2; + q += 4; - SSVAL(q, 0, 0); - q += 2; SIVAL(q, 0, ADS_PDC|ADS_GC|ADS_LDAP|ADS_DS| ADS_KDC|ADS_TIMESERV|ADS_CLOSEST|ADS_WRITABLE); q += 4; @@ -329,7 +329,8 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", memcpy(q, &domain_guid, sizeof(domain_guid)); q += sizeof(domain_guid); - /* Push domain components */ + /* Forest */ + str_offset = q - q_orig; dc = domain; q1 = q; while ((component = strtok(dc, "."))) { @@ -338,44 +339,60 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", SCVAL(q, 0, size); q += (size + 1); } + + /* Unk0 */ SCVAL(q, 0, 0); q++; - SSVAL(q, 0, 0x18c0); /* not sure what this is for, but */ - q += 2; /* it must follow the domain name. */ - /* Push dns host name */ + /* Domain */ + SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F)); + SCVAL(q, 1, str_offset & 0xFF); + q += 2; + + /* Hostname */ size = push_ascii(&q[1], hostname, -1, 0); SCVAL(q, 0, size); q += (size + 1); - SSVAL(q, 0, 0x18c0); /* not sure what this is for, but */ - q += 2; /* it must follow the domain name. */ + SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F)); + SCVAL(q, 1, str_offset & 0xFF); + q += 2; - /* Push NETBIOS of domain */ + /* NETBIOS of domain */ size = push_ascii(&q[1], lp_workgroup(), -1, STR_UPPER); SCVAL(q, 0, size); q += (size + 1); - SCVAL(q, 0, 0); q++; /* is this a null terminator or empty field */ - /* null terminator would not be needed because size is included */ - /* Push NETBIOS of hostname */ + /* Unk1 */ + SCVAL(q, 0, 0); q++; + + /* NETBIOS of hostname */ size = push_ascii(&q[1], my_name, -1, 0); SCVAL(q, 0, size); q += (size + 1); - SCVAL(q, 0, 0); q++; /* null terminator or empty field? */ - /* Push user account */ - size = push_ascii(&q[1], ascuser, -1, 0); - SCVAL(q, 0, size); - q += (size + 1); + /* Unk2 */ + SCVAL(q, 0, 0); q++; + + /* User name */ + if (SVAL(uniuser, 0) != 0) { + size = push_ascii(&q[1], ascuser, -1, 0); + SCVAL(q, 0, size); + q += (size + 1); + } - /* Push 'Default-First-Site-Name' */ + q_orig = q; + /* Site name */ size = push_ascii(&q[1], "Default-First-Site-Name", -1, 0); SCVAL(q, 0, size); q += (size + 1); - SSVAL(q, 0, 0xc000); /* unknown */ - SCVAL(q, 2, PTR_DIFF(q,q1)); - SCVAL(q, 3, 0x10); /* unknown */ - q += 4; + /* Site name (2) */ + str_offset = q - q_orig; + SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F)); + SCVAL(q, 1, str_offset & 0xFF); + q += 2; + + SCVAL(q, 0, PTR_DIFF(q,q1)); + SCVAL(q, 1, 0x10); /* unknown */ SIVAL(q, 0, 0x00000002); q += 4; /* unknown */ SIVAL(q, 0, (iface_ip(p->ip))->s_addr); q += 4; diff --git a/source/nmbd/nmbd_sendannounce.c b/source/nmbd/nmbd_sendannounce.c index 40d07aae168..8501acf9ba5 100644 --- a/source/nmbd/nmbd_sendannounce.c +++ b/source/nmbd/nmbd_sendannounce.c @@ -555,6 +555,7 @@ void browse_sync_remote(time_t t) struct work_record *work; pstring outbuf; char *p; + fstring myname; if (last_time && (t < (last_time + REMOTE_ANNOUNCE_INTERVAL))) return; @@ -589,8 +590,11 @@ for workgroup %s on subnet %s.\n", lp_workgroup(), FIRST_SUBNET->subnet_name )); SCVAL(p,0,ANN_MasterAnnouncement); p++; - StrnCpy(p,global_myname(),15); - strupper(p); + fstrcpy(myname, global_myname()); + strupper(myname); + myname[15]='\0'; + push_pstring_base(p, myname, outbuf); + p = skip_string(p,1); for (ptr=s; next_token(&ptr,s2,NULL,sizeof(s2)); ) diff --git a/source/nmbd/nmbd_serverlistdb.c b/source/nmbd/nmbd_serverlistdb.c index ee0c021d5dc..e99599e16fa 100644 --- a/source/nmbd/nmbd_serverlistdb.c +++ b/source/nmbd/nmbd_serverlistdb.c @@ -153,8 +153,8 @@ workgroup %s. This is a bug.\n", name, work->work_group)); servrec->subnet = work->subnet; - StrnCpy(servrec->serv.name,name,sizeof(servrec->serv.name)-1); - StrnCpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment)-1); + fstrcpy(servrec->serv.name,name); + fstrcpy(servrec->serv.comment,comment); strupper(servrec->serv.name); servrec->serv.type = servertype; diff --git a/source/nmbd/nmbd_winsserver.c b/source/nmbd/nmbd_winsserver.c index 47ce8119f33..eafff03b767 100644 --- a/source/nmbd/nmbd_winsserver.c +++ b/source/nmbd/nmbd_winsserver.c @@ -22,7 +22,7 @@ #include "includes.h" -#define WINS_LIST "wins.tdb" +#define WINS_LIST "wins.dat" #define WINS_VERSION 1 /**************************************************************************** @@ -221,123 +221,177 @@ Load or create the WINS database. BOOL initialise_wins(void) { - time_t time_now = time(NULL); - TDB_CONTEXT *tdb; - TDB_DATA kbuf, dbuf, newkey; - struct name_record *namerec = NULL; - struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0"); + time_t time_now = time(NULL); + XFILE *fp; + pstring line; - DEBUG(2,("initialise_wins: started\n")); + if(!lp_we_are_a_wins_server()) + return True; - if(!lp_we_are_a_wins_server()) - return True; + add_samba_names_to_subnet(wins_server_subnet); - add_samba_names_to_subnet(wins_server_subnet); + if((fp = x_fopen(lock_path(WINS_LIST),O_RDONLY,0)) == NULL) + { + DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n", + WINS_LIST, strerror(errno) )); + return True; + } - tdb = tdb_open_log(lock_path(WINS_LIST), 0, TDB_DEFAULT, O_RDONLY, 0600); - if (!tdb) { - DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n", WINS_LIST, strerror(errno) )); - return True; - } + while (!x_feof(fp)) + { + pstring name_str, ip_str, ttl_str, nb_flags_str; + unsigned int num_ips; + pstring name; + struct in_addr *ip_list; + int type = 0; + int nb_flags; + int ttl; + const char *ptr; + char *p; + BOOL got_token; + BOOL was_ip; + int i; + unsigned hash; + int version; + + /* Read a line from the wins.dat file. Strips whitespace + from the beginning and end of the line. + */ + if (!fgets_slash(line,sizeof(pstring),fp)) + continue; + + if (*line == '#') + continue; + + if (strncmp(line,"VERSION ", 8) == 0) { + if (sscanf(line,"VERSION %d %u", &version, &hash) != 2 || + version != WINS_VERSION) { + DEBUG(0,("Discarding invalid wins.dat file [%s]\n",line)); + x_fclose(fp); + return True; + } + continue; + } - if (tdb_fetch_int32(tdb, INFO_VERSION) != WINS_VERSION) { - DEBUG(0,("Discarding invalid wins.tdb file\n")); - tdb_close(tdb); - return True; - } + ptr = line; - for (kbuf = tdb_firstkey(tdb); - kbuf.dptr; - newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) { - - fstring name_type; - pstring name, ip_str; - char *p; - int type = 0; - int nb_flags; - int ttl; - unsigned int num_ips; - int high, low; - struct in_addr wins_ip; - struct in_addr *ip_list; - int wins_flags; - int len,i; - - if (strncmp(kbuf.dptr, ENTRY_PREFIX, strlen(ENTRY_PREFIX)) != 0) - continue; - - dbuf = tdb_fetch(tdb, kbuf); - if (!dbuf.dptr) - continue; + /* + * Now we handle multiple IP addresses per name we need + * to iterate over the line twice. The first time to + * determine how many IP addresses there are, the second + * time to actually parse them into the ip_list array. + */ - fstrcpy(name_type, kbuf.dptr+strlen(ENTRY_PREFIX)); + if (!next_token(&ptr,name_str,NULL,sizeof(name_str))) + { + DEBUG(0,("initialise_wins: Failed to parse name when parsing line %s\n", line )); + continue; + } - pstrcpy(name, name_type); + if (!next_token(&ptr,ttl_str,NULL,sizeof(ttl_str))) + { + DEBUG(0,("initialise_wins: Failed to parse time to live when parsing line %s\n", line )); + continue; + } - if((p = strchr(name,'#')) != NULL) { - *p = 0; - sscanf(p+1,"%x",&type); - } + /* + * Determine the number of IP addresses per line. + */ + num_ips = 0; + do + { + got_token = next_token(&ptr,ip_str,NULL,sizeof(ip_str)); + was_ip = False; - len = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddfddd", - &nb_flags, &high, &low, - ip_str, &ttl, &num_ips, &wins_flags); + if(got_token && strchr(ip_str, '.')) + { + num_ips++; + was_ip = True; + } + } while( got_token && was_ip); - wins_ip=*interpret_addr2(ip_str); + if(num_ips == 0) + { + DEBUG(0,("initialise_wins: Missing IP address when parsing line %s\n", line )); + continue; + } - /* Don't reload replica records */ - if (!ip_equal(wins_ip, our_fake_ip)) { - SAFE_FREE(dbuf.dptr); - continue; - } + if(!got_token) + { + DEBUG(0,("initialise_wins: Missing nb_flags when parsing line %s\n", line )); + continue; + } - /* Don't reload released or tombstoned records */ - if ((wins_flags&WINS_STATE_MASK) != WINS_ACTIVE) { - SAFE_FREE(dbuf.dptr); - continue; - } + /* Allocate the space for the ip_list. */ + if((ip_list = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr))) == NULL) + { + DEBUG(0,("initialise_wins: Malloc fail !\n")); + return False; + } + + /* Reset and re-parse the line. */ + ptr = line; + next_token(&ptr,name_str,NULL,sizeof(name_str)); + next_token(&ptr,ttl_str,NULL,sizeof(ttl_str)); + for(i = 0; i < num_ips; i++) + { + next_token(&ptr, ip_str, NULL, sizeof(ip_str)); + ip_list[i] = *interpret_addr2(ip_str); + } + next_token(&ptr,nb_flags_str,NULL, sizeof(nb_flags_str)); - /* Allocate the space for the ip_list. */ - if((ip_list = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr))) == NULL) { - SAFE_FREE(dbuf.dptr); - DEBUG(0,("initialise_wins: Malloc fail !\n")); - return False; - } + /* + * Deal with SELF or REGISTER name encoding. Default is REGISTER + * for compatibility with old nmbds. + */ - for (i = 0; i < num_ips; i++) { - len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f", ip_str); - ip_list[i] = *interpret_addr2(ip_str); - } + if(nb_flags_str[strlen(nb_flags_str)-1] == 'S') + { + DEBUG(5,("initialise_wins: Ignoring SELF name %s\n", line)); + SAFE_FREE(ip_list); + continue; + } + + if(nb_flags_str[strlen(nb_flags_str)-1] == 'R') + nb_flags_str[strlen(nb_flags_str)-1] = '\0'; + + /* Netbios name. # divides the name from the type (hex): netbios#xx */ + pstrcpy(name,name_str); + + if((p = strchr(name,'#')) != NULL) + { + *p = 0; + sscanf(p+1,"%x",&type); + } + + /* Decode the netbios flags (hex) and the time-to-live (in seconds). */ + sscanf(nb_flags_str,"%x",&nb_flags); + sscanf(ttl_str,"%d",&ttl); - /* add all entries that have 60 seconds or more to live */ - if ((ttl - 60) > time_now || ttl == PERMANENT_TTL) { - if(ttl != PERMANENT_TTL) - ttl -= time_now; + /* add all entries that have 60 seconds or more to live */ + if ((ttl - 60) > time_now || ttl == PERMANENT_TTL) + { + if(ttl != PERMANENT_TTL) + ttl -= time_now; - DEBUG( 4, ("initialise_wins: add name: %s#%02x ttl = %d first IP %s flags = %2x\n", - name, type, ttl, inet_ntoa(ip_list[0]), nb_flags)); - - namerec=add_name_to_subnet( wins_server_subnet, name, type, nb_flags, - ttl, REGISTER_NAME, num_ips, ip_list); - if (namerec!=NULL) { - update_wins_owner(namerec, wins_ip); - update_wins_flag(namerec, wins_flags); - /* we don't reload the ID, on startup we restart at 1 */ - get_global_id_and_update(&namerec->data.id, True); - } + DEBUG( 4, ("initialise_wins: add name: %s#%02x ttl = %d first IP %s flags = %2x\n", + name, type, ttl, inet_ntoa(ip_list[0]), nb_flags)); - } else { - DEBUG(4, ("initialise_wins: not adding name (ttl problem) %s#%02x ttl = %d first IP %s flags = %2x\n", - name, type, ttl, inet_ntoa(ip_list[0]), nb_flags)); - } + (void)add_name_to_subnet( wins_server_subnet, name, type, nb_flags, + ttl, REGISTER_NAME, num_ips, ip_list ); - SAFE_FREE(dbuf.dptr); - SAFE_FREE(ip_list); - } + } + else + { + DEBUG(4, ("initialise_wins: not adding name (ttl problem) %s#%02x ttl = %d first IP %s flags = %2x\n", + name, type, ttl, inet_ntoa(ip_list[0]), nb_flags)); + } + + SAFE_FREE(ip_list); + } - tdb_close(tdb); - DEBUG(2,("initialise_wins: done\n")); - return True; + x_fclose(fp); + return True; } /**************************************************************************** @@ -1765,113 +1819,87 @@ we are not the wins owner !\n", nmb_namestr(&namerec->name))); ******************************************************************/ void wins_write_database(BOOL background) { - struct name_record *namerec; - pstring fname, fnamenew; - TDB_CONTEXT *tdb; - TDB_DATA kbuf, dbuf; - pstring key, buf; - int len; - int num_record=0; - SMB_BIG_UINT id; - - if(!lp_we_are_a_wins_server()) - return; - - /* we will do the writing in a child process to ensure that the parent - doesn't block while this is done */ - if (background) { - CatchChild(); - if (sys_fork()) { - return; - } - } - - slprintf(fname,sizeof(fname)-1,"%s/%s", lp_lockdir(), WINS_LIST); - all_string_sub(fname,"//", "/", 0); - slprintf(fnamenew,sizeof(fnamenew)-1,"%s.%u", fname, (unsigned int)sys_getpid()); - - tdb = tdb_open_log(fnamenew, 0, TDB_DEFAULT, O_RDWR|O_CREAT|O_TRUNC, 0644); - if (!tdb) { - DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno))); - if (background) - _exit(0); - return; - } - - DEBUG(3,("wins_write_database: Dump of WINS name list.\n")); - - tdb_store_int32(tdb, INFO_VERSION, WINS_VERSION); - - for (namerec = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist ); - namerec; - namerec = (struct name_record *)ubi_trNext( namerec ) ) { - - int i; - struct tm *tm; - - DEBUGADD(3,("%-19s ", nmb_namestr(&namerec->name) )); + struct name_record *namerec; + pstring fname, fnamenew; - if( namerec->data.death_time != PERMANENT_TTL ) { - char *ts, *nl; - - tm = LocalTime(&namerec->data.death_time); - ts = asctime(tm); - nl = strrchr_m( ts, '\n' ); - if( NULL != nl ) - *nl = '\0'; + XFILE *fp; + + if(!lp_we_are_a_wins_server()) + return; - DEBUGADD(3,("TTL = %s ", ts )); - } else - DEBUGADD(3,("TTL = PERMANENT ")); + /* we will do the writing in a child process to ensure that the parent + doesn't block while this is done */ + if (background) { + CatchChild(); + if (sys_fork()) { + return; + } + } - for (i = 0; i < namerec->data.num_ips; i++) - DEBUGADD(0,("%15s ", inet_ntoa(namerec->data.ip[i]) )); + slprintf(fname,sizeof(fname)-1,"%s/%s", lp_lockdir(), WINS_LIST); + all_string_sub(fname,"//", "/", 0); + slprintf(fnamenew,sizeof(fnamenew)-1,"%s.%u", fname, (unsigned int)sys_getpid()); - DEBUGADD(3,("0x%2x 0x%2x %15s\n", namerec->data.nb_flags, namerec->data.wins_flags, inet_ntoa(namerec->data.wins_ip))); + if((fp = x_fopen(fnamenew,O_WRONLY|O_CREAT,0644)) == NULL) + { + DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno))); + if (background) { + _exit(0); + } + return; + } - if( namerec->data.source == REGISTER_NAME ) { - - /* store the type in the key to make the name unique */ - slprintf(key, sizeof(key), "%s%s#%02x", ENTRY_PREFIX, namerec->name.name, namerec->name.name_type); - - len = tdb_pack(buf, sizeof(buf), "dddfddd", - (int)namerec->data.nb_flags, - (int)(namerec->data.id>>32), - (int)(namerec->data.id&0xffffffff), - inet_ntoa(namerec->data.wins_ip), - (int)namerec->data.death_time, - namerec->data.num_ips, - namerec->data.wins_flags); - - for (i = 0; i < namerec->data.num_ips; i++) - len += tdb_pack(buf+len, sizeof(buf)-len, "f", inet_ntoa(namerec->data.ip[i])); - - kbuf.dsize = strlen(key)+1; - kbuf.dptr = key; - dbuf.dsize = len; - dbuf.dptr = buf; - if (tdb_store(tdb, kbuf, dbuf, TDB_INSERT) != 0) return; + DEBUG(4,("wins_write_database: Dump of WINS name list.\n")); - num_record++; - } - } + x_fprintf(fp,"VERSION %d %u\n", WINS_VERSION, 0); + + for( namerec + = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist ); + namerec; + namerec = (struct name_record *)ubi_trNext( namerec ) ) + { + int i; + struct tm *tm; - /* store the number of records */ - tdb_store_int32(tdb, INFO_COUNT, num_record); + DEBUGADD(4,("%-19s ", nmb_namestr(&namerec->name) )); - /* get and store the last used ID */ - get_global_id_and_update(&id, False); - tdb_store_int32(tdb, INFO_ID_HIGH, id>>32); - tdb_store_int32(tdb, INFO_ID_LOW, id&0xffffffff); + if( namerec->data.death_time != PERMANENT_TTL ) + { + char *ts, *nl; + + tm = LocalTime(&namerec->data.death_time); + ts = asctime(tm); + nl = strrchr( ts, '\n' ); + if( NULL != nl ) + *nl = '\0'; + DEBUGADD(4,("TTL = %s ", ts )); + } + else + DEBUGADD(4,("TTL = PERMANENT ")); - tdb_close(tdb); + for (i = 0; i < namerec->data.num_ips; i++) + DEBUGADD(4,("%15s ", inet_ntoa(namerec->data.ip[i]) )); + DEBUGADD(4,("%2x\n", namerec->data.nb_flags )); - chmod(fnamenew,0644); - unlink(fname); - rename(fnamenew,fname); + if( namerec->data.source == REGISTER_NAME ) + { + x_fprintf(fp, "\"%s#%02x\" %d ", + namerec->name.name,namerec->name.name_type, /* Ignore scope. */ + (int)namerec->data.death_time); - if (background) - _exit(0); + for (i = 0; i < namerec->data.num_ips; i++) + x_fprintf( fp, "%s ", inet_ntoa( namerec->data.ip[i] ) ); + x_fprintf( fp, "%2xR\n", namerec->data.nb_flags ); + } + } + + x_fclose(fp); + chmod(fnamenew,0644); + unlink(fname); + rename(fnamenew,fname); + if (background) { + _exit(0); + } } /**************************************************************************** diff --git a/source/nmbd/nmbd_workgroupdb.c b/source/nmbd/nmbd_workgroupdb.c index b8ea60dec07..2357fd637b5 100644 --- a/source/nmbd/nmbd_workgroupdb.c +++ b/source/nmbd/nmbd_workgroupdb.c @@ -57,7 +57,7 @@ static struct work_record *create_workgroup(const char *name, int ttl) } memset((char *)work, '\0', sizeof(*work)); - StrnCpy(work->work_group,name,sizeof(work->work_group)-1); + fstrcpy(work->work_group,name); work->serverlist = NULL; work->RunningElection = False; diff --git a/source/nsswitch/winbindd.h b/source/nsswitch/winbindd.h index 2d9a0b59499..987a58e502f 100644 --- a/source/nsswitch/winbindd.h +++ b/source/nsswitch/winbindd.h @@ -219,7 +219,7 @@ struct winbindd_idmap_methods { void (*status)(void); }; -#include "winbindd_proto.h" +#include "../nsswitch/winbindd_proto.h" #include "rpc_parse.h" #include "rpc_client.h" diff --git a/source/nsswitch/winbindd_cache.c b/source/nsswitch/winbindd_cache.c index f3dc1263b9b..1b817592ae8 100644 --- a/source/nsswitch/winbindd_cache.c +++ b/source/nsswitch/winbindd_cache.c @@ -100,12 +100,12 @@ static struct winbind_cache *get_cache(struct winbindd_domain *domain) ret = smb_xmalloc(sizeof(*ret)); ZERO_STRUCTP(ret); - + switch (lp_security()) { /* winbind pdc disabled until ready if (!strcmp(domain->name, lp_workgroup()) && (lp_security() == SEC_USER)) { extern struct winbindd_methods passdb_methods; ret->backend = &passdb_methods; - } else switch (lp_security()) { + } else switch (lp_security()) { */ #ifdef HAVE_ADS case SEC_ADS: { extern struct winbindd_methods ads_methods; diff --git a/source/nsswitch/winbindd_cm.c b/source/nsswitch/winbindd_cm.c index 02fd15e0691..2aa07afdfc4 100644 --- a/source/nsswitch/winbindd_cm.c +++ b/source/nsswitch/winbindd_cm.c @@ -246,65 +246,11 @@ static void cm_get_ipc_userpass(char **username, char **domain, char **password) } } -/* Open a new smb pipe connection to a DC on a given domain. Cache - negative creation attempts so we don't try and connect to broken - machines too often. */ - -#define FAILED_CONNECTION_CACHE_TIMEOUT 30 /* Seconds between attempts */ - -struct failed_connection_cache { - fstring domain_name; - fstring controller; - time_t lookup_time; - NTSTATUS nt_status; - struct failed_connection_cache *prev, *next; -}; - -static struct failed_connection_cache *failed_connection_cache; - -/* Add an entry to the failed conneciton cache */ - -static void add_failed_connection_entry(struct winbindd_cm_conn *new_conn, - NTSTATUS result) -{ - struct failed_connection_cache *fcc; - - SMB_ASSERT(!NT_STATUS_IS_OK(result)); - - /* Check we already aren't in the cache */ - - for (fcc = failed_connection_cache; fcc; fcc = fcc->next) { - if (strequal(fcc->domain_name, new_conn->domain)) { - DEBUG(10, ("domain %s already tried and failed\n", - fcc->domain_name)); - return; - } - } - - /* Create negative lookup cache entry for this domain and controller */ - - if (!(fcc = (struct failed_connection_cache *) - malloc(sizeof(struct failed_connection_cache)))) { - DEBUG(0, ("malloc failed in add_failed_connection_entry!\n")); - return; - } - - ZERO_STRUCTP(fcc); - - fstrcpy(fcc->domain_name, new_conn->domain); - fstrcpy(fcc->controller, new_conn->controller); - fcc->lookup_time = time(NULL); - fcc->nt_status = result; - - DLIST_ADD(failed_connection_cache, fcc); -} - /* Open a connction to the remote server, cache failures for 30 seconds */ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index, struct winbindd_cm_conn *new_conn) { - struct failed_connection_cache *fcc; NTSTATUS result; char *ipc_username, *ipc_domain, *ipc_password; struct in_addr dc_ip; @@ -316,47 +262,15 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index, fstrcpy(new_conn->domain, domain); fstrcpy(new_conn->pipe_name, get_pipe_name_from_index(pipe_index)); - /* Look for a domain controller for this domain. Negative results - are cached so don't bother applying the caching for this - function just yet. */ + /* connection failure cache has been moved inside of get_dc_name + so we can deal with half dead DC's --jerry */ if (!cm_get_dc_name(domain, new_conn->controller, &dc_ip)) { result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; - add_failed_connection_entry(new_conn, result); + add_failed_connection_entry(domain, "", result); return result; } - /* Return false if we have tried to look up this domain and netbios - name before and failed. */ - - for (fcc = failed_connection_cache; fcc; fcc = fcc->next) { - - if (!(strequal(domain, fcc->domain_name) && - strequal(new_conn->controller, fcc->controller))) - continue; /* Not our domain */ - - if ((time(NULL) - fcc->lookup_time) > - FAILED_CONNECTION_CACHE_TIMEOUT) { - - /* Cache entry has expired, delete it */ - - DEBUG(10, ("cm_open_connection cache entry expired for %s, %s\n", domain, new_conn->controller)); - - DLIST_REMOVE(failed_connection_cache, fcc); - free(fcc); - - break; - } - - /* The timeout hasn't expired yet so return false */ - - DEBUG(10, ("returning negative open_connection_cache entry for %s, %s\n", domain, new_conn->controller)); - - result = fcc->nt_status; - SMB_ASSERT(!NT_STATUS_IS_OK(result)); - return result; - } - /* Initialise SMB connection */ cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password); @@ -402,7 +316,7 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index, * specific UUID right now, i'm not going to bother. --jerry */ if ( !is_win2k_pipe(pipe_index) ) - add_failed_connection_entry(new_conn, result); + add_failed_connection_entry(domain, new_conn->controller, result); cli_shutdown(new_conn->cli); return result; } @@ -415,21 +329,19 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index, static BOOL connection_ok(struct winbindd_cm_conn *conn) { if (!conn) { - smb_panic("Invalid paramater passed to conneciton_ok(): conn was NULL!\n"); + smb_panic("Invalid parameter passed to connection_ok(): conn was NULL!\n"); return False; } if (!conn->cli) { - DEBUG(0, ("Connection to %s for domain %s (pipe %s) has NULL conn->cli!\n", + DEBUG(3, ("Connection to %s for domain %s (pipe %s) has NULL conn->cli!\n", conn->controller, conn->domain, conn->pipe_name)); - smb_panic("connection_ok: conn->cli was null!"); return False; } if (!conn->cli->initialised) { - DEBUG(0, ("Connection to %s for domain %s (pipe %s) was never initialised!\n", + DEBUG(3, ("Connection to %s for domain %s (pipe %s) was never initialised!\n", conn->controller, conn->domain, conn->pipe_name)); - smb_panic("connection_ok: conn->cli->initialised is False!"); return False; } @@ -442,52 +354,73 @@ static BOOL connection_ok(struct winbindd_cm_conn *conn) return True; } -/* Get a connection to the remote DC and open the pipe. If there is already a connection, use that */ +/* Search the cache for a connection. If there is a broken one, + shut it down properly and return NULL. */ -static NTSTATUS get_connection_from_cache(const char *domain, const char *pipe_name, - struct winbindd_cm_conn **conn_out) +static void find_cm_connection(const char *domain, const char *pipe_name, + struct winbindd_cm_conn **conn_out) { - struct winbindd_cm_conn *conn, conn_temp; - NTSTATUS result; - - *conn_out = NULL; + struct winbindd_cm_conn *conn; - for (conn = cm_conns; conn; conn = conn->next) { + for (conn = cm_conns; conn; ) { if (strequal(conn->domain, domain) && strequal(conn->pipe_name, pipe_name)) { if (!connection_ok(conn)) { + /* Dead connection - remove it. */ + struct winbindd_cm_conn *conn_temp = conn->next; if (conn->cli) cli_shutdown(conn->cli); - ZERO_STRUCT(conn_temp); - conn_temp.next = conn->next; DLIST_REMOVE(cm_conns, conn); SAFE_FREE(conn); - conn = &conn_temp; /* Just to keep the loop moving */ + conn = conn_temp; /* Keep the loop moving */ + continue; } else { break; } } + conn = conn->next; } - - if (!conn) { - if (!(conn = malloc(sizeof(*conn)))) - return NT_STATUS_NO_MEMORY; + + *conn_out = conn; +} + +/* Initialize a new connection up to the RPC BIND. */ + +static NTSTATUS new_cm_connection(const char *domain, const char *pipe_name, + struct winbindd_cm_conn **conn_out) +{ + struct winbindd_cm_conn *conn; + NTSTATUS result; + + if (!(conn = malloc(sizeof(*conn)))) + return NT_STATUS_NO_MEMORY; - ZERO_STRUCTP(conn); + ZERO_STRUCTP(conn); - if (!NT_STATUS_IS_OK(result = cm_open_connection(domain, get_pipe_index(pipe_name), conn))) { - DEBUG(3, ("Could not open a connection to %s for %s (%s)\n", - domain, pipe_name, nt_errstr(result))); - SAFE_FREE(conn); - return result; - } - DLIST_ADD(cm_conns, conn); + if (!NT_STATUS_IS_OK(result = cm_open_connection(domain, get_pipe_index(pipe_name), conn))) { + DEBUG(3, ("Could not open a connection to %s for %s (%s)\n", + domain, pipe_name, nt_errstr(result))); + SAFE_FREE(conn); + return result; } - + DLIST_ADD(cm_conns, conn); + *conn_out = conn; return NT_STATUS_OK; } +/* Get a connection to the remote DC and open the pipe. If there is already a connection, use that */ + +static NTSTATUS get_connection_from_cache(const char *domain, const char *pipe_name, + struct winbindd_cm_conn **conn_out) +{ + find_cm_connection(domain, pipe_name, conn_out); + + if (*conn_out != NULL) + return NT_STATUS_OK; + + return new_cm_connection(domain, pipe_name, conn_out); +} /********************************************************************************** **********************************************************************************/ @@ -625,244 +558,17 @@ CLI_POLICY_HND *cm_get_sam_handle(char *domain) return &hnd; } -#if 0 /* This code now *well* out of date */ - -/* Return a SAM domain policy handle on a domain */ - -CLI_POLICY_HND *cm_get_sam_dom_handle(char *domain, DOM_SID *domain_sid) -{ - struct winbindd_cm_conn *conn, *basic_conn = NULL; - static CLI_POLICY_HND hnd; - NTSTATUS result; - uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; - - /* Look for existing connections */ - - for (conn = cm_conns; conn; conn = conn->next) { - if (strequal(conn->domain, domain) && - strequal(conn->pipe_name, PIPE_SAMR) && - conn->pipe_data.samr.pipe_type == SAM_PIPE_DOM) { - - if (!connection_ok(conn)) { - /* Shutdown cli? Free conn? Allow retry of DC? */ - DLIST_REMOVE(cm_conns, conn); - return NULL; - } - - goto ok; - } - } - - /* Create a basic handle to open a domain handle from */ - - if (!cm_get_sam_handle(domain)) - return False; - - for (conn = cm_conns; conn; conn = conn->next) { - if (strequal(conn->domain, domain) && - strequal(conn->pipe_name, PIPE_SAMR) && - conn->pipe_data.samr.pipe_type == SAM_PIPE_BASIC) - basic_conn = conn; - } - - if (!(conn = (struct winbindd_cm_conn *) - malloc(sizeof(struct winbindd_cm_conn)))) - return NULL; - - ZERO_STRUCTP(conn); - - fstrcpy(conn->domain, basic_conn->domain); - fstrcpy(conn->controller, basic_conn->controller); - fstrcpy(conn->pipe_name, basic_conn->pipe_name); - - conn->pipe_data.samr.pipe_type = SAM_PIPE_DOM; - conn->cli = basic_conn->cli; - - result = cli_samr_open_domain(conn->cli, conn->cli->mem_ctx, - &basic_conn->pol, des_access, - domain_sid, &conn->pol); - - if (!NT_STATUS_IS_OK(result)) - return NULL; - - /* Add to list */ - - DLIST_ADD(cm_conns, conn); - - ok: - hnd.pol = conn->pol; - hnd.cli = conn->cli; - - return &hnd; -} - -/* Return a SAM policy handle on a domain user */ - -CLI_POLICY_HND *cm_get_sam_user_handle(char *domain, DOM_SID *domain_sid, - uint32 user_rid) -{ - struct winbindd_cm_conn *conn, *basic_conn = NULL; - static CLI_POLICY_HND hnd; - NTSTATUS result; - uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; - - /* Look for existing connections */ - - for (conn = cm_conns; conn; conn = conn->next) { - if (strequal(conn->domain, domain) && - strequal(conn->pipe_name, PIPE_SAMR) && - conn->pipe_data.samr.pipe_type == SAM_PIPE_USER && - conn->pipe_data.samr.rid == user_rid) { - - if (!connection_ok(conn)) { - /* Shutdown cli? Free conn? Allow retry of DC? */ - DLIST_REMOVE(cm_conns, conn); - return NULL; - } - - goto ok; - } - } - - /* Create a domain handle to open a user handle from */ - - if (!cm_get_sam_dom_handle(domain, domain_sid)) - return NULL; - - for (conn = cm_conns; conn; conn = conn->next) { - if (strequal(conn->domain, domain) && - strequal(conn->pipe_name, PIPE_SAMR) && - conn->pipe_data.samr.pipe_type == SAM_PIPE_DOM) - basic_conn = conn; - } - - if (!basic_conn) { - DEBUG(0, ("No domain sam handle was created!\n")); - return NULL; - } - - if (!(conn = (struct winbindd_cm_conn *) - malloc(sizeof(struct winbindd_cm_conn)))) - return NULL; - - ZERO_STRUCTP(conn); - - fstrcpy(conn->domain, basic_conn->domain); - fstrcpy(conn->controller, basic_conn->controller); - fstrcpy(conn->pipe_name, basic_conn->pipe_name); - - conn->pipe_data.samr.pipe_type = SAM_PIPE_USER; - conn->cli = basic_conn->cli; - conn->pipe_data.samr.rid = user_rid; - - result = cli_samr_open_user(conn->cli, conn->cli->mem_ctx, - &basic_conn->pol, des_access, user_rid, - &conn->pol); - - if (!NT_STATUS_IS_OK(result)) - return NULL; - - /* Add to list */ - - DLIST_ADD(cm_conns, conn); - - ok: - hnd.pol = conn->pol; - hnd.cli = conn->cli; - - return &hnd; -} - -/* Return a SAM policy handle on a domain group */ - -CLI_POLICY_HND *cm_get_sam_group_handle(char *domain, DOM_SID *domain_sid, - uint32 group_rid) -{ - struct winbindd_cm_conn *conn, *basic_conn = NULL; - static CLI_POLICY_HND hnd; - NTSTATUS result; - uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; - - /* Look for existing connections */ - - for (conn = cm_conns; conn; conn = conn->next) { - if (strequal(conn->domain, domain) && - strequal(conn->pipe_name, PIPE_SAMR) && - conn->pipe_data.samr.pipe_type == SAM_PIPE_GROUP && - conn->pipe_data.samr.rid == group_rid) { - - if (!connection_ok(conn)) { - /* Shutdown cli? Free conn? Allow retry of DC? */ - DLIST_REMOVE(cm_conns, conn); - return NULL; - } - - goto ok; - } - } - - /* Create a domain handle to open a user handle from */ - - if (!cm_get_sam_dom_handle(domain, domain_sid)) - return NULL; - - for (conn = cm_conns; conn; conn = conn->next) { - if (strequal(conn->domain, domain) && - strequal(conn->pipe_name, PIPE_SAMR) && - conn->pipe_data.samr.pipe_type == SAM_PIPE_DOM) - basic_conn = conn; - } - - if (!basic_conn) { - DEBUG(0, ("No domain sam handle was created!\n")); - return NULL; - } - - if (!(conn = (struct winbindd_cm_conn *) - malloc(sizeof(struct winbindd_cm_conn)))) - return NULL; - - ZERO_STRUCTP(conn); - - fstrcpy(conn->domain, basic_conn->domain); - fstrcpy(conn->controller, basic_conn->controller); - fstrcpy(conn->pipe_name, basic_conn->pipe_name); - - conn->pipe_data.samr.pipe_type = SAM_PIPE_GROUP; - conn->cli = basic_conn->cli; - conn->pipe_data.samr.rid = group_rid; - - result = cli_samr_open_group(conn->cli, conn->cli->mem_ctx, - &basic_conn->pol, des_access, group_rid, - &conn->pol); - - if (!NT_STATUS_IS_OK(result)) - return NULL; - - /* Add to list */ - - DLIST_ADD(cm_conns, conn); - - ok: - hnd.pol = conn->pol; - hnd.cli = conn->cli; - - return &hnd; -} - -#endif - /* Get a handle on a netlogon pipe. This is a bit of a hack to re-use the netlogon pipe as no handle is returned. */ NTSTATUS cm_get_netlogon_cli(const char *domain, const unsigned char *trust_passwd, uint32 sec_channel_type, + BOOL fresh, struct cli_state **cli) { NTSTATUS result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; struct winbindd_cm_conn *conn; - uint32 neg_flags = 0x000001ff; fstring lock_name; BOOL got_mutex; @@ -871,7 +577,30 @@ NTSTATUS cm_get_netlogon_cli(const char *domain, /* Open an initial conection - keep the mutex. */ - if (!NT_STATUS_IS_OK(result = get_connection_from_cache(domain, PIPE_NETLOGON, &conn))) + find_cm_connection(domain, PIPE_NETLOGON, &conn); + + if ( fresh && (conn != NULL) ) { + cli_shutdown(conn->cli); + conn->cli = NULL; + + conn = NULL; + + /* purge connection from cache */ + find_cm_connection(domain, PIPE_NETLOGON, &conn); + if (conn != NULL) { + DEBUG(0,("Could not purge connection\n")); + return NT_STATUS_UNSUCCESSFUL; + } + } + + if (conn != NULL) { + *cli = conn->cli; + return NT_STATUS_OK; + } + + result = new_cm_connection(domain, PIPE_NETLOGON, &conn); + + if (!NT_STATUS_IS_OK(result)) return result; snprintf(lock_name, sizeof(lock_name), "NETLOGON\\%s", conn->controller); @@ -880,38 +609,16 @@ NTSTATUS cm_get_netlogon_cli(const char *domain, DEBUG(0,("cm_get_netlogon_cli: mutex grab failed for %s\n", conn->controller)); } - result = cli_nt_setup_creds(conn->cli, sec_channel_type, trust_passwd, &neg_flags, 2); + result = cli_nt_establish_netlogon(conn->cli, sec_channel_type, trust_passwd); if (got_mutex) secrets_named_mutex_release(lock_name); - + if (!NT_STATUS_IS_OK(result)) { - DEBUG(0, ("error connecting to domain password server: %s\n", - nt_errstr(result))); - - /* Hit the cache code again. This cleans out the old connection and gets a new one */ - if (conn->cli->fd == -1) { - if (!NT_STATUS_IS_OK(result = get_connection_from_cache(domain, PIPE_NETLOGON, &conn))) - return result; - - snprintf(lock_name, sizeof(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)); - } - - /* Try again */ - result = cli_nt_setup_creds( conn->cli, sec_channel_type,trust_passwd, &neg_flags, 2); - - if (got_mutex) - secrets_named_mutex_release(lock_name); - } - - if (!NT_STATUS_IS_OK(result)) { - cli_shutdown(conn->cli); - DLIST_REMOVE(cm_conns, conn); - SAFE_FREE(conn); - return result; - } + cli_shutdown(conn->cli); + DLIST_REMOVE(cm_conns, conn); + SAFE_FREE(conn); + return result; } *cli = conn->cli; diff --git a/source/nsswitch/winbindd_misc.c b/source/nsswitch/winbindd_misc.c index fb56d0e6574..8d7cdc47317 100644 --- a/source/nsswitch/winbindd_misc.c +++ b/source/nsswitch/winbindd_misc.c @@ -50,7 +50,7 @@ enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *stat the trust account password. */ /* Don't shut this down - it belongs to the connection cache code */ - result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, sec_channel_type, &cli); + result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, sec_channel_type, True, &cli); if (!NT_STATUS_IS_OK(result)) { DEBUG(3, ("could not open handle to NETLOGON pipe\n")); diff --git a/source/nsswitch/winbindd_pam.c b/source/nsswitch/winbindd_pam.c index 2998372bd21..3b306eed3b2 100644 --- a/source/nsswitch/winbindd_pam.c +++ b/source/nsswitch/winbindd_pam.c @@ -68,6 +68,8 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) TALLOC_CTX *mem_ctx = NULL; DATA_BLOB lm_resp; DATA_BLOB nt_resp; + DOM_CRED ret_creds; + int attempts = 0; /* Ensure null termination */ state->request.data.auth.user[sizeof(state->request.data.auth.user)-1]='\0'; @@ -119,23 +121,35 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) goto done; } - ZERO_STRUCT(info3); + do { + ZERO_STRUCT(info3); + ZERO_STRUCT(ret_creds); - /* Don't shut this down - it belongs to the connection cache code */ - result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, - sec_channel_type, - &cli); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(3, ("could not open handle to NETLOGON pipe\n")); - goto done; - } - - result = cli_netlogon_sam_network_logon(cli, mem_ctx, - name_user, name_domain, - global_myname(), chal, - lm_resp, nt_resp, - &info3); + /* Don't shut this down - it belongs to the connection cache code */ + result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, + sec_channel_type, False, &cli); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(3, ("could not open handle to NETLOGON pipe\n")); + goto done; + } + + result = cli_netlogon_sam_network_logon(cli, mem_ctx, + &ret_creds, + name_user, name_domain, + global_myname(), chal, + lm_resp, nt_resp, + &info3); + attempts += 1; + + /* We have to try a second time as cm_get_netlogon_cli + might not yet have noticed that the DC has killed + our connection. */ + + } while ( (attempts < 2) && (cli->fd == -1) ); + + + clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &ret_creds); uni_group_cache_store_netlogon(mem_ctx, &info3); done: @@ -176,6 +190,8 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) const char *domain = NULL; const char *contact_domain; const char *workstation; + DOM_CRED ret_creds; + int attempts = 0; DATA_BLOB lm_resp, nt_resp; @@ -264,21 +280,37 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) goto done; } - ZERO_STRUCT(info3); + do { + ZERO_STRUCT(info3); + ZERO_STRUCT(ret_creds); + + /* Don't shut this down - it belongs to the connection cache code */ + result = cm_get_netlogon_cli(contact_domain, trust_passwd, + sec_channel_type, False, &cli); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(3, ("could not open handle to NETLOGON pipe (error: %s)\n", + nt_errstr(result))); + goto done; + } + + result = cli_netlogon_sam_network_logon(cli, mem_ctx, + &ret_creds, + user, domain, + workstation, + state->request.data.auth_crap.chal, + lm_resp, nt_resp, + &info3); + + attempts += 1; - /* Don't shut this down - it belongs to the connection cache code */ - result = cm_get_netlogon_cli(contact_domain, trust_passwd, sec_channel_type, &cli); + /* We have to try a second time as cm_get_netlogon_cli + might not yet have noticed that the DC has killed + our connection. */ - if (!NT_STATUS_IS_OK(result)) { - DEBUG(3, ("could not open handle to NETLOGON pipe (error: %s)\n", nt_errstr(result))); - goto done; - } + } while ( (attempts < 2) && (cli->fd == -1) ); - result = cli_netlogon_sam_network_logon(cli, mem_ctx, - user, domain, - workstation, state->request.data.auth_crap.chal, - lm_resp, nt_resp, - &info3); + clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &ret_creds); if (NT_STATUS_IS_OK(result)) { uni_group_cache_store_netlogon(mem_ctx, &info3); diff --git a/source/param/loadparm.c b/source/param/loadparm.c index 3925a569ca5..a5e9b1467f2 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -109,6 +109,8 @@ typedef struct char *szRootdir; char *szDefaultService; char *szDfree; + char *szGetQuota; + char *szSetQuota; char *szMsgCommand; char *szHostsEquiv; char *szServerString; @@ -221,6 +223,8 @@ typedef struct int iLockSpinTime; char *szLdapMachineSuffix; char *szLdapUserSuffix; + char *szLdapIdmapSuffix; + char *szLdapGroupSuffix; #ifdef WITH_LDAP_SAMCONFIG int ldap_port; char *szLdapServer; @@ -339,9 +343,7 @@ typedef struct char **printer_admin; char *volume; char *fstype; - char *szVfsObjectFile; - char *szVfsOptions; - char *szVfsPath; + char **szVfsObjects; char *szMSDfsProxy; int iMinPrintSpace; int iMaxPrintJobs; @@ -460,9 +462,7 @@ static service sDefault = { NULL, /* printer admin */ NULL, /* volume */ NULL, /* fstype */ - NULL, /* vfs object */ - NULL, /* vfs options */ - NULL, /* vfs path */ + NULL, /* vfs objects */ NULL, /* szMSDfsProxy */ 0, /* iMinPrintSpace */ 1000, /* iMaxPrintJobs */ @@ -562,9 +562,8 @@ static BOOL handle_workgroup( const char *pszParmValue, char **ptr ); static BOOL handle_netbios_aliases( const char *pszParmValue, char **ptr ); static BOOL handle_netbios_scope( const char *pszParmValue, char **ptr ); -static BOOL handle_ldap_machine_suffix ( const char *pszParmValue, char **ptr ); -static BOOL handle_ldap_user_suffix ( const char *pszParmValue, char **ptr ); static BOOL handle_ldap_suffix ( const char *pszParmValue, char **ptr ); +static BOOL handle_ldap_sub_suffix ( const char *pszParmValue, char **ptr ); static BOOL handle_acl_compatibility(const char *pszParmValue, char **ptr); @@ -751,8 +750,8 @@ static struct parm_struct parm_table[] = { {"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}, - {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC}, + {"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}, @@ -763,7 +762,7 @@ static struct parm_struct parm_table[] = { {"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_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}, @@ -804,12 +803,12 @@ static struct parm_struct parm_table[] = { {"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 | 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 | 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}, @@ -856,11 +855,11 @@ static struct parm_struct parm_table[] = { {"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}, - {"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE | FLAG_ADVANCED | FLAG_WIZARD}, + {"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 | FLAG_WIZARD}, + {"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}, @@ -1003,6 +1002,7 @@ static struct parm_struct parm_table[] = { {"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}, @@ -1027,7 +1027,7 @@ static struct parm_struct parm_table[] = { {"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}, + {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, {"Ldap Options", P_SEP, P_SEPARATOR}, @@ -1036,8 +1036,10 @@ static struct parm_struct parm_table[] = { {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, 0}, #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_machine_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, handle_ldap_user_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}, @@ -1066,6 +1068,8 @@ static struct parm_struct parm_table[] = { {"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}, @@ -1104,10 +1108,9 @@ static struct parm_struct parm_table[] = { {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"VFS module options", P_SEP, P_SEPARATOR}, - - {"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjectFile, NULL, NULL, FLAG_SHARE}, - {"vfs options", P_STRING, P_LOCAL, &sDefault.szVfsOptions, NULL, NULL, FLAG_SHARE}, - {"vfs path", P_STRING, P_LOCAL, &sDefault.szVfsPath, NULL, NULL, FLAG_SHARE}, + + {"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}, @@ -1119,9 +1122,7 @@ static struct parm_struct parm_table[] = { {"idmap only", P_BOOL, P_GLOBAL, &Globals.bIdmapOnly, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"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 | FLAG_HIDE}, {"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 | FLAG_HIDE}, {"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}, @@ -1341,8 +1342,8 @@ static void init_globals(void) Globals.paranoid_server_security = True; Globals.bEncryptPasswords = True; Globals.bUpdateEncrypt = False; - Globals.clientSchannel = False; - Globals.serverSchannel = False; + Globals.clientSchannel = Auto; + Globals.serverSchannel = Auto; Globals.bReadRaw = True; Globals.bWriteRaw = True; Globals.bReadPrediction = False; @@ -1410,7 +1411,7 @@ static void init_globals(void) #ifdef WITH_LDAP_SAMCONFIG string_set(&Globals.szLdapServer, "localhost"); Globals.ldap_port = 636; - Globals.szPassdbBackend = str_list_make("ldapsam guest", NULL); + Globals.szPassdbBackend = str_list_make("ldapsam_compat guest", NULL); #else Globals.szPassdbBackend = str_list_make("smbpasswd guest", NULL); #endif /* WITH_LDAP_SAMCONFIG */ @@ -1419,6 +1420,8 @@ static void init_globals(void) string_set(&Globals.szLdapFilter, "(uid=%u)"); string_set(&Globals.szLdapMachineSuffix, ""); string_set(&Globals.szLdapUserSuffix, ""); + string_set(&Globals.szLdapGroupSuffix, ""); + string_set(&Globals.szLdapIdmapSuffix, ""); string_set(&Globals.szLdapAdminDn, ""); Globals.ldap_ssl = LDAP_SSL_ON; @@ -1496,8 +1499,7 @@ void lp_talloc_free(void) static char *lp_string(const char *s) { - size_t len = s ? strlen(s) : 0; - char *ret; + char *ret, *tmpstr; /* The follow debug is useful for tracking down memory problems especially if you have an inner loop that is calling a lp_*() @@ -1511,25 +1513,16 @@ static char *lp_string(const char *s) if (!lp_talloc) lp_talloc = talloc_init("lp_talloc"); - ret = (char *)talloc(lp_talloc, len + 100); /* leave room for substitution */ - - if (!ret) - return NULL; - - /* Note: StrnCpy touches len+1 bytes, but we allocate 100 - * extra bytes so we're OK. */ - - if (!s) - *ret = 0; - else - StrnCpy(ret, s, len); - - if (trim_string(ret, "\"", "\"")) { - if (strchr(ret,'"') != NULL) - StrnCpy(ret, s, len); + tmpstr = alloc_sub_basic(current_user_info.smb_name, s); + if (trim_string(tmpstr, "\"", "\"")) { + if (strchr(tmpstr,'"') != NULL) { + SAFE_FREE(tmpstr); + tmpstr = alloc_sub_basic(current_user_info.smb_name,s); + } } - - standard_sub_basic(current_user_info.smb_name,ret,len+100); + ret = talloc_strdup(lp_talloc, tmpstr); + SAFE_FREE(tmpstr); + return (ret); } @@ -1592,6 +1585,8 @@ FN_GLOBAL_STRING(lp_source_environment, &Globals.szSourceEnv) FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService) FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand) FN_GLOBAL_STRING(lp_dfree_command, &Globals.szDfree) +FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota) +FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota) FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv) FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices) FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram) @@ -1651,6 +1646,8 @@ FN_GLOBAL_INTEGER(lp_ldap_port, &Globals.ldap_port) FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix) FN_GLOBAL_STRING(lp_ldap_machine_suffix, &Globals.szLdapMachineSuffix) FN_GLOBAL_STRING(lp_ldap_user_suffix, &Globals.szLdapUserSuffix) +FN_GLOBAL_STRING(lp_ldap_idmap_suffix, &Globals.szLdapIdmapSuffix) +FN_GLOBAL_STRING(lp_ldap_group_suffix, &Globals.szLdapGroupSuffix) FN_GLOBAL_STRING(lp_ldap_filter, &Globals.szLdapFilter) FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn) FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl) @@ -1777,9 +1774,7 @@ FN_LOCAL_LIST(lp_readlist, readlist) FN_LOCAL_LIST(lp_writelist, writelist) FN_LOCAL_LIST(lp_printer_admin, printer_admin) FN_LOCAL_STRING(lp_fstype, fstype) -FN_LOCAL_LIST(lp_vfsobj, szVfsObjectFile) -FN_LOCAL_STRING(lp_vfs_options, szVfsOptions) -FN_LOCAL_STRING(lp_vfs_path, szVfsPath) +FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects) FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy) static FN_LOCAL_STRING(lp_volume, volume) FN_LOCAL_STRING(lp_mangled_map, szMangledMap) @@ -2259,6 +2254,7 @@ BOOL lp_add_home(const char *pszHomename, int iDefaultService, } else { pstrcpy(newHomedir, lp_pathname(iDefaultService)); string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir)); + string_sub(newHomedir,"%S", pszHomename, sizeof(newHomedir)); } string_set(&ServicePtrs[i]->szPath, newHomedir); @@ -2942,91 +2938,61 @@ static BOOL handle_debug_list( const char *pszParmValueIn, char **ptr ) } /*************************************************************************** - Handle the ldap machine suffix option. + Handle setting ldap suffix and determines whether ldap machine suffix needs + to be set as well. + + Set all of the sub suffix strings to be the 'ldap suffix' by default ***************************************************************************/ -static BOOL handle_ldap_machine_suffix( const char *pszParmValue, char **ptr) +static BOOL handle_ldap_suffix( const char *pszParmValue, char **ptr ) { - pstring suffix; - - pstrcpy(suffix, pszParmValue); - - if (! *Globals.szLdapSuffix ) { - string_set( ptr, suffix ); - return True; - } - - if (! strstr(suffix, Globals.szLdapSuffix) ) { - if ( *pszParmValue ) - pstrcat(suffix, ","); - pstrcat(suffix, Globals.szLdapSuffix); - } - string_set( ptr, suffix ); - return True; + pstring suffix; + + pstrcpy(suffix, pszParmValue); + + /* set defaults for the the sub-suffixes */ + + if (! *Globals.szLdapMachineSuffix ) + string_set(&Globals.szLdapMachineSuffix, suffix); + if (! *Globals.szLdapUserSuffix ) + string_set(&Globals.szLdapUserSuffix, suffix); + if (! *Globals.szLdapGroupSuffix ) + string_set(&Globals.szLdapGroupSuffix, suffix); + if (! *Globals.szLdapIdmapSuffix ) + string_set(&Globals.szLdapIdmapSuffix, suffix); + + string_set(ptr, suffix); + return True; } /*************************************************************************** - Handle the ldap user suffix option. + Handle the ldap sub suffix option. + Always append the 'ldap suffix' if it is set ***************************************************************************/ -static BOOL handle_ldap_user_suffix( const char *pszParmValue, char **ptr) +static BOOL handle_ldap_sub_suffix( const char *pszParmValue, char **ptr) { - pstring suffix; + pstring suffix; - pstrcpy(suffix, pszParmValue); + pstrcpy(suffix, pszParmValue); - if (! *Globals.szLdapSuffix ) { - string_set( ptr, suffix ); - return True; - } - - if (! strstr(suffix, Globals.szLdapSuffix) ) { - if ( *pszParmValue ) - pstrcat(suffix, ","); - pstrcat(suffix, Globals.szLdapSuffix); - } - string_set( ptr, suffix ); - return True; + if (! *Globals.szLdapSuffix ) { + string_set( ptr, suffix ); + return True; + } + else { + if ( *pszParmValue ) + pstrcat(suffix, ","); + pstrcat(suffix, Globals.szLdapSuffix); + } + + string_set( ptr, suffix ); + return True; } /*************************************************************************** - Handle setting ldap suffix and determines whether ldap machine suffix needs - to be set as well. ***************************************************************************/ -static BOOL handle_ldap_suffix( const char *pszParmValue, char **ptr) -{ - pstring suffix; - pstring user_suffix; - pstring machine_suffix; - - pstrcpy(suffix, pszParmValue); - - if (! *Globals.szLdapMachineSuffix ) - string_set(&Globals.szLdapMachineSuffix, suffix); - if (! *Globals.szLdapUserSuffix ) - string_set(&Globals.szLdapUserSuffix, suffix); - - if (! strstr(Globals.szLdapMachineSuffix, suffix)) { - pstrcpy(machine_suffix, Globals.szLdapMachineSuffix); - if ( *Globals.szLdapMachineSuffix ) - pstrcat(machine_suffix, ","); - pstrcat(machine_suffix, suffix); - string_set(&Globals.szLdapMachineSuffix, machine_suffix); - } - - if (! strstr(Globals.szLdapUserSuffix, suffix)) { - pstrcpy(user_suffix, Globals.szLdapUserSuffix); - if ( *Globals.szLdapUserSuffix ) - pstrcat(user_suffix, ","); - pstrcat(user_suffix, suffix); - string_set(&Globals.szLdapUserSuffix, user_suffix); - } - - string_set(ptr, suffix); - return True; -} - static BOOL handle_acl_compatibility(const char *pszParmValue, char **ptr) { if (strequal(pszParmValue, "auto")) @@ -3040,6 +3006,7 @@ static BOOL handle_acl_compatibility(const char *pszParmValue, char **ptr) return True; } + /*************************************************************************** Initialise a copymap. ***************************************************************************/ @@ -4242,7 +4209,7 @@ void lp_set_logfile(const char *name) } /******************************************************************* - Return the NetBIOS called name. + Return the NetBIOS called name, or my IP - but never global_myname(). ********************************************************************/ const char *get_called_name(void) @@ -4250,22 +4217,11 @@ const char *get_called_name(void) extern fstring local_machine; static fstring called_name; - if (! *local_machine) - return global_myname(); - - /* - * Windows NT/2k uses "*SMBSERVER" and XP uses "*SMBSERV" - * arrggg!!! but we've already rewritten the client's - * netbios name at this point... - */ - - if (*local_machine) { - if (!StrCaseCmp(local_machine, "_SMBSERVER") || !StrCaseCmp(local_machine, "_SMBSERV")) { - fstrcpy(called_name, get_my_primary_ip()); - DEBUG(8,("get_called_name: assuming that client used IP address [%s] as called name.\n", - called_name)); - return called_name; - } + if (!*local_machine) { + fstrcpy(called_name, get_my_primary_ip()); + DEBUG(8,("get_called_name: assuming that client used IP address [%s] as called name.\n", + called_name)); + return called_name; } return local_machine; diff --git a/source/passdb/pdb_interface.c b/source/passdb/pdb_interface.c index 7b44df193fc..7640228ab98 100644 --- a/source/passdb/pdb_interface.c +++ b/source/passdb/pdb_interface.c @@ -74,7 +74,7 @@ static struct pdb_init_function_entry *pdb_find_backend_entry(const char *name) struct pdb_init_function_entry *entry = backends; while(entry) { - if (strcasecmp(entry->name, name) == 0) return entry; + if (strcmp(entry->name, name)==0) return entry; entry = entry->next; } diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c index fb63e81d28b..3ddbd99ca3b 100644 --- a/source/passdb/pdb_ldap.c +++ b/source/passdb/pdb_ldap.c @@ -59,6 +59,8 @@ #define SAM_ACCOUNT struct sam_passwd #endif +#include "smbldap.h" + struct ldapsam_privates { /* Former statics */ LDAP *ldap_struct; @@ -93,177 +95,6 @@ struct ldapsam_privates { static struct ldapsam_privates *static_ldap_state; -/* specify schema versions between 2.2. and 3.0 */ - -#define SCHEMAVER_SAMBAACCOUNT 1 -#define SCHEMAVER_SAMBASAMACCOUNT 2 - -/* objectclass names */ - -#define LDAP_OBJ_SAMBASAMACCOUNT "sambaSamAccount" -#define LDAP_OBJ_SAMBAACCOUNT "sambaAccount" -#define LDAP_OBJ_GROUPMAP "sambaGroupMapping" -#define LDAP_OBJ_DOMINFO "sambaDomain" - -#define LDAP_OBJ_ACCOUNT "account" -#define LDAP_OBJ_POSIXACCOUNT "posixAccount" -#define LDAP_OBJ_POSIXGROUP "posixGroup" - -/* some generic attributes that get reused a lot */ - -#define LDAP_ATTRIBUTE_SID "sambaSID" - -/* attribute map table indexes */ - -#define LDAP_ATTR_LIST_END 0 -#define LDAP_ATTR_UID 1 -#define LDAP_ATTR_UIDNUMBER 2 -#define LDAP_ATTR_GIDNUMBER 3 -#define LDAP_ATTR_UNIX_HOME 4 -#define LDAP_ATTR_PWD_LAST_SET 5 -#define LDAP_ATTR_PWD_CAN_CHANGE 6 -#define LDAP_ATTR_PWD_MUST_CHANGE 7 -#define LDAP_ATTR_LOGON_TIME 8 -#define LDAP_ATTR_LOGOFF_TIME 9 -#define LDAP_ATTR_KICKOFF_TIME 10 -#define LDAP_ATTR_CN 11 -#define LDAP_ATTR_DISPLAY_NAME 12 -#define LDAP_ATTR_HOME_PATH 13 -#define LDAP_ATTR_LOGON_SCRIPT 14 -#define LDAP_ATTR_PROFILE_PATH 15 -#define LDAP_ATTR_DESC 16 -#define LDAP_ATTR_USER_WKS 17 -#define LDAP_ATTR_USER_SID 18 -#define LDAP_ATTR_USER_RID 18 -#define LDAP_ATTR_PRIMARY_GROUP_SID 19 -#define LDAP_ATTR_PRIMARY_GROUP_RID 20 -#define LDAP_ATTR_LMPW 21 -#define LDAP_ATTR_NTPW 22 -#define LDAP_ATTR_DOMAIN 23 -#define LDAP_ATTR_OBJCLASS 24 -#define LDAP_ATTR_ACB_INFO 25 -#define LDAP_ATTR_NEXT_USERRID 26 -#define LDAP_ATTR_NEXT_GROUPRID 27 -#define LDAP_ATTR_DOM_SID 28 -#define LDAP_ATTR_HOME_DRIVE 29 -#define LDAP_ATTR_GROUP_SID 30 -#define LDAP_ATTR_GROUP_TYPE 31 - - -typedef struct _attrib_map_entry { - int attrib; - const char *name; -} ATTRIB_MAP_ENTRY; - - -/* attributes used by Samba 2.2 */ - -static ATTRIB_MAP_ENTRY attrib_map_v22[] = { - { LDAP_ATTR_UID, "uid" }, - { LDAP_ATTR_UIDNUMBER, "uidNumber" }, - { LDAP_ATTR_GIDNUMBER, "gidNumber" }, - { LDAP_ATTR_UNIX_HOME, "homeDirectory" }, - { LDAP_ATTR_PWD_LAST_SET, "pwdLastSet" }, - { LDAP_ATTR_PWD_CAN_CHANGE, "pwdCanChange" }, - { LDAP_ATTR_PWD_MUST_CHANGE, "pwdMustChange" }, - { LDAP_ATTR_LOGON_TIME, "logonTime" }, - { LDAP_ATTR_LOGOFF_TIME, "logoffTime" }, - { LDAP_ATTR_KICKOFF_TIME, "kickoffTime" }, - { LDAP_ATTR_CN, "cn" }, - { LDAP_ATTR_DISPLAY_NAME, "displayName" }, - { LDAP_ATTR_HOME_PATH, "smbHome" }, - { LDAP_ATTR_HOME_DRIVE, "homeDrives" }, - { LDAP_ATTR_LOGON_SCRIPT, "scriptPath" }, - { LDAP_ATTR_PROFILE_PATH, "profilePath" }, - { LDAP_ATTR_DESC, "description" }, - { LDAP_ATTR_USER_WKS, "userWorkstations"}, - { LDAP_ATTR_USER_RID, "rid" }, - { LDAP_ATTR_PRIMARY_GROUP_RID, "primaryGroupID"}, - { LDAP_ATTR_LMPW, "lmPassword" }, - { LDAP_ATTR_NTPW, "ntPassword" }, - { LDAP_ATTR_DOMAIN, "domain" }, - { LDAP_ATTR_OBJCLASS, "objectClass" }, - { LDAP_ATTR_ACB_INFO, "acctFlags" }, - { LDAP_ATTR_LIST_END, NULL } -}; - -/* attributes used by Samba 3.0's sambaSamAccount */ - -static ATTRIB_MAP_ENTRY attrib_map_v30[] = { - { LDAP_ATTR_UID, "uid" }, - { LDAP_ATTR_UIDNUMBER, "uidNumber" }, - { LDAP_ATTR_GIDNUMBER, "gidNumber" }, - { LDAP_ATTR_UNIX_HOME, "homeDirectory" }, - { LDAP_ATTR_PWD_LAST_SET, "sambaPwdLastSet" }, - { LDAP_ATTR_PWD_CAN_CHANGE, "sambaPwdCanChange" }, - { LDAP_ATTR_PWD_MUST_CHANGE, "sambaPwdMustChange" }, - { LDAP_ATTR_LOGON_TIME, "sambaLogonTime" }, - { LDAP_ATTR_LOGOFF_TIME, "sambaLogoffTime" }, - { LDAP_ATTR_KICKOFF_TIME, "sambaKickoffTime" }, - { LDAP_ATTR_CN, "cn" }, - { LDAP_ATTR_DISPLAY_NAME, "displayName" }, - { LDAP_ATTR_HOME_DRIVE, "sambaHomeDrive" }, - { LDAP_ATTR_HOME_PATH, "sambaHomePath" }, - { LDAP_ATTR_LOGON_SCRIPT, "sambaLogonScript" }, - { LDAP_ATTR_PROFILE_PATH, "sambaProfilePath" }, - { LDAP_ATTR_DESC, "description" }, - { LDAP_ATTR_USER_WKS, "sambaUserWorkstations" }, - { LDAP_ATTR_USER_SID, "sambaSID" }, - { LDAP_ATTR_PRIMARY_GROUP_SID, "sambaPrimaryGroupSID" }, - { LDAP_ATTR_LMPW, "sambaLMPassword" }, - { LDAP_ATTR_NTPW, "sambaNTPassword" }, - { LDAP_ATTR_DOMAIN, "sambaDomainName" }, - { LDAP_ATTR_OBJCLASS, "objectClass" }, - { LDAP_ATTR_ACB_INFO, "sambaAcctFlags" }, - { LDAP_ATTR_LIST_END, NULL } -}; - -/* attributes used for alalocating RIDs */ - -static ATTRIB_MAP_ENTRY dominfo_attr_list[] = { - { LDAP_ATTR_DOMAIN, "sambaDomainName" }, - { LDAP_ATTR_NEXT_USERRID, "sambaNextUserRid" }, - { LDAP_ATTR_NEXT_GROUPRID, "sambaNextGroupRid" }, - { LDAP_ATTR_DOM_SID, "sambaSID" }, - { LDAP_ATTR_LIST_END, NULL }, -}; - -/* Samba 3.0 group mapping attributes */ - -static ATTRIB_MAP_ENTRY groupmap_attr_list[] = { - { LDAP_ATTR_GIDNUMBER, "gidNumber" }, - { LDAP_ATTR_GROUP_SID, "sambaSID" }, - { LDAP_ATTR_GROUP_TYPE, "sambaGroupType" }, - { LDAP_ATTR_DESC, "description" }, - { LDAP_ATTR_DISPLAY_NAME, "displayName" }, - { LDAP_ATTR_CN, "cn" }, - { LDAP_ATTR_LIST_END, NULL } -}; - -static ATTRIB_MAP_ENTRY groupmap_attr_list_to_delete[] = { - { LDAP_ATTR_GROUP_SID, "sambaSID" }, - { LDAP_ATTR_GROUP_TYPE, "sambaGroupType" }, - { LDAP_ATTR_DESC, "description" }, - { LDAP_ATTR_DISPLAY_NAME, "displayName" }, - { LDAP_ATTR_LIST_END, NULL } -}; - -/********************************************************************** - perform a simple table lookup and return the attribute name - **********************************************************************/ - -static const char* get_attr_key2string( ATTRIB_MAP_ENTRY table[], int key ) -{ - int i = 0; - - while ( table[i].attrib != LDAP_ATTR_LIST_END ) { - if ( table[i].attrib == key ) - return table[i].name; - i++; - } - - return NULL; -} /********************************************************************** get the attribute name given a user schame version @@ -287,52 +118,6 @@ static const char* get_userattr_key2string( int schema_ver, int key ) } /********************************************************************** - Return the list of attribute names from a mapping table - **********************************************************************/ - -static char** get_attr_list( ATTRIB_MAP_ENTRY table[] ) -{ - char **names; - int i = 0; - - while ( table[i].attrib != LDAP_ATTR_LIST_END ) - i++; - i++; - - names = (char**)malloc( sizeof(char*)*i ); - if ( !names ) { - DEBUG(0,("get_attr_list: out of memory\n")); - return NULL; - } - - i = 0; - while ( table[i].attrib != LDAP_ATTR_LIST_END ) { - names[i] = strdup( table[i].name ); - i++; - } - names[i] = NULL; - - return names; -} - -/********************************************************************* - Cleanup - ********************************************************************/ - -static void free_attr_list( char **list ) -{ - int i = 0; - - if ( !list ) - return; - - while ( list[i] ) - SAFE_FREE( list[i] ); - - SAFE_FREE( list ); -} - -/********************************************************************** return the list of attribute names given a user schema version **********************************************************************/ @@ -352,70 +137,6 @@ static char** get_userattr_list( int schema_ver ) return NULL; } - -/******************************************************************* - find the ldap password -******************************************************************/ -static BOOL fetch_ldapsam_pw(char **dn, char** pw) -{ - char *key = NULL; - size_t size; - - *dn = smb_xstrdup(lp_ldap_admin_dn()); - - if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) { - SAFE_FREE(*dn); - DEBUG(0, ("fetch_ldapsam_pw: asprintf failed!\n")); - } - - *pw=secrets_fetch(key, &size); - SAFE_FREE(key); - - if (!size) { - /* Upgrade 2.2 style entry */ - char *p; - char* old_style_key = strdup(*dn); - char *data; - fstring old_style_pw; - - if (!old_style_key) { - DEBUG(0, ("fetch_ldapsam_pw: strdup failed!\n")); - return False; - } - - for (p=old_style_key; *p; p++) - if (*p == ',') *p = '/'; - - data=secrets_fetch(old_style_key, &size); - if (!size && size < sizeof(old_style_pw)) { - DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n")); - SAFE_FREE(old_style_key); - SAFE_FREE(*dn); - return False; - } - - strncpy(old_style_pw, data, size); - old_style_pw[size] = 0; - - SAFE_FREE(data); - - if (!secrets_store_ldap_pw(*dn, old_style_pw)) { - DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n")); - SAFE_FREE(old_style_key); - SAFE_FREE(*dn); - return False; - } - if (!secrets_delete(old_style_key)) { - DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n")); - } - - SAFE_FREE(old_style_key); - - *pw = smb_xstrdup(old_style_pw); - } - - return True; -} /******************************************************************* open a connection to the ldap server. @@ -632,7 +353,7 @@ static int ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * ld static_ldap_state = ldap_state; /* get the password */ - if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret)) + if (!fetch_ldap_pw(&ldap_dn, &ldap_secret)) { DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n")); return LDAP_INVALID_CREDENTIALS; @@ -1097,93 +818,6 @@ static BOOL get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry, return True; } -/************************************************************************ -Routine to manage the LDAPMod structure array -manage memory used by the array, by each struct, and values - -************************************************************************/ -static void make_a_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value) -{ - LDAPMod **mods; - int i; - int j; - - mods = *modlist; - - /* sanity checks on the mod values */ - - if (attribute == NULL || *attribute == '\0') - return; -#if 0 /* commented out after discussion with abartlet. Do not reenable. - left here so other so re-add similar code --jerry */ - if (value == NULL || *value == '\0') - return; -#endif - - if (mods == NULL) - { - mods = (LDAPMod **) malloc(sizeof(LDAPMod *)); - if (mods == NULL) - { - DEBUG(0, ("make_a_mod: out of memory!\n")); - return; - } - mods[0] = NULL; - } - - for (i = 0; mods[i] != NULL; ++i) { - if (mods[i]->mod_op == modop && !strcasecmp(mods[i]->mod_type, attribute)) - break; - } - - if (mods[i] == NULL) - { - mods = (LDAPMod **) Realloc (mods, (i + 2) * sizeof (LDAPMod *)); - if (mods == NULL) - { - DEBUG(0, ("make_a_mod: out of memory!\n")); - return; - } - mods[i] = (LDAPMod *) malloc(sizeof(LDAPMod)); - if (mods[i] == NULL) - { - DEBUG(0, ("make_a_mod: out of memory!\n")); - return; - } - mods[i]->mod_op = modop; - mods[i]->mod_values = NULL; - mods[i]->mod_type = strdup(attribute); - mods[i + 1] = NULL; - } - - if (value != NULL) - { - char *utf8_value = NULL; - - j = 0; - if (mods[i]->mod_values != NULL) { - for (; mods[i]->mod_values[j] != NULL; j++); - } - mods[i]->mod_values = (char **)Realloc(mods[i]->mod_values, - (j + 2) * sizeof (char *)); - - if (mods[i]->mod_values == NULL) { - DEBUG (0, ("make_a_mod: Memory allocation failure!\n")); - return; - } - - if (push_utf8_allocate(&utf8_value, value) == (size_t)-1) { - DEBUG (0, ("make_a_mod: String conversion failure!\n")); - return; - } - - mods[i]->mod_values[j] = utf8_value; - - mods[i]->mod_values[j + 1] = NULL; - } - *modlist = mods; -} - /********************************************************************** Set attribute to newval in LDAP, regardless of what value the attribute had in LDAP before. @@ -1217,7 +851,7 @@ static void make_ldap_mod(LDAP *ldap_struct, LDAPMessage *existing, the old value, should it exist. */ if ((newval != NULL) && (strlen(newval) > 0)) { - make_a_mod(mods, LDAP_MOD_ADD, attribute, newval); + ldap_set_mod(mods, LDAP_MOD_ADD, attribute, newval); } if (values == NULL) { @@ -1232,7 +866,7 @@ static void make_ldap_mod(LDAP *ldap_struct, LDAPMessage *existing, deny the complete operation if somebody changed the attribute behind our back. */ - make_a_mod(mods, LDAP_MOD_DELETE, attribute, values[0]); + ldap_set_mod(mods, LDAP_MOD_DELETE, attribute, values[0]); ldap_value_free(values); } @@ -1288,7 +922,7 @@ static NTSTATUS ldapsam_delete_entry(struct ldapsam_privates *ldap_state, { if (StrCaseCmp(*attrib, name) == 0) { DEBUG(10, ("deleting attribute %s\n", name)); - make_a_mod(&mods, LDAP_MOD_DELETE, name, NULL); + ldap_set_mod(&mods, LDAP_MOD_DELETE, name, NULL); } } @@ -1299,10 +933,10 @@ static NTSTATUS ldapsam_delete_entry(struct ldapsam_privates *ldap_state, ber_free(ptr, 0); } - make_a_mod(&mods, LDAP_MOD_DELETE, "objectClass", objectclass); + ldap_set_mod(&mods, LDAP_MOD_DELETE, "objectClass", objectclass); rc = ldapsam_modify(ldap_state, dn, mods); - ldap_mods_free(mods, 1); + ldap_mods_free(mods, True); if (rc != LDAP_SUCCESS) { char *ld_error = NULL; @@ -1488,12 +1122,11 @@ static uint32 search_next_allocated_rid(struct ldapsam_privates *ldap_state, int static NTSTATUS add_new_domain_info(struct ldapsam_privates *ldap_state) { pstring tmp; - pstring filter; + pstring filter, dn; LDAPMod **mods = NULL; int rc; int ldap_op; LDAPMessage *result = NULL; - char *dn = NULL; int num_result; char **attr_list; @@ -1533,29 +1166,26 @@ static NTSTATUS add_new_domain_info(struct ldapsam_privates *ldap_state) /* Check if we need to add an entry */ DEBUG(3,("Adding new domain\n")); ldap_op = LDAP_MOD_ADD; - asprintf (&dn, "%s=%s,%s", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), + snprintf(dn, sizeof(dn), "%s=%s,%s", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), ldap_state->domain_name, lp_ldap_suffix()); /* Free original search */ ldap_msgfree(result); - if (!dn) - return NT_STATUS_NO_MEMORY; - /* make the changes - the entry *must* not already have samba attributes */ - make_a_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), + ldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), ldap_state->domain_name); sid_to_string(tmp, &ldap_state->domain_sid); - make_a_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID), tmp); + ldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID), tmp); snprintf(tmp, sizeof(tmp)-1, "%i", next_allocated_user_rid); - make_a_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID), tmp); + ldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID), tmp); snprintf(tmp, sizeof(tmp)-1, "%i", next_allocated_group_rid); - make_a_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID), tmp); + ldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID), tmp); - make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_DOMINFO); + ldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_DOMINFO); switch(ldap_op) { @@ -1581,12 +1211,12 @@ static NTSTATUS add_new_domain_info(struct ldapsam_privates *ldap_state) ld_error?ld_error:"unknown")); SAFE_FREE(ld_error); - ldap_mods_free(mods,1); + ldap_mods_free(mods, True); return NT_STATUS_UNSUCCESSFUL; } DEBUG(2,("added: domain = %s in the LDAP database\n", ldap_state->domain_name)); - ldap_mods_free(mods, 1); + ldap_mods_free(mods, True); return NT_STATUS_OK; } @@ -1766,20 +1396,20 @@ static NTSTATUS ldapsam_next_rid(struct ldapsam_privates *ldap_state, uint32 *ri get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID), domain_sid_string)) { - ldap_mods_free(mods, 1); + ldap_mods_free(mods, True); ldap_memfree(dn); ldap_msgfree(result); return ret; } if (!string_to_sid(&dom_sid, domain_sid_string)) { - ldap_mods_free(mods, 1); + ldap_mods_free(mods, True); ldap_memfree(dn); ldap_msgfree(result); return ret; } - ldap_mods_free(mods, 1); + ldap_mods_free(mods, True); mods = NULL; ldap_memfree(dn); ldap_msgfree(result); @@ -1802,7 +1432,7 @@ static NTSTATUS ldapsam_next_rid(struct ldapsam_privates *ldap_state, uint32 *ri DEBUG(2, ("Failed to modify rid: %s\n", ld_error)); SAFE_FREE(ld_error); - ldap_mods_free(mods, 1); + ldap_mods_free(mods, True); mods = NULL; ldap_memfree(dn); @@ -2268,13 +1898,13 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, "finding next available NUA RID failed, " "cannot store!\n", pdb_get_username(sampass))); - ldap_mods_free(*mods, 1); + ldap_mods_free(*mods, True); return False; } } else { DEBUG(0, ("NO user RID specified on account %s, " "cannot store!\n", pdb_get_username(sampass))); - ldap_mods_free(*mods, 1); + ldap_mods_free(*mods, True); return False; } @@ -2284,7 +1914,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, if (!pdb_set_user_sid_from_rid(sampass, rid, PDB_CHANGED)) { DEBUG(0, ("Could not store RID back onto SAM_ACCOUNT for user %s!\n", pdb_get_username(sampass))); - ldap_mods_free(*mods, 1); + ldap_mods_free(*mods, True); return False; } } @@ -2693,7 +2323,7 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods, switch(ldap_op) { case LDAP_MOD_ADD: - make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_ACCOUNT); + ldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_ACCOUNT); rc = ldapsam_add(ldap_state, dn, mods); break; case LDAP_MOD_REPLACE: @@ -2884,12 +2514,12 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_A if (mods == NULL) { DEBUG(4,("mods is empty: nothing to update for user: %s\n", pdb_get_username(newpwd))); - ldap_mods_free(mods, 1); + ldap_mods_free(mods, True); return NT_STATUS_OK; } ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, element_is_changed); - ldap_mods_free(mods,1); + ldap_mods_free(mods,True); if (!NT_STATUS_IS_OK(ret)) { char *ld_error = NULL; @@ -3020,10 +2650,10 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO switch ( ldap_state->schema_ver ) { case SCHEMAVER_SAMBAACCOUNT: - make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBAACCOUNT); + ldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBAACCOUNT); break; case SCHEMAVER_SAMBASAMACCOUNT: - make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBASAMACCOUNT); + ldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBASAMACCOUNT); break; default: DEBUG(0,("ldapsam_add_sam_account: invalid schema version specified\n")); @@ -3034,12 +2664,12 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO if (NT_STATUS_IS_ERR(ret)) { DEBUG(0,("failed to modify/add user with uid = %s (dn = %s)\n", pdb_get_username(newpwd),dn)); - ldap_mods_free(mods,1); + ldap_mods_free(mods, True); return ret; } DEBUG(2,("added: uid == %s in the LDAP database\n", pdb_get_username(newpwd))); - ldap_mods_free(mods, 1); + ldap_mods_free(mods, True); return NT_STATUS_OK; } @@ -3083,7 +2713,7 @@ static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state, attr_list = get_attr_list(groupmap_attr_list); - rc = ldapsam_search(ldap_state, lp_ldap_suffix (), scope, + rc = ldapsam_search(ldap_state, lp_ldap_group_suffix (), scope, filter, attr_list, 0, result); free_attr_list( attr_list ); @@ -3095,7 +2725,7 @@ static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state, "Problem during the LDAP search: LDAP error: %s (%s)", ld_error?ld_error:"(unknown)", ldap_err2string(rc))); DEBUG(3, ("ldapsam_search_one_group: Query was: %s, %s\n", - lp_ldap_suffix(), filter)); + lp_ldap_group_suffix(), filter)); SAFE_FREE(ld_error); } @@ -3372,7 +3002,7 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods, if (!init_ldap_from_group(ldap_state->ldap_struct, result, &mods, map)) { DEBUG(0, ("init_ldap_from_group failed!\n")); - ldap_mods_free(mods, 1); + ldap_mods_free(mods, True); ldap_msgfree(result); return NT_STATUS_UNSUCCESSFUL; } @@ -3384,11 +3014,10 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods, return NT_STATUS_UNSUCCESSFUL; } - make_a_mod(&mods, LDAP_MOD_ADD, "objectClass", - "sambaGroupMapping"); + ldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP ); rc = ldapsam_modify(ldap_state, dn, mods); - ldap_mods_free(mods, 1); + ldap_mods_free(mods, True); if (rc != LDAP_SUCCESS) { char *ld_error = NULL; @@ -3449,7 +3078,7 @@ static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods, rc = ldapsam_modify(ldap_state, dn, mods); - ldap_mods_free(mods, 1); + ldap_mods_free(mods, True); if (rc != LDAP_SUCCESS) { char *ld_error = NULL; @@ -3509,14 +3138,14 @@ static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods, BOOL update) snprintf( filter, sizeof(filter)-1, "(objectclass=%s)", LDAP_OBJ_GROUPMAP); attr_list = get_attr_list( groupmap_attr_list ); - rc = ldapsam_search(ldap_state, lp_ldap_suffix(), + rc = ldapsam_search(ldap_state, lp_ldap_group_suffix(), LDAP_SCOPE_SUBTREE, filter, attr_list, 0, &ldap_state->result); free_attr_list( attr_list ); if (rc != LDAP_SUCCESS) { DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc))); - DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter)); + DEBUG(3, ("Query was: %s, %s\n", lp_ldap_group_suffix(), filter)); ldap_msgfree(ldap_state->result); ldap_state->result = NULL; return NT_STATUS_UNSUCCESSFUL; diff --git a/source/passdb/pdb_smbpasswd.c b/source/passdb/pdb_smbpasswd.c index c392846d935..7095e8a4529 100644 --- a/source/passdb/pdb_smbpasswd.c +++ b/source/passdb/pdb_smbpasswd.c @@ -1133,24 +1133,34 @@ Error was %s\n", pwd->smb_name, pfile2, strerror(errno))); ********************************************************************/ static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampass) { - uid_t uid; uint32 rid; if (sampass == NULL) return False; - - rid = pdb_get_user_rid(sampass); - - /* If the user specified a RID, make sure its able to be both stored and retreived */ - if (rid && rid != DOMAIN_USER_RID_GUEST && uid != fallback_pdb_user_rid_to_uid(rid)) { - DEBUG(0,("build_sam_pass: Failing attempt to store user with non-uid based user RID. \n")); - return False; - } - ZERO_STRUCTP(smb_pw); - smb_pw->smb_userid_set = True; - smb_pw->smb_userid=uid; + if (!IS_SAM_DEFAULT(sampass, PDB_USERSID)) { + rid = pdb_get_user_rid(sampass); + + /* If the user specified a RID, make sure its able to be both stored and retreived */ + if (rid == DOMAIN_USER_RID_GUEST) { + struct passwd *passwd = getpwnam_alloc(lp_guestaccount()); + if (!passwd) { + DEBUG(0, ("Could not find gest account via getpwnam()! (%s)\n", lp_guestaccount())); + return False; + } + smb_pw->smb_userid_set = True; + smb_pw->smb_userid=passwd->pw_uid; + passwd_free(&passwd); + + } else if (fallback_pdb_rid_is_user(rid)) { + smb_pw->smb_userid_set = True; + smb_pw->smb_userid=fallback_pdb_user_rid_to_uid(rid); + } else { + DEBUG(0,("build_sam_pass: Failing attempt to store user with non-uid based user RID. \n")); + return False; + } + } smb_pw->smb_name=(const char*)pdb_get_username(sampass); diff --git a/source/printing/lpq_parse.c b/source/printing/lpq_parse.c index c845170749e..b2f45ad3662 100644 --- a/source/printing/lpq_parse.c +++ b/source/printing/lpq_parse.c @@ -145,8 +145,8 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) buf->size = atoi(tok[TOTALTOK]); buf->status = strequal(tok[RANKTOK],"active")?LPQ_PRINTING:LPQ_QUEUED; buf->time = time(NULL); - StrnCpy(buf->fs_user,tok[USERTOK],sizeof(buf->fs_user)-1); - StrnCpy(buf->fs_file,tok[FILETOK],sizeof(buf->fs_file)-1); + fstrcpy(buf->fs_user,tok[USERTOK]); + fstrcpy(buf->fs_file,tok[FILETOK]); if ((FILETOK + 1) != TOTALTOK) { int i; @@ -266,7 +266,7 @@ static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first) buf->time = LPRng_time(tokarr[LPRNG_TIMETOK]); - StrnCpy(buf->fs_user,tokarr[LPRNG_USERTOK],sizeof(buf->fs_user)-1); + fstrcpy(buf->fs_user,tokarr[LPRNG_USERTOK]); /* The '@hostname' prevents windows from displaying the printing icon * for the current user on the taskbar. Plop in a null. @@ -276,7 +276,7 @@ static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first) *ptr = '\0'; } - StrnCpy(buf->fs_file,tokarr[LPRNG_FILETOK],sizeof(buf->fs_file)-1); + fstrcpy(buf->fs_file,tokarr[LPRNG_FILETOK]); if ((LPRNG_FILETOK + 1) != LPRNG_TOTALTOK) { int i; @@ -353,8 +353,8 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first) buf->status = strequal(tok[0],"HELD")?LPQ_PAUSED:LPQ_QUEUED; buf->priority = 0; buf->time = time(NULL); - StrnCpy(buf->fs_user,tok[3],sizeof(buf->fs_user)-1); - StrnCpy(buf->fs_file,tok[2],sizeof(buf->fs_file)-1); + fstrcpy(buf->fs_user,tok[3]); + fstrcpy(buf->fs_file,tok[2]); } else { @@ -387,8 +387,8 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first) buf->status = strequal(tok[2],"RUNNING")?LPQ_PRINTING:LPQ_QUEUED; buf->priority = 0; buf->time = time(NULL); - StrnCpy(buf->fs_user,tok[5],sizeof(buf->fs_user)-1); - StrnCpy(buf->fs_file,tok[4],sizeof(buf->fs_file)-1); + fstrcpy(buf->fs_user,tok[5]); + fstrcpy(buf->fs_file,tok[4]); } @@ -449,14 +449,14 @@ static BOOL parse_lpq_hpux(char *line, print_queue_struct *buf, BOOL first) fstrcpy(tok[0],"STDIN"); buf->size = atoi(tok[1]); - StrnCpy(buf->fs_file,tok[0],sizeof(buf->fs_file)-1); + fstrcpy(buf->fs_file,tok[0]); /* fill things from header line */ buf->time = jobtime; buf->job = jobid; buf->status = jobstat; buf->priority = jobprio; - StrnCpy(buf->fs_user,jobuser,sizeof(buf->fs_user)-1); + fstrcpy(buf->fs_user,jobuser); return(True); } @@ -482,7 +482,7 @@ static BOOL parse_lpq_hpux(char *line, print_queue_struct *buf, BOOL first) /* the 2nd, 5th & 7th column must be integer */ if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[4]) || !isdigit((int)*tok[6])) return(False); jobid = atoi(tok[1]); - StrnCpy(jobuser,tok[2],sizeof(buf->fs_user)-1); + fstrcpy(jobuser,tok[2]); jobprio = atoi(tok[4]); /* process time */ @@ -573,8 +573,8 @@ static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first) buf->status = LPQ_QUEUED; buf->priority = 0; buf->time = EntryTime(tok, 4, count, 7); - StrnCpy(buf->fs_user,tok[2],sizeof(buf->fs_user)-1); - StrnCpy(buf->fs_file,tok[2],sizeof(buf->fs_file)-1); + fstrcpy(buf->fs_user,tok[2]); + fstrcpy(buf->fs_file,tok[2]); return(True); } @@ -633,8 +633,8 @@ static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first) buf->status = strequal(tok[3],"active")?LPQ_PRINTING:LPQ_QUEUED; buf->priority = 0; buf->time = time(NULL); - StrnCpy(buf->fs_user,tok[1],sizeof(buf->fs_user)-1); - StrnCpy(buf->fs_file,tok[6],sizeof(buf->fs_file)-1); + fstrcpy(buf->fs_user,tok[1]); + fstrcpy(buf->fs_file,tok[6]); return(True); } @@ -704,8 +704,8 @@ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first) buf->status = strequal(tok[0],"active")?LPQ_PRINTING:LPQ_QUEUED; buf->priority = 0; buf->time = time(NULL); - StrnCpy(buf->fs_user,tok[1],sizeof(buf->fs_user)-1); - StrnCpy(buf->fs_file,tok[6],sizeof(buf->fs_file)-1); + fstrcpy(buf->fs_user,tok[1]); + fstrcpy(buf->fs_file,tok[6]); return(True); } @@ -779,8 +779,8 @@ static BOOL parse_lpq_nt(char *line,print_queue_struct *buf,BOOL first) buf->priority = 0; buf->size = atoi(parse_line.size); buf->time = time(NULL); - StrnCpy(buf->fs_user, parse_line.owner, sizeof(buf->fs_user)-1); - StrnCpy(buf->fs_file, parse_line.jobname, sizeof(buf->fs_file)-1); + fstrcpy(buf->fs_user, parse_line.owner); + fstrcpy(buf->fs_file, parse_line.jobname); if (strequal(parse_line.status, LPRNT_PRINTING)) buf->status = LPQ_PRINTING; else if (strequal(parse_line.status, LPRNT_PAUSED)) @@ -838,7 +838,7 @@ static BOOL parse_lpq_os2(char *line,print_queue_struct *buf,BOOL first) /* Get the job name */ parse_line.space2[0] = '\0'; trim_string(parse_line.jobname, NULL, " "); - StrnCpy(buf->fs_file, parse_line.jobname, sizeof(buf->fs_file)-1); + fstrcpy(buf->fs_file, parse_line.jobname); buf->priority = 0; buf->size = atoi(parse_line.size); @@ -856,7 +856,7 @@ static BOOL parse_lpq_os2(char *line,print_queue_struct *buf,BOOL first) !strequal(parse_line.status, LPROS2_WAITING)) return(False); - StrnCpy(buf->fs_user, parse_line.owner, sizeof(buf->fs_user)-1); + fstrcpy(buf->fs_user, parse_line.owner); if (strequal(parse_line.status, LPROS2_PRINTING)) buf->status = LPQ_PRINTING; else if (strequal(parse_line.status, LPROS2_PAUSED)) @@ -990,23 +990,23 @@ BOOL parse_lpq_entry(int snum,char *line, case LPSTAT_OK: for (i=0; stat0_strings[i]; i++) if (strstr(line,stat0_strings[i])) { - StrnCpy(status->message,line,sizeof(status->message)-1); - status->status=LPSTAT_OK; - return ret; + fstrcpy(status->message,line); + status->status=LPSTAT_OK; + return ret; } case LPSTAT_STOPPED: for (i=0; stat1_strings[i]; i++) if (strstr(line,stat1_strings[i])) { - StrnCpy(status->message,line,sizeof(status->message)-1); - status->status=LPSTAT_STOPPED; - return ret; + fstrcpy(status->message,line); + status->status=LPSTAT_STOPPED; + return ret; } case LPSTAT_ERROR: for (i=0; stat2_strings[i]; i++) if (strstr(line,stat2_strings[i])) { - StrnCpy(status->message,line,sizeof(status->message)-1); - status->status=LPSTAT_ERROR; - return ret; + fstrcpy(status->message,line); + status->status=LPSTAT_ERROR; + return ret; } break; } diff --git a/source/printing/nt_printing.c b/source/printing/nt_printing.c index 2b4b7dab6ba..f6c5c183a47 100644 --- a/source/printing/nt_printing.c +++ b/source/printing/nt_printing.c @@ -198,6 +198,22 @@ static const nt_forms_struct default_forms[] = { {"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0} }; +struct table_node { + const char *long_archi; + const char *short_archi; + int version; +}; + +static const struct table_node archi_table[]= { + + {"Windows 4.0", "WIN40", 0 }, + {"Windows NT x86", "W32X86", 2 }, + {"Windows NT R4000", "W32MIPS", 2 }, + {"Windows NT Alpha_AXP", "W32ALPHA", 2 }, + {"Windows NT PowerPC", "W32PPC", 2 }, + {NULL, "", -1 } +}; + static BOOL upgrade_to_version_3(void) { TDB_DATA kbuf, newkey, dbuf; @@ -638,12 +654,12 @@ void update_a_form(nt_forms_struct **list, const FORM *form, int count) int get_ntdrivers(fstring **list, const char *architecture, uint32 version) { int total=0; - fstring short_archi; + const char *short_archi; fstring *fl; pstring key; TDB_DATA kbuf, newkey; - get_short_archi(short_archi, architecture); + short_archi = get_short_archi(architecture); slprintf(key, sizeof(key)-1, "%s%s/%d/", DRIVERS_PREFIX, short_archi, version); for (kbuf = tdb_firstkey(tdb_drivers); @@ -667,52 +683,32 @@ int get_ntdrivers(fstring **list, const char *architecture, uint32 version) } /**************************************************************************** - Function to do the mapping between the long architecture name and - the short one. +function to do the mapping between the long architecture name and +the short one. ****************************************************************************/ -BOOL get_short_archi(char *short_archi, const char *long_archi) +const char *get_short_archi(const char *long_archi) { - struct table { - const char *long_archi; - const char *short_archi; - }; - - struct table archi_table[]= - { - {"Windows 4.0", "WIN40" }, - {"Windows NT x86", "W32X86" }, - {"Windows NT R4000", "W32MIPS" }, - {"Windows NT Alpha_AXP", "W32ALPHA" }, - {"Windows NT PowerPC", "W32PPC" }, - {NULL, "" } - }; - - int i=-1; + int i=-1; - DEBUG(107,("Getting architecture dependant directory\n")); + DEBUG(107,("Getting architecture dependant directory\n")); + do { + i++; + } while ( (archi_table[i].long_archi!=NULL ) && + StrCaseCmp(long_archi, archi_table[i].long_archi) ); - if (long_archi == NULL) { - DEBUGADD(107,("Bad long_archi param.!\n")); - return False; - } + if (archi_table[i].long_archi==NULL) { + DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi)); + return NULL; + } - do { - i++; - } while ( (archi_table[i].long_archi!=NULL ) && - StrCaseCmp(long_archi, archi_table[i].long_archi) ); + /* this might be client code - but shouldn't this be an fstrcpy etc? */ - if (archi_table[i].long_archi==NULL) { - DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi)); - return False; - } - StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi)); + DEBUGADD(108,("index: [%d]\n", i)); + DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi)); + DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi)); - DEBUGADD(108,("index: [%d]\n", i)); - DEBUGADD(108,("long architecture: [%s]\n", long_archi)); - DEBUGADD(108,("short architecture: [%s]\n", short_archi)); - - return True; + return archi_table[i].short_archi; } /**************************************************************************** @@ -750,7 +746,7 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 } /* Skip OEM header (if any) and the DOS stub to start of Windows header */ - if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) { + if (SMB_VFS_LSEEK(fsp, fsp->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) { DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n", fname, errno)); /* Assume this isn't an error... the file just looks sort of like a PE/NE file */ @@ -810,7 +806,7 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 } /* Seek to the start of the .rsrc section info */ - if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) { + if (SMB_VFS_LSEEK(fsp, fsp->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) { DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n", fname, errno)); goto error_exit; @@ -903,7 +899,7 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 * twice, as it is simpler to read the code. */ if (strcmp(&buf[i], VS_SIGNATURE) == 0) { /* Compute skip alignment to next long address */ - int skip = -(fsp->conn->vfs_ops.lseek(fsp, fsp->fd, 0, SEEK_CUR) - (byte_count - i) + + int skip = -(SMB_VFS_LSEEK(fsp, fsp->fd, 0, SEEK_CUR) - (byte_count - i) + sizeof(VS_SIGNATURE)) & 3; if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue; @@ -996,7 +992,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n", old_file)); use_version = False; - if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit; + if (SMB_VFS_FSTAT(fsp, fsp->fd, &st) == -1) goto error_exit; old_create_time = st.st_mtime; DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time)); } @@ -1025,7 +1021,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n", new_file)); use_version = False; - if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit; + if (SMB_VFS_FSTAT(fsp, fsp->fd, &st) == -1) goto error_exit; new_create_time = st.st_mtime; DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time)); } @@ -1066,7 +1062,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr /**************************************************************************** Determine the correct cVersion associated with an architecture and driver ****************************************************************************/ -static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in, +static uint32 get_correct_cversion(const char *architecture, fstring driverpath_in, struct current_user *user, WERROR *perr) { int cversion; @@ -1111,7 +1107,7 @@ static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in, } /* We are temporarily becoming the connection user. */ - if (!become_user(conn, conn->vuid)) { + if (!become_user(conn, user->vuid)) { DEBUG(0,("get_correct_cversion: Can't become user!\n")); *perr = WERR_ACCESS_DENIED; return -1; @@ -1192,7 +1188,7 @@ static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in, static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver, struct current_user *user) { - fstring architecture; + const char *architecture; fstring new_name; char *p; int i; @@ -1232,7 +1228,7 @@ static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dri } } - get_short_archi(architecture, driver->environment); + architecture = get_short_archi(driver->environment); /* jfm:7/16/2000 the client always sends the cversion=0. * The server should check which version the driver is by reading @@ -1256,7 +1252,7 @@ static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dri ****************************************************************************/ static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver, struct current_user *user) { - fstring architecture; + const char *architecture; fstring new_name; char *p; int i; @@ -1296,7 +1292,7 @@ static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *dri } } - get_short_archi(architecture, driver->environment); + architecture = get_short_archi(driver->environment); /* jfm:7/16/2000 the client always sends the cversion=0. * The server should check which version the driver is by reading @@ -1382,7 +1378,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, { NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver; NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver; - fstring architecture; + const char *architecture; pstring new_dir; pstring old_name; pstring new_name; @@ -1409,7 +1405,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, return False; } - get_short_archi(architecture, driver->environment); + architecture = get_short_archi(driver->environment); /* * Connect to the print$ share under the same account as the user connected to the rpc pipe. @@ -1589,7 +1585,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver) { int len, buflen; - fstring architecture; + const char *architecture; pstring directory; fstring temp_name; pstring key; @@ -1597,7 +1593,7 @@ static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver) int i, ret; TDB_DATA kbuf, dbuf; - get_short_archi(architecture, driver->environment); + architecture = get_short_archi(driver->environment); /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx * \\server is added in the rpc server layer. @@ -1751,14 +1747,14 @@ static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, { NT_PRINTER_DRIVER_INFO_LEVEL_3 driver; TDB_DATA kbuf, dbuf; - fstring architecture; + const char *architecture; int len = 0; int i; pstring key; ZERO_STRUCT(driver); - get_short_archi(architecture, arch); + architecture = get_short_archi(arch); DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, drivername)); @@ -2611,6 +2607,10 @@ static WERROR publish_it(NT_PRINTER_INFO_LEVEL *printer) DEBUG(3, ("ads_init() failed\n")); return WERR_SERVER_UNAVAILABLE; } + setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1); + SAFE_FREE(ads->auth.password); + ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), + NULL, NULL); ads_rc = ads_connect(ads); if (!ADS_ERR_OK(ads_rc)) { DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc))); @@ -2668,6 +2668,10 @@ WERROR unpublish_it(NT_PRINTER_INFO_LEVEL *printer) DEBUG(3, ("ads_init() failed\n")); return WERR_SERVER_UNAVAILABLE; } + setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1); + SAFE_FREE(ads->auth.password); + ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), + NULL, NULL); ads_rc = ads_connect(ads); if (!ADS_ERR_OK(ads_rc)) { DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc))); @@ -4405,13 +4409,13 @@ WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct cur uint32 version, BOOL delete_files ) { pstring key; - fstring arch; + const char *arch; TDB_DATA kbuf, dbuf; NT_PRINTER_DRIVER_INFO_LEVEL ctr; /* delete the tdb data first */ - get_short_archi(arch, info_3->environment); + arch = get_short_archi(info_3->environment); slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, arch, version, info_3->name); diff --git a/source/printing/pcap.c b/source/printing/pcap.c index c399c3c6cc4..1bdbf4a789e 100644 --- a/source/printing/pcap.c +++ b/source/printing/pcap.c @@ -384,7 +384,7 @@ void pcap_printer_fn(void (*fn)(char *, char *)) if (strlen(p)>strlen(comment) && has_punctuation) { - StrnCpy(comment,p,sizeof(comment)-1); + pstrcpy(comment,p); continue; } @@ -398,8 +398,8 @@ void pcap_printer_fn(void (*fn)(char *, char *)) if (!strchr_m(comment,' ') && strlen(p) > strlen(comment)) { - StrnCpy(comment,p,sizeof(comment)-1); - continue; + pstrcpy(comment,p); + continue; } } diff --git a/source/printing/printfsp.c b/source/printing/printfsp.c index 45d937f29c4..0b6d4fdbe1c 100644 --- a/source/printing/printfsp.c +++ b/source/printing/printfsp.c @@ -80,7 +80,7 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname) string_set(&fsp->fsp_name,print_job_fname(SNUM(conn),jobid)); fsp->wbmpx_ptr = NULL; fsp->wcp = NULL; - conn->vfs_ops.fstat(fsp,fsp->fd, &sbuf); + SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf); fsp->mode = sbuf.st_mode; fsp->inode = sbuf.st_ino; fsp->dev = sbuf.st_dev; diff --git a/source/python/py_winbind.c b/source/python/py_winbind.c index 0c40861c701..db66be2321a 100644 --- a/source/python/py_winbind.c +++ b/source/python/py_winbind.c @@ -261,12 +261,12 @@ static PyObject *py_config_dict(void) /* Winbind uid/gid range */ - if (lp_idmap_uid(&ulow, &uhi)) { + if (lp_winbind_uid(&ulow, &uhi)) { PyDict_SetItemString(result, "uid_low", PyInt_FromLong(ulow)); PyDict_SetItemString(result, "uid_high", PyInt_FromLong(uhi)); } - if (lp_idmap_gid(&glow, &ghi)) { + if (lp_winbind_gid(&glow, &ghi)) { PyDict_SetItemString(result, "gid_low", PyInt_FromLong(glow)); PyDict_SetItemString(result, "gid_high", PyInt_FromLong(ghi)); } diff --git a/source/rpc_client/cli_lsarpc.c b/source/rpc_client/cli_lsarpc.c index 9002ad3d1b5..db873236e46 100644 --- a/source/rpc_client/cli_lsarpc.c +++ b/source/rpc_client/cli_lsarpc.c @@ -1164,7 +1164,7 @@ NTSTATUS cli_lsa_enum_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ctx, LSA_Q_ENUM_ACCT_RIGHTS q; LSA_R_ENUM_ACCT_RIGHTS r; NTSTATUS result; - unsigned int i; + int i; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -1199,7 +1199,7 @@ NTSTATUS cli_lsa_enum_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ctx, *privs_name = (char **)talloc(mem_ctx, (*count) * sizeof(char **)); for (i=0;i<*count;i++) { - (*privs_name)[i] = unistr2_tdup(mem_ctx, &r.rights.strings[i].string); + pull_ucs2_talloc(mem_ctx, &(*privs_name)[i], r.rights.strings[i].string.buffer); } done: @@ -1293,58 +1293,6 @@ done: } -/* list account SIDs that have the specified right */ - -NTSTATUS cli_lsa_enum_account_with_right(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, const char *right, - uint32 *count, DOM_SID **sids) -{ - prs_struct qbuf, rbuf; - LSA_Q_ENUM_ACCT_WITH_RIGHT q; - LSA_R_ENUM_ACCT_WITH_RIGHT r; - NTSTATUS result; - - ZERO_STRUCT(q); - - /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - init_q_enum_acct_with_right(&q, pol, right); - - if (!lsa_io_q_enum_acct_with_right("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_ENUMACCTWITHRIGHT, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_enum_acct_with_right("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - *count = r.count; - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - if (*count) { - int i; - (*sids) = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * (*count)); - for (i=0; i<*count; i++) { - sid_copy(&(*sids)[i], &r.sids.sids[i].sid.sid); - } - } -done: - - return result; -} - - #if 0 /** An example of how to use the routines in this file. Fetch a DOMAIN diff --git a/source/rpc_client/cli_netlogon.c b/source/rpc_client/cli_netlogon.c index ce0dd95e94a..831101ed81e 100644 --- a/source/rpc_client/cli_netlogon.c +++ b/source/rpc_client/cli_netlogon.c @@ -280,7 +280,7 @@ NTSTATUS cli_nt_setup_creds(struct cli_state *cli, } if (!NT_STATUS_IS_OK(result)) - DEBUG(1,("cli_nt_setup_creds: auth%d challenge failed %s\n", level, nt_errstr(result))); + DEBUG(3,("cli_nt_setup_creds: auth%d challenge failed %s\n", level, nt_errstr(result))); return result; } @@ -472,6 +472,7 @@ NTSTATUS cli_netlogon_sam_deltas(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Logon domain user */ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, + DOM_CRED *ret_creds, const char *username, const char *password, int logon_type) { @@ -486,6 +487,7 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, ZERO_STRUCT(q); ZERO_STRUCT(r); + ZERO_STRUCT(dummy_rtn_creds); /* Initialise parse structures */ @@ -498,8 +500,8 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, q.validation_level = validation_level; - memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds)); - dummy_rtn_creds.timestamp.time = time(NULL); + if (ret_creds == NULL) + ret_creds = &dummy_rtn_creds; ctr.switch_value = logon_type; @@ -542,7 +544,7 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, } init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname(), - &clnt_creds, &dummy_rtn_creds, logon_type, + &clnt_creds, ret_creds, logon_type, &ctr); /* Marshall data and send request */ @@ -563,6 +565,7 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return results */ result = r.status; + memcpy(ret_creds, &r.srv_creds, sizeof(*ret_creds)); done: prs_mem_free(&qbuf); @@ -579,6 +582,7 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, **/ NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, + DOM_CRED *ret_creds, const char *username, const char *domain, const char *workstation, const uint8 chal[8], DATA_BLOB lm_response, DATA_BLOB nt_response, @@ -598,6 +602,7 @@ NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_c ZERO_STRUCT(q); ZERO_STRUCT(r); + ZERO_STRUCT(dummy_rtn_creds); workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation); @@ -617,8 +622,8 @@ NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_c q.validation_level = validation_level; - memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds)); - dummy_rtn_creds.timestamp.time = time(NULL); + if (ret_creds == NULL) + ret_creds = &dummy_rtn_creds; ctr.switch_value = NET_LOGON_TYPE; @@ -629,7 +634,7 @@ NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_c lm_response.data, lm_response.length, nt_response.data, nt_response.length); init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname(), - &clnt_creds, &dummy_rtn_creds, NET_LOGON_TYPE, + &clnt_creds, ret_creds, NET_LOGON_TYPE, &ctr); /* Marshall data and send request */ @@ -659,6 +664,7 @@ NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_c /* Return results */ result = r.status; + memcpy(ret_creds, &r.srv_creds, sizeof(*ret_creds)); done: prs_mem_free(&qbuf); diff --git a/source/rpc_client/cli_pipe.c b/source/rpc_client/cli_pipe.c index a5cb6d425ee..a6a49dd3ebe 100644 --- a/source/rpc_client/cli_pipe.c +++ b/source/rpc_client/cli_pipe.c @@ -174,7 +174,8 @@ static void NTLMSSPcalc_ap( struct cli_state *cli, unsigned char *data, uint32 l Never on bind requests/responses. ****************************************************************************/ -static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int auth_len) +static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, + uint32 fragment_start, int len, int auth_len, int *pauth_padding_len) { /* * The following is that length of the data we must sign or seal. @@ -187,12 +188,14 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int /* * The start of the data to sign/seal is just after the RPC headers. */ - char *reply_data = prs_data_p(rdata) + RPC_HEADER_LEN + RPC_HDR_REQ_LEN; + char *reply_data = prs_data_p(rdata) + fragment_start + RPC_HEADER_LEN + RPC_HDR_REQ_LEN; BOOL auth_verify = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SIGN) != 0); BOOL auth_seal = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SEAL) != 0); BOOL auth_schannel = (cli->saved_netlogon_pipe_fnum != 0); + *pauth_padding_len = 0; + DEBUG(5,("rpc_auth_pipe: len: %d auth_len: %d verify %s seal %s schannel %s\n", len, auth_len, BOOLSTR(auth_verify), BOOLSTR(auth_seal), BOOLSTR(auth_schannel))); @@ -297,11 +300,33 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int if (auth_schannel) { RPC_AUTH_NETSEC_CHK chk; - char data[RPC_AUTH_NETSEC_CHK_LEN]; - char *dp = prs_data_p(rdata) + len - auth_len; + RPC_HDR_AUTH rhdr_auth; + char data[RPC_HDR_AUTH_LEN+RPC_AUTH_NETSEC_CHK_LEN]; + char *dp = prs_data_p(rdata) + fragment_start + len - + RPC_HDR_AUTH_LEN - RPC_AUTH_NETSEC_CHK_LEN; prs_struct auth_verf; if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) { + + if ( (auth_len == 12) && + (cli->auth_info.seq_num == 0) ) { + + /* This is the reply to our bind. Ok, + the sequence number can wrap + around. But this only means that + every 4 billion request we + misdetect a wrong length in a + reply. This is an error condition + which will lead to failure anyway + later. + + The reply contains a + RPC_AUTH_VERIFIER with no content + (12 bytes), so ignore it. + */ + return True; + } + DEBUG(0,("rpc_auth_pipe: wrong schannel auth len %d\n", auth_len)); return False; } @@ -322,7 +347,19 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int /* The endinness must be preserved. JRA. */ prs_set_endian_data( &auth_verf, rdata->bigendian_data); - prs_give_memory(&auth_verf, data, RPC_AUTH_NETSEC_CHK_LEN, False); + prs_give_memory(&auth_verf, data, sizeof(data), False); + + if (!smb_io_rpc_hdr_auth("auth_hdr", &rhdr_auth, &auth_verf, 0)) { + DEBUG(0, ("rpc_auth_pipe: Could not parse schannel auth header\n")); + return False; + } + + if ((rhdr_auth.auth_type != NETSEC_AUTH_TYPE) || + (rhdr_auth.auth_level != NETSEC_AUTH_LEVEL)) { + DEBUG(0, ("rpc_auth_pipe: Got wrong schannel auth type/level: %d/%d\n", + rhdr_auth.auth_type, rhdr_auth.auth_level)); + return False; + } if (!smb_io_rpc_auth_netsec_chk("schannel_auth_sign", &chk, &auth_verf, 0)) { DEBUG(0, ("rpc_auth_pipe: schannel unmarshalling " @@ -336,6 +373,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int DEBUG(0, ("rpc_auth_pipe: Could not decode schannel\n")); return False; } + *pauth_padding_len = rhdr_auth.padding; } return True; } @@ -379,6 +417,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd char *prdata = NULL; uint32 rdata_len = 0; uint32 current_offset = 0; + uint32 fragment_start = 0; uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : 1024; /* Create setup parameters - must be in native byte order. */ @@ -469,7 +508,10 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd */ if (rhdr.auth_len != 0) { - if(!rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len)) + int auth_padding_len = 0; + + if(!rpc_auth_pipe(cli, rdata, fragment_start, rhdr.frag_len, + rhdr.auth_len, &auth_padding_len)) return False; /* * Drop the auth footers from the current offset. @@ -477,7 +519,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd * The auth footers consist of the auth_data and the * preceeding 8 byte auth_header. */ - current_offset -= (rhdr.auth_len + RPC_HDR_AUTH_LEN); + current_offset -= (auth_padding_len + RPC_HDR_AUTH_LEN + rhdr.auth_len); } /* @@ -557,12 +599,17 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd if (!rpc_read(cli, rdata, len, ¤t_offset)) return False; + fragment_start = current_offset - len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN; + /* * Verify any authentication footer. */ if (rhdr.auth_len != 0 ) { - if(!rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len)) + int auth_padding_len = 0; + + if(!rpc_auth_pipe(cli, rdata, fragment_start, rhdr.frag_len, + rhdr.auth_len, &auth_padding_len)) return False; /* * Drop the auth footers from the current offset. @@ -570,7 +617,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd * preceeding 8 byte auth_header. * We need this if there are more fragments. */ - current_offset -= (rhdr.auth_len + RPC_HDR_AUTH_LEN); + current_offset -= (auth_padding_len + RPC_HDR_AUTH_LEN + rhdr.auth_len); } } @@ -650,6 +697,12 @@ static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, BOOL do_netse init_rpc_hdr_auth(&hdr_auth, NETSEC_AUTH_TYPE, NETSEC_AUTH_LEVEL, 0x00, 1); + + /* Use lp_workgroup() if domain not specified */ + + if (!domain || !domain[0]) + domain = lp_workgroup(); + init_rpc_auth_netsec_neg(&netsec_neg, domain, my_name); /* @@ -967,8 +1020,10 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, * be stored in the auth header. */ - if (auth_schannel) - auth_padding = 8 - (send_size & 7); + if (auth_schannel) { + if (send_size % 8) + auth_padding = 8 - (send_size % 8); + } data_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + send_size + ((auth_verify|auth_schannel) ? RPC_HDR_AUTH_LEN : 0) + @@ -1536,8 +1591,8 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) Open a session to the NETLOGON pipe using schannel. ****************************************************************************/ -BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password, - int sec_chan) +NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan, + const char *trust_password) { NTSTATUS result; uint32 neg_flags = 0x000001ff; @@ -1546,22 +1601,12 @@ BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password, if (lp_client_schannel() != False) neg_flags |= NETLOGON_NEG_SCHANNEL; - - if (!cli_nt_session_open(cli, PI_NETLOGON)) { - return False; - } - - if (!secrets_init()) { - DEBUG(3,("Failed to init secrets.tdb\n")); - return False; - } - result = cli_nt_setup_creds(cli, sec_chan, trust_password, &neg_flags, 2); if (!NT_STATUS_IS_OK(result)) { cli_nt_session_close(cli); - return False; + return result; } if ((lp_client_schannel() == True) && @@ -1569,12 +1614,12 @@ BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password, DEBUG(3, ("Server did not offer schannel\n")); cli_nt_session_close(cli); - return False; + return NT_STATUS_UNSUCCESSFUL; } if ((lp_client_schannel() == False) || ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) { - return True; + return NT_STATUS_OK; } /* Server offered schannel, so try it. */ @@ -1597,7 +1642,7 @@ BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password, "Error was %s\n", PIPE_NETLOGON, cli->desthost, cli_errstr(cli))); - return False; + return NT_STATUS_UNSUCCESSFUL; } cli->nt_pipe_fnum = (uint16)fnum; @@ -1608,7 +1653,7 @@ BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password, "Error was %s\n", PIPE_NETLOGON, cli->desthost, cli_errstr(cli))); - return False; + return NT_STATUS_UNSUCCESSFUL; } cli->nt_pipe_fnum = (uint16)fnum; @@ -1618,17 +1663,17 @@ BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password, DEBUG(0,("Pipe hnd state failed. Error was %s\n", cli_errstr(cli))); cli_close(cli, cli->nt_pipe_fnum); - return False; + return NT_STATUS_UNSUCCESSFUL; } } if (!rpc_pipe_bind(cli, PI_NETLOGON, global_myname(), True)) { DEBUG(2,("rpc bind to %s failed\n", PIPE_NETLOGON)); cli_close(cli, cli->nt_pipe_fnum); - return False; + return NT_STATUS_UNSUCCESSFUL; } - return True; + return NT_STATUS_OK; } diff --git a/source/rpc_client/cli_samr.c b/source/rpc_client/cli_samr.c index 767c6a12b25..4fe8fba7b0b 100644 --- a/source/rpc_client/cli_samr.c +++ b/source/rpc_client/cli_samr.c @@ -1000,6 +1000,8 @@ NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, ZERO_STRUCT(q); ZERO_STRUCT(r); + *num_entries = 0; + /* Initialise parse structures */ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); diff --git a/source/rpc_parse/parse_lsa.c b/source/rpc_parse/parse_lsa.c index 7ff2aa7d01d..f620845d3b3 100644 --- a/source/rpc_parse/parse_lsa.c +++ b/source/rpc_parse/parse_lsa.c @@ -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,15 +2357,6 @@ 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! */ -} - /******************************************************************* Inits an LSA_Q_REMOVE_ACCT_RIGHTS structure. @@ -2398,6 +2374,7 @@ void init_q_remove_acct_rights(LSA_Q_REMOVE_ACCT_RIGHTS *q_q, init_dom_sid2(&q_q->sid, sid); q_q->removeall = removeall; init_unistr2_array(&q_q->rights, count, rights); + q_q->count = 5; } @@ -2428,7 +2405,7 @@ BOOL lsa_io_q_remove_acct_rights(const char *desc, LSA_Q_REMOVE_ACCT_RIGHTS *q_q } /******************************************************************* -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) { @@ -2440,89 +2417,3 @@ BOOL lsa_io_r_remove_acct_rights(const char *desc, LSA_R_REMOVE_ACCT_RIGHTS *r_c 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); -} diff --git a/source/rpc_parse/parse_misc.c b/source/rpc_parse/parse_misc.c index a39e3391bbe..17a96fff80c 100644 --- a/source/rpc_parse/parse_misc.c +++ b/source/rpc_parse/parse_misc.c @@ -1122,78 +1122,6 @@ BOOL smb_io_unistr2_array(const char *desc, UNISTR2_ARRAY *array, prs_struct *ps } -/* - initialise a SID_ARRAY from a list of sids -*/ -BOOL init_sid_array(SID_ARRAY *array, - uint32 count, DOM_SID *sids) -{ - unsigned int i; - - array->count = count; - array->ref_id = count?1:0; - if (array->count == 0) { - return True; - } - - array->sids = (SID_ARRAY_EL *)talloc_zero(get_talloc_ctx(), count * sizeof(SID_ARRAY_EL)); - if (!array->sids) { - return False; - } - - for (i=0;i<count;i++) { - array->sids[i].ref_id = 1; - init_dom_sid2(&array->sids[i].sid, &sids[i]); - } - - return True; -} - - -/******************************************************************* - Reads or writes a SID_ARRAY structure. -********************************************************************/ -BOOL smb_io_sid_array(const char *desc, SID_ARRAY *array, prs_struct *ps, int depth) -{ - unsigned int i; - - prs_debug(ps, depth, desc, "smb_io_sid_array"); - depth++; - - if(!prs_uint32("ref_id", ps, depth, &array->ref_id)) - return False; - - if (! array->ref_id) { - return True; - } - - if(!prs_uint32("count", ps, depth, &array->count)) - return False; - - if (array->count == 0) { - return True; - } - - if (UNMARSHALLING(ps)) { - array->sids = talloc_zero(get_talloc_ctx(), array->count * sizeof(array->sids[0])); - } - if (! array->sids) { - return False; - } - - for (i=0;i<array->count;i++) { - if(!prs_uint32("ref_id", ps, depth, &array->sids[i].ref_id)) - return False; - } - - for (i=0;i<array->count;i++) { - if (!smb_io_dom_sid2("sid", &array->sids[i].sid, ps, depth)) - return False; - } - - return True; -} - /******************************************************************* Inits a DOM_RID2 structure. ********************************************************************/ @@ -1289,22 +1217,22 @@ void init_dom_rid4(DOM_RID4 *rid4, uint16 unknown, uint16 attr, uint32 rid) Inits a DOM_CLNT_SRV structure. ********************************************************************/ -static void init_clnt_srv(DOM_CLNT_SRV *dlog, const char *logon_srv, const char *comp_name) +static void init_clnt_srv(DOM_CLNT_SRV *logcln, const char *logon_srv, const char *comp_name) { DEBUG(5,("init_clnt_srv: %d\n", __LINE__)); if (logon_srv != NULL) { - dlog->undoc_buffer = 1; - init_unistr2(&dlog->uni_logon_srv, logon_srv, strlen(logon_srv)+1); + logcln->undoc_buffer = 1; + init_unistr2(&logcln->uni_logon_srv, logon_srv, strlen(logon_srv)+1); } else { - dlog->undoc_buffer = 0; + logcln->undoc_buffer = 0; } if (comp_name != NULL) { - dlog->undoc_buffer2 = 1; - init_unistr2(&dlog->uni_comp_name, comp_name, strlen(comp_name)+1); + logcln->undoc_buffer2 = 1; + init_unistr2(&logcln->uni_comp_name, comp_name, strlen(comp_name)+1); } else { - dlog->undoc_buffer2 = 0; + logcln->undoc_buffer2 = 0; } } @@ -1312,9 +1240,9 @@ static void init_clnt_srv(DOM_CLNT_SRV *dlog, const char *logon_srv, const char Inits or writes a DOM_CLNT_SRV structure. ********************************************************************/ -static BOOL smb_io_clnt_srv(const char *desc, DOM_CLNT_SRV *dlog, prs_struct *ps, int depth) +static BOOL smb_io_clnt_srv(const char *desc, DOM_CLNT_SRV *logcln, prs_struct *ps, int depth) { - if (dlog == NULL) + if (logcln == NULL) return False; prs_debug(ps, depth, desc, "smb_io_clnt_srv"); @@ -1323,22 +1251,22 @@ static BOOL smb_io_clnt_srv(const char *desc, DOM_CLNT_SRV *dlog, prs_struct *ps if(!prs_align(ps)) return False; - if(!prs_uint32("undoc_buffer ", ps, depth, &dlog->undoc_buffer)) + if(!prs_uint32("undoc_buffer ", ps, depth, &logcln->undoc_buffer)) return False; - if (dlog->undoc_buffer != 0) { - if(!smb_io_unistr2("unistr2", &dlog->uni_logon_srv, dlog->undoc_buffer, ps, depth)) + if (logcln->undoc_buffer != 0) { + if(!smb_io_unistr2("unistr2", &logcln->uni_logon_srv, logcln->undoc_buffer, ps, depth)) return False; } if(!prs_align(ps)) return False; - if(!prs_uint32("undoc_buffer2", ps, depth, &dlog->undoc_buffer2)) + if(!prs_uint32("undoc_buffer2", ps, depth, &logcln->undoc_buffer2)) return False; - if (dlog->undoc_buffer2 != 0) { - if(!smb_io_unistr2("unistr2", &dlog->uni_comp_name, dlog->undoc_buffer2, ps, depth)) + if (logcln->undoc_buffer2 != 0) { + if(!smb_io_unistr2("unistr2", &logcln->uni_comp_name, logcln->undoc_buffer2, ps, depth)) return False; } @@ -1349,28 +1277,28 @@ static BOOL smb_io_clnt_srv(const char *desc, DOM_CLNT_SRV *dlog, prs_struct *ps Inits a DOM_LOG_INFO structure. ********************************************************************/ -void init_log_info(DOM_LOG_INFO *dlog, const char *logon_srv, const char *acct_name, +void init_log_info(DOM_LOG_INFO *loginfo, const char *logon_srv, const char *acct_name, uint16 sec_chan, const char *comp_name) { DEBUG(5,("make_log_info %d\n", __LINE__)); - dlog->undoc_buffer = 1; + loginfo->undoc_buffer = 1; - init_unistr2(&dlog->uni_logon_srv, logon_srv, strlen(logon_srv)+1); - init_unistr2(&dlog->uni_acct_name, acct_name, strlen(acct_name)+1); + init_unistr2(&loginfo->uni_logon_srv, logon_srv, strlen(logon_srv)+1); + init_unistr2(&loginfo->uni_acct_name, acct_name, strlen(acct_name)+1); - dlog->sec_chan = sec_chan; + loginfo->sec_chan = sec_chan; - init_unistr2(&dlog->uni_comp_name, comp_name, strlen(comp_name)+1); + init_unistr2(&loginfo->uni_comp_name, comp_name, strlen(comp_name)+1); } /******************************************************************* Reads or writes a DOM_LOG_INFO structure. ********************************************************************/ -BOOL smb_io_log_info(const char *desc, DOM_LOG_INFO *dlog, prs_struct *ps, int depth) +BOOL smb_io_log_info(const char *desc, DOM_LOG_INFO *loginfo, prs_struct *ps, int depth) { - if (dlog == NULL) + if (loginfo == NULL) return False; prs_debug(ps, depth, desc, "smb_io_log_info"); @@ -1379,18 +1307,18 @@ BOOL smb_io_log_info(const char *desc, DOM_LOG_INFO *dlog, prs_struct *ps, int d if(!prs_align(ps)) return False; - if(!prs_uint32("undoc_buffer", ps, depth, &dlog->undoc_buffer)) + if(!prs_uint32("undoc_buffer", ps, depth, &loginfo->undoc_buffer)) return False; - if(!smb_io_unistr2("unistr2", &dlog->uni_logon_srv, True, ps, depth)) + if(!smb_io_unistr2("unistr2", &loginfo->uni_logon_srv, True, ps, depth)) return False; - if(!smb_io_unistr2("unistr2", &dlog->uni_acct_name, True, ps, depth)) + if(!smb_io_unistr2("unistr2", &loginfo->uni_acct_name, True, ps, depth)) return False; - if(!prs_uint16("sec_chan", ps, depth, &dlog->sec_chan)) + if(!prs_uint16("sec_chan", ps, depth, &loginfo->sec_chan)) return False; - if(!smb_io_unistr2("unistr2", &dlog->uni_comp_name, True, ps, depth)) + if(!smb_io_unistr2("unistr2", &loginfo->uni_comp_name, True, ps, depth)) return False; return True; @@ -1529,21 +1457,21 @@ BOOL smb_io_clnt_info(const char *desc, DOM_CLNT_INFO *clnt, prs_struct *ps, in Inits a DOM_LOGON_ID structure. ********************************************************************/ -void init_logon_id(DOM_LOGON_ID *dlog, uint32 log_id_low, uint32 log_id_high) +void init_logon_id(DOM_LOGON_ID *logonid, uint32 log_id_low, uint32 log_id_high) { DEBUG(5,("make_logon_id: %d\n", __LINE__)); - dlog->low = log_id_low; - dlog->high = log_id_high; + logonid->low = log_id_low; + logonid->high = log_id_high; } /******************************************************************* Reads or writes a DOM_LOGON_ID structure. ********************************************************************/ -BOOL smb_io_logon_id(const char *desc, DOM_LOGON_ID *dlog, prs_struct *ps, int depth) +BOOL smb_io_logon_id(const char *desc, DOM_LOGON_ID *logonid, prs_struct *ps, int depth) { - if (dlog == NULL) + if (logonid == NULL) return False; prs_debug(ps, depth, desc, "smb_io_logon_id"); @@ -1552,9 +1480,9 @@ BOOL smb_io_logon_id(const char *desc, DOM_LOGON_ID *dlog, prs_struct *ps, int d if(!prs_align(ps)) return False; - if(!prs_uint32("low ", ps, depth, &dlog->low )) + if(!prs_uint32("low ", ps, depth, &logonid->low )) return False; - if(!prs_uint32("high", ps, depth, &dlog->high)) + if(!prs_uint32("high", ps, depth, &logonid->high)) return False; return True; diff --git a/source/rpc_parse/parse_net.c b/source/rpc_parse/parse_net.c index 1a14915c9f5..7d04eace230 100644 --- a/source/rpc_parse/parse_net.c +++ b/source/rpc_parse/parse_net.c @@ -1808,9 +1808,9 @@ static BOOL net_io_sam_domain_info(const char *desc, SAM_DOMAIN_INFO * info, if (!smb_io_unihdr("hdr_unknown", &info->hdr_unknown, ps, depth)) return False; - if (prs_offset(ps) + 40 > prs_data_size(ps)) + if (ps->data_offset + 40 > ps->buffer_size) return False; - prs_set_offset(ps, prs_offset(ps) + 40); + ps->data_offset += 40; if (!smb_io_unistr2("uni_dom_name", &info->uni_dom_name, info->hdr_dom_name.buffer, ps, depth)) @@ -1847,9 +1847,9 @@ static BOOL net_io_sam_group_info(const char *desc, SAM_GROUP_INFO * info, if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth)) return False; - if (prs_offset(ps) + 48 > prs_data_size(ps)) + if (ps->data_offset + 48 > ps->buffer_size) return False; - prs_set_offset(ps, prs_offset(ps) + 48); + ps->data_offset += 48; if (!smb_io_unistr2("uni_grp_name", &info->uni_grp_name, info->hdr_grp_name.buffer, ps, depth)) @@ -2128,13 +2128,13 @@ static BOOL net_io_sam_account_info(const char *desc, uint8 sess_key[16], uint32 len = 0x44; if (!prs_uint32("pwd_len", ps, depth, &len)) return False; - old_offset = prs_offset(ps); + old_offset = ps->data_offset; if (len > 0) { if (ps->io) { /* reading */ - if (!prs_hash1(ps, prs_offset(ps), sess_key)) + if (!prs_hash1(ps, ps->data_offset, sess_key, len)) return False; } if (!net_io_sam_passwd_info("pass", &info->pass, @@ -2144,13 +2144,13 @@ static BOOL net_io_sam_account_info(const char *desc, uint8 sess_key[16], if (!ps->io) { /* writing */ - if (!prs_hash1(ps, old_offset, sess_key)) + if (!prs_hash1(ps, old_offset, sess_key, len)) return False; } } - if (old_offset + len > prs_data_size(ps)) + if (old_offset + len > ps->buffer_size) return False; - prs_set_offset(ps, old_offset + len); + ps->data_offset = old_offset + len; } if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc, info->hdr_sec_desc.buffer, ps, depth)) @@ -2185,9 +2185,9 @@ static BOOL net_io_sam_group_mem_info(const char *desc, SAM_GROUP_MEM_INFO * inf if (!prs_uint32("num_members", ps, depth, &info->num_members)) return False; - if (prs_offset(ps) + 16 > prs_data_size(ps)) + if (ps->data_offset + 16 > ps->buffer_size) return False; - prs_set_offset(ps, prs_offset(ps) + 16); + ps->data_offset += 16; if (info->ptr_rids != 0) { @@ -2267,9 +2267,9 @@ static BOOL net_io_sam_alias_info(const char *desc, SAM_ALIAS_INFO * info, if (!smb_io_unihdr("hdr_als_desc", &info->hdr_als_desc, ps, depth)) return False; - if (prs_offset(ps) + 40 > prs_data_size(ps)) + if (ps->data_offset + 40 > ps->buffer_size) return False; - prs_set_offset(ps, prs_offset(ps) + 40); + ps->data_offset += 40; if (!smb_io_unistr2("uni_als_name", &info->uni_als_name, info->hdr_als_name.buffer, ps, depth)) @@ -2307,9 +2307,9 @@ static BOOL net_io_sam_alias_mem_info(const char *desc, SAM_ALIAS_MEM_INFO * inf if (info->ptr_members != 0) { - if (prs_offset(ps) + 16 > prs_data_size(ps)) + if (ps->data_offset + 16 > ps->buffer_size) return False; - prs_set_offset(ps, prs_offset(ps) + 16); + ps->data_offset += 16; if (!prs_uint32("num_sids", ps, depth, &info->num_sids)) return False; diff --git a/source/rpc_parse/parse_prs.c b/source/rpc_parse/parse_prs.c index e0a75d73825..88150c718b6 100644 --- a/source/rpc_parse/parse_prs.c +++ b/source/rpc_parse/parse_prs.c @@ -1316,7 +1316,7 @@ int tdb_prs_fetch(TDB_CONTEXT *tdb, char *keystr, prs_struct *ps, TALLOC_CTX *me /******************************************************************* hash a stream. ********************************************************************/ -BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16]) +BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16], int len) { char *q; @@ -1326,12 +1326,12 @@ BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16]) #ifdef DEBUG_PASSWORD DEBUG(100, ("prs_hash1\n")); dump_data(100, sess_key, 16); - dump_data(100, q, 68); + dump_data(100, q, len); #endif - SamOEMhash((uchar *) q, sess_key, 68); + SamOEMhash((uchar *) q, sess_key, len); #ifdef DEBUG_PASSWORD - dump_data(100, q, 68); + dump_data(100, q, len); #endif return True; diff --git a/source/rpc_parse/parse_samr.c b/source/rpc_parse/parse_samr.c index ac1e9da61be..47bf3f390dd 100644 --- a/source/rpc_parse/parse_samr.c +++ b/source/rpc_parse/parse_samr.c @@ -4598,7 +4598,6 @@ BOOL samr_io_r_query_aliasmem(const char *desc, SAMR_R_QUERY_ALIASMEM * r_u, prs_struct *ps, int depth) { uint32 i; - uint32 ptr_sid[MAX_LOOKUP_SIDS]; if (r_u == NULL) return False; @@ -4614,28 +4613,31 @@ BOOL samr_io_r_query_aliasmem(const char *desc, SAMR_R_QUERY_ALIASMEM * r_u, if(!prs_uint32("ptr", ps, depth, &r_u->ptr)) return False; - if (r_u->ptr != 0) { - SMB_ASSERT_ARRAY(ptr_sid, r_u->num_sids); - - if (r_u->num_sids != 0) { - if(!prs_uint32("num_sids1", ps, depth, &r_u->num_sids1)) - return False; - - for (i = 0; i < r_u->num_sids1; i++) { - ptr_sid[i] = 1; - if(!prs_uint32("ptr_sid", ps, depth, &ptr_sid[i])) - return False; - } + if (r_u->ptr != 0 && r_u->num_sids != 0) { + uint32 *ptr_sid = NULL; - if (UNMARSHALLING(ps)) { - r_u->sid = talloc(ps->mem_ctx, r_u->num_sids1 * sizeof(DOM_SID2)); - } + if(!prs_uint32("num_sids1", ps, depth, &r_u->num_sids1)) + return False; - for (i = 0; i < r_u->num_sids1; i++) { - if (ptr_sid[i] != 0) { - if(!smb_io_dom_sid2("sid", &r_u->sid[i], ps, depth)) - return False; - } + ptr_sid = talloc(ps->mem_ctx, sizeof(uint32) * r_u->num_sids1); + if (!ptr_sid) { + return False; + } + + for (i = 0; i < r_u->num_sids1; i++) { + ptr_sid[i] = 1; + if(!prs_uint32("ptr_sid", ps, depth, &ptr_sid[i])) + return False; + } + + if (UNMARSHALLING(ps)) { + r_u->sid = talloc(ps->mem_ctx, r_u->num_sids1 * sizeof(DOM_SID2)); + } + + for (i = 0; i < r_u->num_sids1; i++) { + if (ptr_sid[i] != 0) { + if(!smb_io_dom_sid2("sid", &r_u->sid[i], ps, depth)) + return False; } } } diff --git a/source/rpc_parse/parse_sec.c b/source/rpc_parse/parse_sec.c index 081173cf8de..870402db5d3 100644 --- a/source/rpc_parse/parse_sec.c +++ b/source/rpc_parse/parse_sec.c @@ -48,7 +48,7 @@ BOOL sec_io_access(const char *desc, SEC_ACCESS *t, prs_struct *ps, int depth) prs_debug(ps, depth, desc, "sec_io_access"); depth++; - if(!prs_uint32("mask", ps, depth, &(t->mask))) + if(!prs_uint32("mask", ps, depth, &t->mask)) return False; return True; @@ -579,8 +579,6 @@ SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision, { SEC_DESC *dst; uint32 offset = 0; - uint32 offset_sid = SEC_DESC_HEADER_SIZE; - uint32 offset_acl = 0; *sd_size = 0; @@ -610,58 +608,33 @@ SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision, if(dacl && ((dst->dacl = dup_sec_acl(ctx, dacl)) == NULL)) goto error_exit; - offset = 0; + offset = SEC_DESC_HEADER_SIZE; /* * Work out the linearization sizes. */ - if (dst->owner_sid != NULL) { - - if (offset == 0) - offset = SEC_DESC_HEADER_SIZE; - - offset += sid_size(dst->owner_sid); - } - - if (dst->grp_sid != NULL) { - - if (offset == 0) - offset = SEC_DESC_HEADER_SIZE; - - offset += sid_size(dst->grp_sid); - } if (dst->sacl != NULL) { - - offset_acl = SEC_DESC_HEADER_SIZE; - - dst->off_sacl = offset_acl; - offset_acl += dst->sacl->size; - offset += dst->sacl->size; - offset_sid += dst->sacl->size; + dst->off_sacl = offset; + offset += dst->sacl->size; } if (dst->dacl != NULL) { - - if (offset_acl == 0) - offset_acl = SEC_DESC_HEADER_SIZE; - - dst->off_dacl = offset_acl; - offset_acl += dst->dacl->size; - offset += dst->dacl->size; - offset_sid += dst->dacl->size; + dst->off_dacl = offset; + offset += dst->dacl->size; } - *sd_size = (size_t)((offset == 0) ? SEC_DESC_HEADER_SIZE : offset); + if (dst->owner_sid != NULL) { + dst->off_owner_sid = offset; + offset += sid_size(dst->owner_sid); + } - if (dst->owner_sid != NULL) - dst->off_owner_sid = offset_sid; - - /* sid_size() returns 0 if the sid is NULL so this is ok */ - - if (dst->grp_sid != NULL) - dst->off_grp_sid = offset_sid + sid_size(dst->owner_sid); + if (dst->grp_sid != NULL) { + dst->off_grp_sid = offset; + offset += sid_size(dst->grp_sid); + } + *sd_size = (size_t)offset; return dst; error_exit: diff --git a/source/rpc_server/srv_lsa.c b/source/rpc_server/srv_lsa.c index 1c4ef6c8e6f..679cfb73bba 100644 --- a/source/rpc_server/srv_lsa.c +++ b/source/rpc_server/srv_lsa.c @@ -642,176 +642,45 @@ static BOOL api_lsa_query_info2(pipes_struct *p) } - -/*************************************************************************** - api_lsa_enum_acctrights - ***************************************************************************/ -static BOOL api_lsa_enum_acct_rights(pipes_struct *p) -{ - LSA_Q_ENUM_ACCT_RIGHTS q_u; - LSA_R_ENUM_ACCT_RIGHTS r_u; - - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!lsa_io_q_enum_acct_rights("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_enum_acct_rights: failed to unmarshall LSA_Q_ENUM_ACCT_RIGHTS.\n")); - return False; - } - - r_u.status = _lsa_enum_acct_rights(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_enum_acct_rights("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_enum_acct_rights: Failed to marshall LSA_R_ENUM_ACCT_RIGHTS.\n")); - return False; - } - - return True; -} - - -/*************************************************************************** - api_lsa_enum_acct_with_right - ***************************************************************************/ -static BOOL api_lsa_enum_acct_with_right(pipes_struct *p) -{ - LSA_Q_ENUM_ACCT_WITH_RIGHT q_u; - LSA_R_ENUM_ACCT_WITH_RIGHT r_u; - - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!lsa_io_q_enum_acct_with_right("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_enum_acct_with_right: failed to unmarshall LSA_Q_ENUM_ACCT_WITH_RIGHT.\n")); - return False; - } - - r_u.status = _lsa_enum_acct_with_right(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_enum_acct_with_right("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_enum_acct_with_right: Failed to marshall LSA_R_ENUM_ACCT_WITH_RIGHT.\n")); - return False; - } - - return True; -} - - -/*************************************************************************** - api_lsa_add_acctrights - ***************************************************************************/ -static BOOL api_lsa_add_acct_rights(pipes_struct *p) -{ - LSA_Q_ADD_ACCT_RIGHTS q_u; - LSA_R_ADD_ACCT_RIGHTS r_u; - - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!lsa_io_q_add_acct_rights("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_add_acct_rights: failed to unmarshall LSA_Q_ADD_ACCT_RIGHTS.\n")); - return False; - } - - r_u.status = _lsa_add_acct_rights(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_add_acct_rights("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_add_acct_rights: Failed to marshall LSA_R_ADD_ACCT_RIGHTS.\n")); - return False; - } - - return True; -} - - -/*************************************************************************** - api_lsa_remove_acctrights - ***************************************************************************/ -static BOOL api_lsa_remove_acct_rights(pipes_struct *p) -{ - LSA_Q_REMOVE_ACCT_RIGHTS q_u; - LSA_R_REMOVE_ACCT_RIGHTS r_u; - - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!lsa_io_q_remove_acct_rights("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_remove_acct_rights: failed to unmarshall LSA_Q_REMOVE_ACCT_RIGHTS.\n")); - return False; - } - - r_u.status = _lsa_remove_acct_rights(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_remove_acct_rights("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_remove_acct_rights: Failed to marshall LSA_R_REMOVE_ACCT_RIGHTS.\n")); - return False; - } - - return True; -} - - /*************************************************************************** \PIPE\ntlsa commands ***************************************************************************/ - NTSTATUS rpc_lsa_init(void) { - static const struct api_struct api_lsa_cmds[] = - { - { "LSA_OPENPOLICY2" , LSA_OPENPOLICY2 , api_lsa_open_policy2 }, - { "LSA_OPENPOLICY" , LSA_OPENPOLICY , api_lsa_open_policy }, - { "LSA_QUERYINFOPOLICY" , LSA_QUERYINFOPOLICY , api_lsa_query_info }, - { "LSA_ENUMTRUSTDOM" , LSA_ENUMTRUSTDOM , api_lsa_enum_trust_dom }, - { "LSA_CLOSE" , LSA_CLOSE , api_lsa_close }, - { "LSA_OPENSECRET" , LSA_OPENSECRET , api_lsa_open_secret }, - { "LSA_LOOKUPSIDS" , LSA_LOOKUPSIDS , api_lsa_lookup_sids }, - { "LSA_LOOKUPNAMES" , LSA_LOOKUPNAMES , api_lsa_lookup_names }, - { "LSA_ENUM_PRIVS" , LSA_ENUM_PRIVS , api_lsa_enum_privs }, - { "LSA_PRIV_GET_DISPNAME",LSA_PRIV_GET_DISPNAME,api_lsa_priv_get_dispname}, - { "LSA_ENUM_ACCOUNTS" , LSA_ENUM_ACCOUNTS , api_lsa_enum_accounts }, - { "LSA_UNK_GET_CONNUSER", LSA_UNK_GET_CONNUSER, api_lsa_unk_get_connuser }, - { "LSA_OPENACCOUNT" , LSA_OPENACCOUNT , api_lsa_open_account }, - { "LSA_ENUMPRIVSACCOUNT", LSA_ENUMPRIVSACCOUNT, api_lsa_enum_privsaccount}, - { "LSA_GETSYSTEMACCOUNT", LSA_GETSYSTEMACCOUNT, api_lsa_getsystemaccount }, - { "LSA_SETSYSTEMACCOUNT", LSA_SETSYSTEMACCOUNT, api_lsa_setsystemaccount }, - { "LSA_ADDPRIVS" , LSA_ADDPRIVS , api_lsa_addprivs }, - { "LSA_REMOVEPRIVS" , LSA_REMOVEPRIVS , api_lsa_removeprivs }, - { "LSA_QUERYSECOBJ" , LSA_QUERYSECOBJ , api_lsa_query_secobj }, - { "LSA_ENUMACCTRIGHTS" , LSA_ENUMACCTRIGHTS , api_lsa_enum_acct_rights }, - { "LSA_ENUMACCTWITHRIGHT", LSA_ENUMACCTWITHRIGHT, api_lsa_enum_acct_with_right }, - { "LSA_ADDACCTRIGHTS" , LSA_ADDACCTRIGHTS , api_lsa_add_acct_rights }, - { "LSA_REMOVEACCTRIGHTS", LSA_REMOVEACCTRIGHTS, api_lsa_remove_acct_rights}, - /* be careful of the adding of new RPC's. See commentrs below about - * ADS DC capabilities */ - { "LSA_QUERYINFO2" , LSA_QUERYINFO2 , api_lsa_query_info2 }, - }; - +static const struct api_struct api_lsa_cmds[] = +{ + { "LSA_OPENPOLICY2" , LSA_OPENPOLICY2 , api_lsa_open_policy2 }, + { "LSA_OPENPOLICY" , LSA_OPENPOLICY , api_lsa_open_policy }, + { "LSA_QUERYINFOPOLICY" , LSA_QUERYINFOPOLICY , api_lsa_query_info }, + { "LSA_ENUMTRUSTDOM" , LSA_ENUMTRUSTDOM , api_lsa_enum_trust_dom }, + { "LSA_CLOSE" , LSA_CLOSE , api_lsa_close }, + { "LSA_OPENSECRET" , LSA_OPENSECRET , api_lsa_open_secret }, + { "LSA_LOOKUPSIDS" , LSA_LOOKUPSIDS , api_lsa_lookup_sids }, + { "LSA_LOOKUPNAMES" , LSA_LOOKUPNAMES , api_lsa_lookup_names }, + { "LSA_ENUM_PRIVS" , LSA_ENUM_PRIVS , api_lsa_enum_privs }, + { "LSA_PRIV_GET_DISPNAME",LSA_PRIV_GET_DISPNAME,api_lsa_priv_get_dispname}, + { "LSA_ENUM_ACCOUNTS" , LSA_ENUM_ACCOUNTS , api_lsa_enum_accounts }, + { "LSA_UNK_GET_CONNUSER", LSA_UNK_GET_CONNUSER, api_lsa_unk_get_connuser }, + { "LSA_OPENACCOUNT" , LSA_OPENACCOUNT , api_lsa_open_account }, + { "LSA_ENUMPRIVSACCOUNT", LSA_ENUMPRIVSACCOUNT, api_lsa_enum_privsaccount}, + { "LSA_GETSYSTEMACCOUNT", LSA_GETSYSTEMACCOUNT, api_lsa_getsystemaccount }, + { "LSA_SETSYSTEMACCOUNT", LSA_SETSYSTEMACCOUNT, api_lsa_setsystemaccount }, + { "LSA_ADDPRIVS" , LSA_ADDPRIVS , api_lsa_addprivs }, + { "LSA_REMOVEPRIVS" , LSA_REMOVEPRIVS , api_lsa_removeprivs }, + { "LSA_QUERYSECOBJ" , LSA_QUERYSECOBJ , api_lsa_query_secobj }, + /* be careful of the adding of new RPC's. See commentrs below about + ADS DC capabilities */ + { "LSA_QUERYINFO2" , LSA_QUERYINFO2 , api_lsa_query_info2 } +}; /* * NOTE: Certain calls can not be enabled if we aren't an ADS DC. Make sure * these calls are always last and that you decrement by the amount of calls * to disable. - */ + */ int funcs = sizeof(api_lsa_cmds) / sizeof(struct api_struct); if (!(SEC_ADS == lp_security() && ROLE_DOMAIN_PDC == lp_server_role())) { - funcs -= 1; + funcs -= 1; } return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "lsarpc", "lsass", api_lsa_cmds, diff --git a/source/rpc_server/srv_lsa_nt.c b/source/rpc_server/srv_lsa_nt.c index 3581be01819..2a24d7faa57 100644 --- a/source/rpc_server/srv_lsa_nt.c +++ b/source/rpc_server/srv_lsa_nt.c @@ -547,7 +547,7 @@ NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INF switch (lp_server_role()) { case ROLE_DOMAIN_PDC: case ROLE_DOMAIN_BDC: - name = lp_workgroup(); + name = get_global_sam_name(); sid = get_global_sam_sid(); break; case ROLE_DOMAIN_MEMBER: @@ -573,23 +573,8 @@ NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INF return NT_STATUS_ACCESS_DENIED; /* Request PolicyAccountDomainInformation. */ - switch (lp_server_role()) { - case ROLE_DOMAIN_PDC: - case ROLE_DOMAIN_BDC: - name = lp_workgroup(); - sid = get_global_sam_sid(); - break; - case ROLE_DOMAIN_MEMBER: - name = global_myname(); - sid = get_global_sam_sid(); - break; - case ROLE_STANDALONE: - name = global_myname(); - sid = get_global_sam_sid(); - break; - default: - return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - } + name = get_global_sam_name(); + sid = get_global_sam_sid(); init_dom_query(&r_u->dom.id5, name, sid); break; case 0x06: @@ -645,7 +630,7 @@ NTSTATUS _lsa_lookup_sids(pipes_struct *p, LSA_Q_LOOKUP_SIDS *q_u, LSA_R_LOOKUP_ num_entries = MAX_LOOKUP_SIDS; DEBUG(5,("_lsa_lookup_sids: truncating SID lookup list to %d\n", num_entries)); } - + ref = (DOM_R_REF *)talloc_zero(p->mem_ctx, sizeof(DOM_R_REF)); names = (LSA_TRANS_NAME_ENUM *)talloc_zero(p->mem_ctx, sizeof(LSA_TRANS_NAME_ENUM)); @@ -1240,7 +1225,7 @@ NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_I switch (lp_server_role()) { case ROLE_DOMAIN_PDC: case ROLE_DOMAIN_BDC: - nb_name = lp_workgroup(); + nb_name = get_global_sam_name(); /* ugly temp hack for these next two */ /* This should be a 'netbios domain -> DNS domain' mapping */ @@ -1273,140 +1258,3 @@ NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_I return r_u->status; } - - -/*************************************************************************** - For a given SID, enumerate all the privilege this account has. - ***************************************************************************/ -NTSTATUS _lsa_enum_acct_rights(pipes_struct *p, LSA_Q_ENUM_ACCT_RIGHTS *q_u, LSA_R_ENUM_ACCT_RIGHTS *r_u) -{ - struct lsa_info *info=NULL; - char **rights = NULL; - int num_rights = 0; - int i; - - r_u->status = NT_STATUS_OK; - - /* find the connection policy handle. */ - if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) - return NT_STATUS_INVALID_HANDLE; - - r_u->status = privilege_enum_account_rights(&q_u->sid.sid, &num_rights, &rights); - - init_r_enum_acct_rights(r_u, num_rights, (const char **)rights); - - for (i=0;i<num_rights;i++) { - free(rights[i]); - } - safe_free(rights); - - return r_u->status; -} - -/*************************************************************************** -return a list of SIDs for a particular privilege - ***************************************************************************/ -NTSTATUS _lsa_enum_acct_with_right(pipes_struct *p, - LSA_Q_ENUM_ACCT_WITH_RIGHT *q_u, - LSA_R_ENUM_ACCT_WITH_RIGHT *r_u) -{ - struct lsa_info *info=NULL; - char *right; - DOM_SID *sids = NULL; - uint32 count = 0; - - r_u->status = NT_STATUS_OK; - - /* find the connection policy handle. */ - if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) - return NT_STATUS_INVALID_HANDLE; - - right = unistr2_tdup(p->mem_ctx, &q_u->right); - - DEBUG(5,("lsa_enum_acct_with_right on right %s\n", right)); - - r_u->status = privilege_enum_account_with_right(right, &count, &sids); - - init_r_enum_acct_with_right(r_u, count, sids); - - safe_free(sids); - - return r_u->status; -} - -/*************************************************************************** - add privileges to a acct by SID - ***************************************************************************/ -NTSTATUS _lsa_add_acct_rights(pipes_struct *p, LSA_Q_ADD_ACCT_RIGHTS *q_u, LSA_R_ADD_ACCT_RIGHTS *r_u) -{ - struct lsa_info *info=NULL; - int i; - - r_u->status = NT_STATUS_OK; - - /* find the connection policy handle. */ - if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) - return NT_STATUS_INVALID_HANDLE; - - DEBUG(5,("_lsa_add_acct_rights to %s (%d rights)\n", - sid_string_static(&q_u->sid.sid), q_u->rights.count)); - - for (i=0;i<q_u->rights.count;i++) { - DEBUG(5,("\t%s\n", unistr2_static(&q_u->rights.strings[i].string))); - } - - - for (i=0;i<q_u->rights.count;i++) { - r_u->status = privilege_add_account_right(unistr2_static(&q_u->rights.strings[i].string), - &q_u->sid.sid); - if (!NT_STATUS_IS_OK(r_u->status)) { - DEBUG(2,("Failed to add right '%s'\n", - unistr2_static(&q_u->rights.strings[i].string))); - break; - } - } - - init_r_add_acct_rights(r_u); - - return r_u->status; -} - - -/*************************************************************************** - remove privileges from a acct by SID - ***************************************************************************/ -NTSTATUS _lsa_remove_acct_rights(pipes_struct *p, LSA_Q_REMOVE_ACCT_RIGHTS *q_u, LSA_R_REMOVE_ACCT_RIGHTS *r_u) -{ - struct lsa_info *info=NULL; - int i; - - r_u->status = NT_STATUS_OK; - - /* find the connection policy handle. */ - if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) - return NT_STATUS_INVALID_HANDLE; - - - DEBUG(5,("_lsa_remove_acct_rights from %s all=%d (%d rights)\n", - sid_string_static(&q_u->sid.sid), - q_u->removeall, - q_u->rights.count)); - - for (i=0;i<q_u->rights.count;i++) { - DEBUG(5,("\t%s\n", unistr2_static(&q_u->rights.strings[i].string))); - } - - for (i=0;i<q_u->rights.count;i++) { - r_u->status = privilege_remove_account_right(unistr2_static(&q_u->rights.strings[i].string), - &q_u->sid.sid); - if (!NT_STATUS_IS_OK(r_u->status)) { - DEBUG(2,("Failed to remove right '%s'\n", - unistr2_static(&q_u->rights.strings[i].string))); - break; - } - } - - init_r_remove_acct_rights(r_u); - - return r_u->status; -} diff --git a/source/rpc_server/srv_samr_nt.c b/source/rpc_server/srv_samr_nt.c index fc29df39761..ee496126ada 100644 --- a/source/rpc_server/srv_samr_nt.c +++ b/source/rpc_server/srv_samr_nt.c @@ -2575,14 +2575,7 @@ NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_EN return r_u->status; } - switch (lp_server_role()) { - case ROLE_DOMAIN_PDC: - case ROLE_DOMAIN_BDC: - name = lp_workgroup(); - break; - default: - name = global_myname(); - } + name = get_global_sam_name(); fstrcpy(dom[0],name); strupper(dom[0]); diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c index 24459a26f09..92b1481ab82 100644 --- a/source/rpc_server/srv_spoolss_nt.c +++ b/source/rpc_server/srv_spoolss_nt.c @@ -1025,9 +1025,9 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx ) } if ( sending_msg_count ) { - cli_spoolss_rrpcn( ¬ify_cli, mem_ctx, &p->notify.client_hnd, - data_len, data, p->notify.change, 0 ); - } + cli_spoolss_rrpcn( ¬ify_cli, mem_ctx, &p->notify.client_hnd, + data_len, data, p->notify.change, 0 ); + } } done: @@ -7609,12 +7609,12 @@ static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environmen { pstring path; pstring long_archi; - pstring short_archi; + const char *short_archi; DRIVER_DIRECTORY_1 *info=NULL; unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1); - if (get_short_archi(short_archi, long_archi)==False) + if (!(short_archi = get_short_archi(long_archi))) return WERR_INVALID_ENVIRONMENT; if((info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1))) == NULL) @@ -8440,7 +8440,7 @@ WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_ /**************************************************************************** ****************************************************************************/ -static WERROR getjob_level_1(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) { int i=0; BOOL found=False; @@ -8453,7 +8453,7 @@ static WERROR getjob_level_1(print_queue_struct *queue, int count, int snum, uin } for (i=0; i<count && found==False; i++) { - if (queue[i].job==(int)jobid) + if ((*queue)[i].job==(int)jobid) found=True; } @@ -8463,7 +8463,7 @@ static WERROR getjob_level_1(print_queue_struct *queue, int count, int snum, uin return WERR_INVALID_PARAM; } - fill_job_info_1(info_1, &(queue[i-1]), i, snum); + fill_job_info_1(info_1, &((*queue)[i-1]), i, snum); *needed += spoolss_size_job_info_1(info_1); @@ -8485,7 +8485,7 @@ static WERROR getjob_level_1(print_queue_struct *queue, int count, int snum, uin /**************************************************************************** ****************************************************************************/ -static WERROR getjob_level_2(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) { int i = 0; BOOL found = False; @@ -8506,7 +8506,7 @@ static WERROR getjob_level_2(print_queue_struct *queue, int count, int snum, uin for ( i=0; i<count && found==False; i++ ) { - if (queue[i].job == (int)jobid) + if ((*queue)[i].job == (int)jobid) found = True; } @@ -8537,7 +8537,7 @@ static WERROR getjob_level_2(print_queue_struct *queue, int count, int snum, uin } } - fill_job_info_2(info_2, &(queue[i-1]), i, snum, ntprinter, devmode); + fill_job_info_2(info_2, &((*queue)[i-1]), i, snum, ntprinter, devmode); *needed += spoolss_size_job_info_2(info_2); @@ -8601,11 +8601,11 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_ switch ( level ) { case 1: - wstatus = getjob_level_1(queue, count, snum, jobid, + wstatus = getjob_level_1(&queue, count, snum, jobid, buffer, offered, needed); break; case 2: - wstatus = getjob_level_2(queue, count, snum, jobid, + wstatus = getjob_level_2(&queue, count, snum, jobid, buffer, offered, needed); break; default: @@ -9143,12 +9143,12 @@ static WERROR getprintprocessordirectory_level_1(UNISTR2 *name, { pstring path; pstring long_archi; - pstring short_archi; + const char *short_archi; PRINTPROCESSOR_DIRECTORY_1 *info=NULL; unistr2_to_ascii(long_archi, environment, sizeof(long_archi)-1); - if (get_short_archi(short_archi, long_archi)==False) + if (!(short_archi = get_short_archi(long_archi))) return WERR_INVALID_ENVIRONMENT; if((info=(PRINTPROCESSOR_DIRECTORY_1 *)malloc(sizeof(PRINTPROCESSOR_DIRECTORY_1))) == NULL) diff --git a/source/rpc_server/srv_srvsvc_nt.c b/source/rpc_server/srv_srvsvc_nt.c index 4d9130fb970..57ba055aefa 100644 --- a/source/rpc_server/srv_srvsvc_nt.c +++ b/source/rpc_server/srv_srvsvc_nt.c @@ -1840,8 +1840,6 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC struct current_user user; connection_struct *conn = NULL; BOOL became_user = False; - fstring dev; - fstrcpy(dev, "A:"); ZERO_STRUCT(st); @@ -1855,7 +1853,7 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC get_current_user(&user, p); become_root(); - conn = make_connection(qualname, null_pw, dev, user.vuid, &nt_status); + conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status); unbecome_root(); if (conn == NULL) { @@ -1889,7 +1887,7 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC } } - sd_size = conn->vfs_ops.get_nt_acl(fsp, fsp->fsp_name, &psd); + sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd); if (sd_size == 0) { DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename)); @@ -1945,12 +1943,9 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_ struct current_user user; connection_struct *conn = NULL; BOOL became_user = False; - fstring dev; - fstrcpy(dev, "A:"); ZERO_STRUCT(st); - r_u->status = WERR_OK; unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname)); @@ -1961,7 +1956,7 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_ get_current_user(&user, p); become_root(); - conn = make_connection(qualname, null_pw, dev, user.vuid, &nt_status); + conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status); unbecome_root(); if (conn == NULL) { @@ -1996,7 +1991,7 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_ } } - ret = conn->vfs_ops.set_nt_acl(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc); + ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc); if (ret == False) { DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename)); diff --git a/source/rpc_server/srv_util.c b/source/rpc_server/srv_util.c index f96ccaef672..c43eb22375e 100644 --- a/source/rpc_server/srv_util.c +++ b/source/rpc_server/srv_util.c @@ -194,7 +194,7 @@ NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, ui break; } - free(groups); + if(num_groups) free(groups); /* now check for the user's gid (the primary group rid) */ for (i=0; i<cur_rid && grid!=rids[i]; i++) diff --git a/source/rpcclient/cmd_lsarpc.c b/source/rpcclient/cmd_lsarpc.c index 808ef50a455..db74370bc0b 100644 --- a/source/rpcclient/cmd_lsarpc.c +++ b/source/rpcclient/cmd_lsarpc.c @@ -543,50 +543,6 @@ static NTSTATUS cmd_lsa_enum_acct_rights(struct cli_state *cli, } -/* Enumerate the accounts with a specific right */ - -static NTSTATUS cmd_lsa_enum_acct_with_right(struct cli_state *cli, - TALLOC_CTX *mem_ctx, int argc, - const char **argv) -{ - POLICY_HND dom_pol; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DOM_SID *sids; - uint32 count; - const char *right; - - int i; - - if (argc != 2 ) { - printf("Usage: %s <RIGHT>\n", argv[0]); - return NT_STATUS_OK; - } - - right = argv[1]; - - result = cli_lsa_open_policy2(cli, mem_ctx, True, - SEC_RIGHTS_MAXIMUM_ALLOWED, - &dom_pol); - - if (!NT_STATUS_IS_OK(result)) - goto done; - - result = cli_lsa_enum_account_with_right(cli, mem_ctx, &dom_pol, right, &count, &sids); - - if (!NT_STATUS_IS_OK(result)) - goto done; - - printf("found %d SIDs for '%s'\n", count, right); - - for (i = 0; i < count; i++) { - printf("\t%s\n", sid_string_static(&sids[i])); - } - - done: - return result; -} - - /* add some privileges to a SID via LsaAddAccountRights */ static NTSTATUS cmd_lsa_add_acct_rights(struct cli_state *cli, @@ -750,7 +706,6 @@ struct cmd_set lsarpc_commands[] = { { "lsaenumsid", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_sids, NULL, PI_LSARPC, "Enumerate the LSA SIDS", "" }, { "lsaenumprivsaccount", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_privsaccounts, NULL, PI_LSARPC, "Enumerate the privileges of an SID", "" }, { "lsaenumacctrights", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_acct_rights, NULL, PI_LSARPC, "Enumerate the rights of an SID", "" }, - { "lsaenumacctwithright",RPC_RTYPE_NTSTATUS, cmd_lsa_enum_acct_with_right,NULL, PI_LSARPC,"Enumerate accounts with a right", "" }, { "lsaaddacctrights", RPC_RTYPE_NTSTATUS, cmd_lsa_add_acct_rights, NULL, PI_LSARPC, "Add rights to an account", "" }, { "lsaremoveacctrights", RPC_RTYPE_NTSTATUS, cmd_lsa_remove_acct_rights, NULL, PI_LSARPC, "Remove rights from an account", "" }, { "lsalookupprivvalue", RPC_RTYPE_NTSTATUS, cmd_lsa_lookupprivvalue, NULL, PI_LSARPC, "Get a privilege value given its name", "" }, diff --git a/source/rpcclient/cmd_netlogon.c b/source/rpcclient/cmd_netlogon.c index 32fa9c3699f..0ec78a06734 100644 --- a/source/rpcclient/cmd_netlogon.c +++ b/source/rpcclient/cmd_netlogon.c @@ -275,6 +275,7 @@ static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli, const char *username, *password; uint32 neg_flags = 0x000001ff; int auth_level = 2; + DOM_CRED ret_creds; /* Check arguments */ @@ -299,7 +300,13 @@ static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli, /* Perform the sam logon */ - result = cli_netlogon_sam_logon(cli, mem_ctx, username, password, logon_type); + ZERO_STRUCT(ret_creds); + + result = cli_netlogon_sam_logon(cli, mem_ctx, &ret_creds, username, password, logon_type); + + clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &ret_creds); + + result = cli_netlogon_sam_logon(cli, mem_ctx, &ret_creds, username, password, logon_type); if (!NT_STATUS_IS_OK(result)) goto done; diff --git a/source/rpcclient/cmd_spoolss.c b/source/rpcclient/cmd_spoolss.c index 3ce7f9e6ac8..e4ff06a35ec 100644 --- a/source/rpcclient/cmd_spoolss.c +++ b/source/rpcclient/cmd_spoolss.c @@ -54,7 +54,7 @@ static const struct table_node archi_table[]= { function to do the mapping between the long architecture name and the short one. ****************************************************************************/ -BOOL get_short_archi(char *short_archi, const char *long_archi) +static const char *cmd_spoolss_get_short_archi(const char *long_archi) { int i=-1; @@ -66,18 +66,17 @@ BOOL get_short_archi(char *short_archi, const char *long_archi) if (archi_table[i].long_archi==NULL) { DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi)); - return False; + return NULL; } /* this might be client code - but shouldn't this be an fstrcpy etc? */ - StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi)); DEBUGADD(108,("index: [%d]\n", i)); - DEBUGADD(108,("long architecture: [%s]\n", long_archi)); - DEBUGADD(108,("short architecture: [%s]\n", short_archi)); + DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi)); + DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi)); - return True; + return archi_table[i].short_archi; } #if 0 @@ -1153,7 +1152,7 @@ static char* get_driver_3_param (const char* str, const char* delim, UNISTR* des parameter because two consecutive delimiters will not return an empty string. See man strtok(3) for details */ - if (StrCaseCmp(ptr, "NULL") == 0) + if (ptr && (StrCaseCmp(ptr, "NULL") == 0)) ptr = NULL; if (dest != NULL) @@ -1227,7 +1226,7 @@ static WERROR cmd_spoolss_addprinterdriver(struct cli_state *cli, uint32 level = 3; PRINTER_DRIVER_CTR ctr; DRIVER_INFO_3 info3; - fstring arch; + const char *arch; fstring driver_name; /* parse the command arguements */ @@ -1243,7 +1242,7 @@ static WERROR cmd_spoolss_addprinterdriver(struct cli_state *cli, /* Fill in the DRIVER_INFO_3 struct */ ZERO_STRUCT(info3); - if (!get_short_archi(arch, argv[1])) + if (!(arch = cmd_spoolss_get_short_archi(argv[1]))) { printf ("Error Unknown architechture [%s]\n", argv[1]); return WERR_INVALID_PARAM; diff --git a/source/rpcclient/rpcclient.c b/source/rpcclient/rpcclient.c index b01e2d694c5..a1b0a8cd345 100644 --- a/source/rpcclient/rpcclient.c +++ b/source/rpcclient/rpcclient.c @@ -391,6 +391,14 @@ static NTSTATUS do_cmd(struct cli_state *cli, /* Open pipe */ + if (cmd_entry->pipe_idx != -1) { + if (!cli_nt_session_open(cli, cmd_entry->pipe_idx)) { + DEBUG(0, ("Could not initialise %s\n", + get_pipe_name_from_index(cmd_entry->pipe_idx))); + return NT_STATUS_UNSUCCESSFUL; + } + } + if (cmd_entry->pipe_idx == PI_NETLOGON) { uchar trust_password[16]; uint32 sec_channel_type; @@ -401,19 +409,11 @@ static NTSTATUS do_cmd(struct cli_state *cli, return NT_STATUS_UNSUCCESSFUL; } - if (!cli_nt_open_netlogon(cli, trust_password, - sec_channel_type)) { + if (!NT_STATUS_IS_OK(cli_nt_establish_netlogon(cli, sec_channel_type, + trust_password))) { DEBUG(0, ("Could not initialise NETLOGON pipe\n")); return NT_STATUS_UNSUCCESSFUL; } - } else { - if (cmd_entry->pipe_idx != -1) { - if (!cli_nt_session_open(cli, cmd_entry->pipe_idx)) { - DEBUG(0, ("Could not initialise %s\n", - get_pipe_name_from_index(cmd_entry->pipe_idx))); - return NT_STATUS_UNSUCCESSFUL; - } - } } /* Run command */ diff --git a/source/sam/idmap.c b/source/sam/idmap.c index 9695e7b764e..d031c49e257 100644 --- a/source/sam/idmap.c +++ b/source/sam/idmap.c @@ -24,49 +24,69 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_IDMAP -static struct { - +struct idmap_function_entry { const char *name; - /* Function to create a member of the idmap_methods list */ - NTSTATUS (*reg_meth)(struct idmap_methods **methods); struct idmap_methods *methods; - -} remote_idmap_functions[] = { - { NULL, NULL, NULL } + struct idmap_function_entry *prev,*next; }; +static struct idmap_function_entry *backends = NULL; + static struct idmap_methods *local_map; static struct idmap_methods *remote_map; static void lazy_initialize_idmap(void) { static BOOL initialized = False; - if (initialized) return; - idmap_init(); - initialized = True; -} - + if(!initialized) { + idmap_init(); + initialized = True; + } +} static struct idmap_methods *get_methods(const char *name) { - int i = 0; - struct idmap_methods *ret = NULL; + struct idmap_function_entry *entry = backends; - while (remote_idmap_functions[i].name && strcmp(remote_idmap_functions[i].name, name)) { - i++; + while(entry) { + if (strcmp(entry->name, name) == 0) return entry->methods; + entry = entry->next; } - if (remote_idmap_functions[i].name) { + return NULL; +} - if (!remote_idmap_functions[i].methods) { - remote_idmap_functions[i].reg_meth(&remote_idmap_functions[i].methods); - } +NTSTATUS smb_register_idmap(int version, const char *name, struct idmap_methods *methods) +{ + struct idmap_function_entry *entry; + + if ((version != SMB_IDMAP_INTERFACE_VERSION)) { + DEBUG(0, ("Failed to register idmap module.\n" + "The module was compiled against SMB_IDMAP_INTERFACE_VERSION %d,\n" + "current SMB_IDMAP_INTERFACE_VERSION is %d.\n" + "Please recompile against the current version of samba!\n", + version, SMB_IDMAP_INTERFACE_VERSION)); + return NT_STATUS_OBJECT_TYPE_MISMATCH; + } + + if (!name || !name[0] || !methods) { + DEBUG(0,("smb_register_idmap() called with NULL pointer or empty name!\n")); + return NT_STATUS_INVALID_PARAMETER; + } - ret = remote_idmap_functions[i].methods; + if (get_methods(name)) { + DEBUG(0,("idmap module %s already registered!\n", name)); + return NT_STATUS_OBJECT_NAME_COLLISION; } - return ret; + entry = smb_xmalloc(sizeof(struct idmap_function_entry)); + entry->name = smb_xstrdup(name); + entry->methods = methods; + + DLIST_ADD(backends, entry); + DEBUG(5, ("Successfully added idmap backend '%s'\n", name)); + return NT_STATUS_OK; } /* Initialize backend */ @@ -74,23 +94,46 @@ BOOL idmap_init(void) { const char *remote_backend = lp_idmap_backend(); + if (!backends) + static_init_idmap; + if (!local_map) { - idmap_reg_tdb(&local_map); - if (NT_STATUS_IS_ERR(local_map->init())) { + local_map = get_methods("tdb"); + + if (!local_map) { + DEBUG(0, ("idmap_init: could not find tdb backend!\n")); + return False; + } + + if (NT_STATUS_IS_ERR(local_map->init( NULL ))) { DEBUG(0, ("idmap_init: could not load or create local backend!\n")); return False; } } if (!remote_map && remote_backend && *remote_backend != 0) { + fstring params = ""; + char *pparams; + + /* get any mode parameters passed in */ + + if ( (pparams = strchr( remote_backend, ':' )) != NULL ) { + pparams = '\0'; + pparams++; + fstrcpy( params, pparams ); + } + DEBUG(3, ("idmap_init: using '%s' as remote backend\n", remote_backend)); - remote_map = get_methods(remote_backend); - if (!remote_map) { + if((remote_map = get_methods(remote_backend)) || + (NT_STATUS_IS_OK(smb_probe_module("idmap", remote_backend)) && + (remote_map = get_methods(remote_backend)))) { + remote_map->init(params); + } else { DEBUG(0, ("idmap_init: could not load remote backend '%s'\n", remote_backend)); return False; } - remote_map->init(); + } return True; diff --git a/source/sam/idmap_ldap.c b/source/sam/idmap_ldap.c index 33cf5fb0302..379f7729abb 100644 --- a/source/sam/idmap_ldap.c +++ b/source/sam/idmap_ldap.c @@ -3,9 +3,10 @@ idmap LDAP backend - Copyright (C) Tim Potter 2000 - Copyright (C) Anthony Liguori 2003 - Copyright (C) Simo Sorce 2003 + Copyright (C) Tim Potter 2000 + Copyright (C) Anthony Liguori 2003 + Copyright (C) Simo Sorce 2003 + Copyright (C) Gerald Carter 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 @@ -31,10 +32,16 @@ #include <lber.h> #include <ldap.h> +#include "smbldap.h" + +#define IDMAP_GROUP_SUFFIX "ou=idmap group" +#define IDMAP_USER_SUFFIX "ou=idmap people" + + struct ldap_idmap_state { LDAP *ldap_struct; time_t last_ping; - const char *uri; + char *uri; char *bind_dn; char *bind_secret; unsigned int num_failures; @@ -53,70 +60,6 @@ static NTSTATUS ldap_idmap_close(void); /******************************************************************* - find the ldap password -******************************************************************/ -static BOOL fetch_ldapsam_pw(char **dn, char** pw) -{ - char *key = NULL; - size_t size; - - *dn = smb_xstrdup(lp_ldap_admin_dn()); - - if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) { - SAFE_FREE(*dn); - DEBUG(0, ("fetch_ldapsam_pw: asprintf failed!\n")); - } - - *pw=secrets_fetch(key, &size); - SAFE_FREE(key); - - if (!size) { - /* Upgrade 2.2 style entry */ - char *p; - char* old_style_key = strdup(*dn); - char *data; - fstring old_style_pw; - - if (!old_style_key) { - DEBUG(0, ("fetch_ldapsam_pw: strdup failed!\n")); - return False; - } - - for (p=old_style_key; *p; p++) - if (*p == ',') *p = '/'; - - data=secrets_fetch(old_style_key, &size); - if (!size && size < sizeof(old_style_pw)) { - DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n")); - SAFE_FREE(old_style_key); - SAFE_FREE(*dn); - return False; - } - - strncpy(old_style_pw, data, size); - old_style_pw[size] = 0; - - SAFE_FREE(data); - - if (!secrets_store_ldap_pw(*dn, old_style_pw)) { - DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n")); - SAFE_FREE(old_style_key); - SAFE_FREE(*dn); - return False; - } - if (!secrets_delete(old_style_key)) { - DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n")); - } - - SAFE_FREE(old_style_key); - - *pw = smb_xstrdup(old_style_pw); - } - - return True; -} - -/******************************************************************* open a connection to the ldap server. ******************************************************************/ static int ldap_idmap_open_connection(struct ldap_idmap_state *state) @@ -284,6 +227,9 @@ static int ldap_idmap_open(struct ldap_idmap_state *state) return LDAP_SUCCESS; } +/******************************************************************* +******************************************************************/ + static int ldap_idmap_retry_open(struct ldap_idmap_state *state, int *attempts) { int rc; @@ -319,6 +265,7 @@ static int ldap_idmap_retry_open(struct ldap_idmap_state *state, int *attempts) a rebind function for authenticated referrals This version takes a void* that we can shove useful stuff in :-) ******************************************************************/ + #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) #else static int rebindproc_with_state (LDAP * ld, char **whop, char **credp, @@ -421,7 +368,7 @@ static int ldap_idmap_connect_system(struct ldap_idmap_state *state) char *ldap_secret; /* get the password */ - if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret)) + if (!fetch_ldap_pw(&ldap_dn, &ldap_secret)) { DEBUG(0, ("ldap_idmap_connect_system: Failed to retrieve " "password from secrets.tdb\n")); @@ -478,9 +425,13 @@ static int ldap_idmap_connect_system(struct ldap_idmap_state *state) return rc; } +/***************************************************************************** + wrapper around ldap_search() +*****************************************************************************/ + static int ldap_idmap_search(struct ldap_idmap_state *state, const char *base, int scope, const char *filter, - const char *attrs[], int attrsonly, + char *attrs[], int attrsonly, LDAPMessage **res) { int rc = LDAP_SERVER_DOWN; @@ -510,9 +461,10 @@ static int ldap_idmap_search(struct ldap_idmap_state *state, return rc; } -/******************************************************************* -search an attribute and return the first value found. -******************************************************************/ +/*********************************************************************** + search an attribute and return the first value found. +***********************************************************************/ + static BOOL ldap_idmap_attribute (struct ldap_idmap_state *state, LDAPMessage * entry, const char *attribute, pstring value) @@ -520,12 +472,16 @@ static BOOL ldap_idmap_attribute (struct ldap_idmap_state *state, char **values; value[0] = '\0'; - if ((values = ldap_get_values (state->ldap_struct, entry, attribute)) - == NULL) { + if ( !entry ) + return False; + + if ((values = ldap_get_values (state->ldap_struct, entry, attribute)) == NULL) + { DEBUG(10,("get_single_attribute: [%s] = [<does not exist>]\n", attribute)); return False; } + if (convert_string(CH_UTF8, CH_UNIX, values[0], -1, value, sizeof(pstring)) == (size_t)-1) @@ -540,9 +496,9 @@ static BOOL ldap_idmap_attribute (struct ldap_idmap_state *state, return True; } -static const char *attrs[] = {"objectClass", "uidNumber", "gidNumber", - "ntSid", NULL}; -static const char *pool_attr[] = {"uidNumber", "gidNumber", NULL}; +/***************************************************************************** + Allocate a new uid or gid +*****************************************************************************/ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type) { @@ -552,23 +508,36 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type) LDAPMessage *result = 0; LDAPMessage *entry = 0; pstring id_str, new_id_str; - LDAPMod mod[2]; - LDAPMod *mods[3]; - const char *type = (id_type & ID_USERID) ? "uidNumber" : "gidNumber"; - char *val[4]; + LDAPMod **mods = NULL; + const char *type; char *dn; + char **attr_list; + pstring filter; + uid_t luid, huid; + gid_t lgid, hgid; + - rc = ldap_idmap_search(&ldap_state, lp_ldap_suffix(), - LDAP_SCOPE_SUBTREE, "(objectClass=unixIdPool)", - pool_attr, 0, &result); + type = (id_type & ID_USERID) ? + get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER ) : + get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER ); + + snprintf(filter, sizeof(filter)-1, "(objectClass=%s)", LDAP_OBJ_IDPOOL); + + attr_list = get_attr_list( idpool_attr_list ); + + rc = ldap_idmap_search(&ldap_state, lp_ldap_idmap_suffix(), + LDAP_SCOPE_SUBTREE, filter, + attr_list, 0, &result); + free_attr_list( attr_list ); + if (rc != LDAP_SUCCESS) { - DEBUG(0,("ldap_allocate_id: unixIdPool object not found\n")); + DEBUG(0,("ldap_allocate_id: %s object not found\n", LDAP_OBJ_IDPOOL)); goto out; } count = ldap_count_entries(ldap_state.ldap_struct, result); if (count != 1) { - DEBUG(0,("ldap_allocate_id: single unixIdPool not found\n")); + DEBUG(0,("ldap_allocate_id: single %s object not found\n", LDAP_OBJ_IDPOOL)); goto out; } @@ -580,210 +549,308 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type) type)); goto out; } + + /* this must succeed or else we wouldn't have initialized */ + + lp_idmap_uid( &luid, &huid); + lp_idmap_gid( &lgid, &hgid); + + /* make sure we still have room to grow */ + if (id_type & ID_USERID) { id->uid = strtoul(id_str, NULL, 10); - } else { + if (id->uid > huid ) { + DEBUG(0,("ldap_allocate_id: Cannot allocate uid above %d!\n", huid)); + goto out; + } + } + else { id->gid = strtoul(id_str, NULL, 10); + if (id->gid > hgid ) { + DEBUG(0,("ldap_allocate_id: Cannot allocate gid above %d!\n", hgid)); + goto out; + } } - - mod[0].mod_op = LDAP_MOD_DELETE; - mod[0].mod_type = strdup(type); - val[0] = id_str; val[1] = NULL; - mod[0].mod_values = val; - - pstr_sprintf(new_id_str, "%ud", + + snprintf(new_id_str, sizeof(new_id_str), "%u", ((id_type & ID_USERID) ? id->uid : id->gid) + 1); - mod[1].mod_op = LDAP_MOD_ADD; - mod[1].mod_type = strdup(type); - val[3] = new_id_str; val[4] = NULL; - mod[1].mod_values = val + 2; - - mods[0] = mod; mods[1] = mod + 1; mods[2] = NULL; + + ldap_set_mod( &mods, LDAP_MOD_DELETE, type, id_str ); + ldap_set_mod( &mods, LDAP_MOD_ADD, type, new_id_str ); + rc = ldap_modify_s(ldap_state.ldap_struct, dn, mods); - ldap_memfree(dn); - if (rc == LDAP_SUCCESS) ret = NT_STATUS_OK; + ldap_memfree(dn); + ldap_mods_free( mods, True ); + + if (rc != LDAP_SUCCESS) { + DEBUG(0,("ldap_allocate_id: Failed to allocate new %s. ldap_modify() failed.\n", + type)); + goto out; + } + + ret = NT_STATUS_OK; out: return ret; } -/* Get a sid from an id */ +/***************************************************************************** + get a sid from an id +*****************************************************************************/ + static NTSTATUS ldap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type) { LDAPMessage *result = 0; LDAPMessage *entry = 0; pstring sid_str; pstring filter; - char type = (id_type & ID_USERID) ? 'u' : 'g'; + pstring suffix; + const char *type; int rc; int count; NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - - pstr_sprintf(filter, "(&(%cidNumber=%ud)(objectClass=sambaAccount))", - type, ((id_type & ID_USERID) ? id.uid : id.gid)); - rc = ldap_idmap_search(&ldap_state, lp_ldap_suffix(), - LDAP_SCOPE_SUBTREE, filter, attrs, 0, - &result); - if (rc != LDAP_SUCCESS) { - goto out; - } + char **attr_list; + + /* first we try for a samba user or group mapping */ + + if ( id_type & ID_USERID ) { + type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER ); + snprintf(filter, sizeof(filter), "(&(objectClass=%s)(%s=%u))", + LDAP_OBJ_SAMBASAMACCOUNT, type, id.uid ); + pstrcpy( suffix, lp_ldap_suffix()); + } + else { + type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER ); + snprintf(filter, sizeof(filter), "(&(objectClass=%s)(%s=%u))", + LDAP_OBJ_GROUPMAP, type, id.gid ); + pstrcpy( suffix, lp_ldap_group_suffix() ); + } + + attr_list = get_attr_list( sidmap_attr_list ); + rc = ldap_idmap_search(&ldap_state, suffix, LDAP_SCOPE_SUBTREE, + filter, attr_list, 0, &result); + if (rc != LDAP_SUCCESS) + goto out; + count = ldap_count_entries(ldap_state.ldap_struct, result); + + /* fall back to looking up an idmap entry if we didn't find and + actual user or group */ + if (count == 0) { - pstr_sprintf(filter, - "(&(objectClass=idmapEntry)(%cidNumber=%ud))", - type, ((id_type & ID_USERID) ? id.uid : id.gid)); - rc = ldap_idmap_search(&ldap_state, lp_ldap_suffix(), - LDAP_SCOPE_SUBTREE, filter, - attrs, 0, &result); - if (rc != LDAP_SUCCESS) { + snprintf(filter, sizeof(filter), "(&(objectClass=%s)(%s=%u))", + LDAP_OBJ_IDMAP_ENTRY, type, ((id_type & ID_USERID) ? id.uid : id.gid)); + +#if 0 /* commented out for now -- jerry */ + if ( id_type & ID_USERID ) + snprintf( suffix, sizeof(suffix), "%s,%s", IDMAP_USER_SUFFIX, lp_ldap_idmap_suffix() ); + else + snprintf( suffix, sizeof(suffix), "%s,%s", IDMAP_GROUP_SUFFIX, lp_ldap_idmap_suffix() ); +#else + pstrcpy( suffix, lp_ldap_idmap_suffix() ); +#endif + + rc = ldap_idmap_search(&ldap_state, suffix, LDAP_SCOPE_SUBTREE, + filter, attr_list, 0, &result); + + if (rc != LDAP_SUCCESS) goto out; - } - count = ldap_count_entries(ldap_state.ldap_struct, result); + + count = ldap_count_entries(ldap_state.ldap_struct, result); } if (count != 1) { - DEBUG(0,("ldap_get_sid_from_id: mapping not found for " - "%cid: %ud\n", (id_type&ID_USERID)?'u':'g', - ((id_type & ID_USERID) ? id.uid : id.gid))); + DEBUG(0,("ldap_get_sid_from_id: mapping not found for %s: %u\n", + type, ((id_type & ID_USERID) ? id.uid : id.gid))); goto out; } entry = ldap_first_entry(ldap_state.ldap_struct, result); - if (!ldap_idmap_attribute(&ldap_state, entry, "ntSid", sid_str)) { + if ( !ldap_idmap_attribute(&ldap_state, entry, LDAP_ATTRIBUTE_SID, sid_str) ) goto out; - } - if (!string_to_sid(sid, sid_str)) { + if (!string_to_sid(sid, sid_str)) goto out; - } ret = NT_STATUS_OK; out: + free_attr_list( attr_list ); + return ret; } -/* Get an id from a sid */ -static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type, - const DOM_SID *sid) +/*********************************************************************** + Get an id from a sid +***********************************************************************/ + +static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *sid) { LDAPMessage *result = 0; LDAPMessage *entry = 0; pstring sid_str; pstring filter; pstring id_str; - const char *type = (*id_type & ID_USERID) ? "uidNumber" : "gidNumber"; - const char *class = - (*id_type & ID_USERID) ? "sambaAccount" : "sambaGroupMapping"; + pstring suffix; + const char *type; + const char *obj_class; int rc; int count; + char **attr_list; NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + + /* first try getting the mapping from a samba user or group */ + + if ( *id_type & ID_USERID ) { + type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER ); + obj_class = LDAP_OBJ_SAMBASAMACCOUNT; + pstrcpy( suffix, lp_ldap_suffix() ); + } + else { + type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER ); + obj_class = LDAP_OBJ_GROUPMAP; + pstrcpy( suffix, lp_ldap_group_suffix() ); + } sid_to_string(sid_str, sid); - pstr_sprintf(filter, "(&(objectClass=%s)(ntSid=%s)", class, sid_str); - rc = ldap_idmap_search(&ldap_state, lp_ldap_suffix(), - LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result); - if (rc != LDAP_SUCCESS) { + snprintf(filter, sizeof(filter), "(&(objectClass=%s)(%s=%s))", obj_class, + LDAP_ATTRIBUTE_SID, sid_str); + + attr_list = get_attr_list( sidmap_attr_list ); + rc = ldap_idmap_search(&ldap_state, suffix, LDAP_SCOPE_SUBTREE, + filter, attr_list, 0, &result); + + if (rc != LDAP_SUCCESS) goto out; - } + count = ldap_count_entries(ldap_state.ldap_struct, result); + + /* fall back to looking up an idmap entry if we didn't find and + actual user or group */ + if (count == 0) { - pstr_sprintf(filter, - "(&(objectClass=idmapEntry)(ntSid=%s))", sid_str); + snprintf(filter, sizeof(filter), "(&(objectClass=%s)(%s=%s))", + LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_SID, sid_str); + +#if 0 /* commented out for now -- jerry */ + if ( *id_type & ID_USERID ) + snprintf( suffix, sizeof(suffix), "%s,%s", IDMAP_USER_SUFFIX, lp_ldap_idmap_suffix() ); + else + snprintf( suffix, sizeof(suffix), "%s,%s", IDMAP_GROUP_SUFFIX, lp_ldap_idmap_suffix() ); +#else + pstrcpy( suffix, lp_ldap_idmap_suffix() ); +#endif - rc = ldap_idmap_search(&ldap_state, lp_ldap_suffix(), - LDAP_SCOPE_SUBTREE, filter, - attrs, 0, &result); - if (rc != LDAP_SUCCESS) { - goto out; - } - count = ldap_count_entries(ldap_state.ldap_struct, result); + rc = ldap_idmap_search(&ldap_state, suffix, LDAP_SCOPE_SUBTREE, + filter, attr_list, 0, &result); + + if (rc != LDAP_SUCCESS) + goto out; + + count = ldap_count_entries(ldap_state.ldap_struct, result); } - - /* our search filters may 2 objects in the case that a user and group - rid are the same */ - if (count != 1 && count != 2) { - DEBUG(0, - ("ldap_get_id_from_sid: incorrect number of objects\n")); + + if ( count > 1 ) { + DEBUG(0, ("ldap_get_id_from_sid: search %s returned more than on entry!\n", + filter)); goto out; } - entry = ldap_first_entry(ldap_state.ldap_struct, result); - if (!ldap_idmap_attribute(&ldap_state, entry, type, id_str)) { - entry = ldap_next_entry(ldap_state.ldap_struct, entry); - - if (!ldap_idmap_attribute(&ldap_state, entry, type, id_str)) { - int i; + /* we might have an existing entry to work with so pull out the requested information */ + + if ( count ) + entry = ldap_first_entry(ldap_state.ldap_struct, result); + + /* if entry == NULL, then we will default to allocating a new id */ + + if ( !ldap_idmap_attribute(&ldap_state, entry, type, id_str) ) + { + int i; - for (i = 0; i < LDAP_MAX_ALLOC_ID; i++) { - ret = ldap_allocate_id(id, *id_type); - if (NT_STATUS_IS_OK(ret)) { - break; - } - } - if (NT_STATUS_IS_OK(ret)) { - ret = ldap_set_mapping(sid, *id, *id_type); - } else { - DEBUG(0,("ldap_allocate_id: cannot acquire id" - " lock\n")); - } - } else { - if ((*id_type & ID_USERID)) { - id->uid = strtoul(id_str, NULL, 10); - } else { - id->gid = strtoul(id_str, NULL, 10); - } - ret = NT_STATUS_OK; + for (i = 0; i < LDAP_MAX_ALLOC_ID; i++) + { + ret = ldap_allocate_id(id, *id_type); + if ( NT_STATUS_IS_OK(ret) ) + break; } - } else { - if ((*id_type & ID_USERID)) { + + if ( !NT_STATUS_IS_OK(ret) ) { + DEBUG(0,("ldap_allocate_id: cannot acquire id lock!\n")); + goto out; + } + + ret = ldap_set_mapping(sid, *id, *id_type); + + } + else + { + if ( (*id_type & ID_USERID) ) id->uid = strtoul(id_str, NULL, 10); - } else { + else id->gid = strtoul(id_str, NULL, 10); - } + ret = NT_STATUS_OK; } out: + free_attr_list( attr_list ); + return ret; } -/* This function cannot be called to modify a mapping, only set a new one */ +/*********************************************************************** + This function cannot be called to modify a mapping, only set a new one +***********************************************************************/ + static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type) { pstring dn, sid_str, id_str; - const char *type = (id_type & ID_USERID) ? "uidNumber" : "gidNumber"; - LDAPMod *mods[3]; - LDAPMod mod[2]; - char *val[4]; + fstring type; + LDAPMod **mods = NULL; int rc; int attempts = 0; - pstr_sprintf(id_str, "%ud", ((id_type & ID_USERID) ? id.uid : id.gid)); - sid_to_string(sid_str, sid); - pstr_sprintf(dn, "%s=%ud,%s", type, ((id_type & ID_USERID) ? id.uid : id.gid), lp_ldap_suffix()); - mod[0].mod_op = LDAP_MOD_REPLACE; - mod[0].mod_type = strdup(type); - val[0] = id_str; val[1] = NULL; - mod[0].mod_values = val; + if ( id_type & ID_USERID ) + fstrcpy( type, get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER ) ); + else + fstrcpy( type, get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER ) ); - mod[1].mod_op = LDAP_MOD_REPLACE; - mod[1].mod_type = strdup("ntSid"); - val[2] = sid_str; val[3] = NULL; - mod[1].mod_values = val + 2; +#if 0 + snprintf(dn, sizeof(dn), "%s=%u,%s,%s", type, + ((id_type & ID_USERID) ? id.uid : id.gid), + ((id_type & ID_USERID) ? IDMAP_USER_SUFFIX : IDMAP_GROUP_SUFFIX ), + lp_ldap_idmap_suffix()); +#else + snprintf(dn, sizeof(dn), "%s=%u,%s", type, + ((id_type & ID_USERID) ? id.uid : id.gid), + lp_ldap_idmap_suffix()); +#endif - mods[0] = mod; mods[1] = mod + 1; mods[2] = NULL; + snprintf(id_str, sizeof(id_str), "%u", ((id_type & ID_USERID) ? id.uid : id.gid)); + sid_to_string( sid_str, sid ); + + ldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_IDMAP_ENTRY ); + ldap_set_mod( &mods, LDAP_MOD_ADD, type, id_str ); + ldap_set_mod( &mods, LDAP_MOD_ADD, + get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID), sid_str ); do { - if ((rc = ldap_idmap_retry_open(&ldap_state, &attempts)) != - LDAP_SUCCESS) continue; + if ((rc = ldap_idmap_retry_open(&ldap_state, &attempts)) != LDAP_SUCCESS) + continue; - rc = ldap_modify_s(ldap_state.ldap_struct, dn, mods); + rc = ldap_add_s(ldap_state.ldap_struct, dn, mods); } while ((rc == LDAP_SERVER_DOWN) && (attempts <= 8)); + ldap_mods_free( mods, True ); + if (rc != LDAP_SUCCESS) { + DEBUG(0,("ldap_set_mapping: Failed to create mapping from %s to %d [%s]\n", + sid_str, ((id_type & ID_USERID) ? id.uid : id.gid), type)); return NT_STATUS_UNSUCCESSFUL; } + + DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to %d [%s]\n", + sid_str, ((id_type & ID_USERID) ? id.uid : id.gid), type)); return NT_STATUS_OK; } @@ -791,21 +858,109 @@ static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type) /***************************************************************************** Initialise idmap database. *****************************************************************************/ -static NTSTATUS ldap_idmap_init(void) +static NTSTATUS ldap_idmap_init( char *params ) { - /* We wait for the first search request before we try to connect to - the LDAP server. We may want to connect upon initialization though - -- aliguori */ + fstring filter; +#if 0 + pstring dn; +#endif + int rc; + char **attr_list; + LDAPMessage *result = NULL; + LDAPMod **mods = NULL; + int count; + + /* parse out the server (assuming only parameter is a URI) */ + + if ( params ) + ldap_state.uri = smb_xstrdup( params ); + else + ldap_state.uri = smb_xstrdup( "ldap://localhost/" ); + + /* see if the idmap suffix and sub entries exists */ + + snprintf( filter, sizeof(filter), "(objectclass=%s)", LDAP_OBJ_IDPOOL ); + + attr_list = get_attr_list( idpool_attr_list ); + rc = ldap_idmap_search(&ldap_state, lp_ldap_idmap_suffix(), + LDAP_SCOPE_SUBTREE, filter, attr_list, 0, &result); + free_attr_list ( attr_list ); + + if (rc != LDAP_SUCCESS) + return NT_STATUS_UNSUCCESSFUL; + + count = ldap_count_entries(ldap_state.ldap_struct, result); + + if ( count > 1 ) { + DEBUG(0,("ldap_idmap_init: multiple entries returned from %s (base == %s)\n", + filter, lp_ldap_idmap_suffix() )); + return NT_STATUS_UNSUCCESSFUL; + } + else if (count == 0) { + uid_t luid, huid; + gid_t lgid, hgid; + fstring uid_str, gid_str; + int attempts = 0; + + if ( !lp_idmap_uid(&luid, &huid) || !lp_idmap_gid( &lgid, &hgid ) ) { + DEBUG(0,("ldap_idmap_init: idmap uid/gid parameters not specified\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + snprintf( uid_str, sizeof(uid_str), "%d", luid ); + snprintf( gid_str, sizeof(gid_str), "%d", lgid ); + + ldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_IDPOOL ); + ldap_set_mod( &mods, LDAP_MOD_ADD, + get_attr_key2string(idpool_attr_list, LDAP_ATTR_UIDNUMBER), uid_str ); + ldap_set_mod( &mods, LDAP_MOD_ADD, + get_attr_key2string(idpool_attr_list, LDAP_ATTR_GIDNUMBER), gid_str ); + + do { + if ((rc = ldap_idmap_retry_open(&ldap_state, &attempts)) != LDAP_SUCCESS) + continue; + + rc = ldap_modify_s(ldap_state.ldap_struct, lp_ldap_idmap_suffix(), mods); + } while ((rc == LDAP_SERVER_DOWN) && (attempts <= 8)); + } + + /* we have the initial entry now; let's create the sub entries */ + /* if they already exist then this will fail, but we don't care */ + +#if 0 /* commenting out for now, but I will come back to this --jerry */ + + mods = NULL; + snprintf( dn, sizeof(dn), "%s,%s", IDMAP_USER_SUFFIX, lp_ldap_idmap_suffix() ); + ldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_OU ); + ldap_set_mod( &mods, LDAP_MOD_ADD, "ou", "idmap people" ); + ldap_add_s(ldap_state.ldap_struct, dn, mods); + ldap_mods_free( mods, True ); + + mods = NULL; + snprintf( dn, sizeof(dn), "%s,%s", IDMAP_GROUP_SUFFIX, lp_ldap_idmap_suffix() ); + ldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_OU ); + ldap_set_mod( &mods, LDAP_MOD_ADD, "ou", "idmap group" ); + ldap_add_s(ldap_state.ldap_struct, dn, mods); + ldap_mods_free( mods, True ); +#endif + return NT_STATUS_OK; } -/* End the LDAP session */ +/***************************************************************************** + End the LDAP session +*****************************************************************************/ + static NTSTATUS ldap_idmap_close(void) { if (ldap_state.ldap_struct != NULL) { ldap_unbind_ext(ldap_state.ldap_struct, NULL, NULL); ldap_state.ldap_struct = NULL; } + + SAFE_FREE( ldap_state.uri ); + SAFE_FREE( ldap_state.bind_dn ); + SAFE_FREE( ldap_state.bind_secret ); DEBUG(5,("The connection to the LDAP server was closed\n")); /* maybe free the results here --metze */ @@ -833,6 +988,5 @@ static struct idmap_methods ldap_methods = { NTSTATUS idmap_ldap_init(void) { - DEBUG(0,("idmap_reg_ldap: no LDAP support\n")); return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "ldap", &ldap_methods); } diff --git a/source/sam/idmap_tdb.c b/source/sam/idmap_tdb.c index 31c12241bf7..278269e8198 100644 --- a/source/sam/idmap_tdb.c +++ b/source/sam/idmap_tdb.c @@ -263,7 +263,7 @@ static NTSTATUS db_set_mapping(const DOM_SID *sid, unid_t id, int id_type) /***************************************************************************** Initialise idmap database. *****************************************************************************/ -static NTSTATUS db_idmap_init(void) +static NTSTATUS db_idmap_init( char *params ) { SMB_STRUCT_STAT stbuf; char *tdbfile = NULL; @@ -424,7 +424,7 @@ static void db_idmap_status(void) /* Display complete mapping of users and groups to rids */ } -struct idmap_methods db_methods = { +static struct idmap_methods db_methods = { db_idmap_init, db_get_sid_from_id, @@ -435,9 +435,7 @@ struct idmap_methods db_methods = { }; -NTSTATUS idmap_reg_tdb(struct idmap_methods **meth) +NTSTATUS idmap_tdb_init(void) { - *meth = &db_methods; - - return NT_STATUS_OK; + return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "tdb", &db_methods); } diff --git a/source/script/.cvsignore b/source/script/.cvsignore index 5efd0d33db3..7a8114ecd73 100644 --- a/source/script/.cvsignore +++ b/source/script/.cvsignore @@ -1,2 +1 @@ findsmb -mkproto.sh diff --git a/source/script/build_env.sh b/source/script/build_env.sh index 0000759f160..eb54f37aeda 100755 --- a/source/script/build_env.sh +++ b/source/script/build_env.sh @@ -1,25 +1,31 @@ #!/bin/sh +if [ $# -lt 3 ] +then + echo "Usage: $0 srcdir builddir compiler" + exit 1 +fi + uname=`uname -a` date=`date` srcdir=$1 builddir=$2 compiler=$3 - if [ ! "x$USER" = "x" ]; then - whoami=$USER - else - if [ ! "x$LOGNAME" = "x" ]; then - whoami=$LOGNAME - else - whoami=`whoami || id -un` - fi - fi +if [ ! "x$USER" = "x" ]; then + whoami=$USER +else + if [ ! "x$LOGNAME" = "x" ]; then + whoami=$LOGNAME + else + whoami=`whoami || id -un` + fi +fi host=`hostname` cat <<EOF -/* This file is automatically generated with "make build_env". DO NOT EDIT */ +/* This file is automatically generated with "make include/build_env.h". DO NOT EDIT */ #ifndef _BUILD_ENV_H #define _BUILD_ENV_H diff --git a/source/script/installswat.sh b/source/script/installswat.sh index c66604cdb84..d1f8ea191d9 100755 --- a/source/script/installswat.sh +++ b/source/script/installswat.sh @@ -1,5 +1,5 @@ #!/bin/sh -#fist version March 1998, Andrew Tridgell +#first version March 1998, Andrew Tridgell SWATDIR=$1 SRCDIR=$2/ diff --git a/source/smbd/.cvsignore b/source/smbd/.cvsignore index 5f2a5c4cf75..d2b1fd5b2ee 100644 --- a/source/smbd/.cvsignore +++ b/source/smbd/.cvsignore @@ -1,2 +1,3 @@ *.po *.po32 +build_options.c diff --git a/source/smbd/close.c b/source/smbd/close.c index 5cca85500fd..1be13270bab 100644 --- a/source/smbd/close.c +++ b/source/smbd/close.c @@ -185,7 +185,7 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close) if (normal_close && delete_on_close) { DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n", fsp->fsp_name)); - if(fsp->conn->vfs_ops.unlink(conn,fsp->fsp_name) != 0) { + if(SMB_VFS_UNLINK(conn,fsp->fsp_name) != 0) { /* * This call can potentially fail as another smbd may have * had the file open with delete on close set and deleted diff --git a/source/smbd/conn.c b/source/smbd/conn.c index b6c7aa1076e..eb2d2bbcbf2 100644 --- a/source/smbd/conn.c +++ b/source/smbd/conn.c @@ -93,6 +93,7 @@ thinking the server is still available. ****************************************************************************/ connection_struct *conn_new(void) { + TALLOC_CTX *mem_ctx; connection_struct *conn; int i; @@ -103,10 +104,16 @@ connection_struct *conn_new(void) return NULL; } - conn = (connection_struct *)malloc(sizeof(*conn)); - if (!conn) return NULL; + if ((mem_ctx=talloc_init("connection_struct"))==NULL) { + DEBUG(0,("talloc_init(connection_struct) failed!\n")); + return NULL; + } - ZERO_STRUCTP(conn); + if ((conn=(connection_struct *)talloc_zero(mem_ctx, sizeof(*conn)))==NULL) { + DEBUG(0,("talloc_zero() failed!\n")); + return NULL; + } + conn->mem_ctx = mem_ctx; conn->cnum = i; bitmap_set(bmap, i); @@ -195,27 +202,16 @@ void conn_clear_vuid_cache(uint16 vuid) void conn_free(connection_struct *conn) { - smb_vfs_handle_struct *handle, *thandle; - void (*done_fptr)(connection_struct *the_conn); + vfs_handle_struct *handle = NULL, *thandle = NULL; + TALLOC_CTX *mem_ctx = NULL; /* Free vfs_connection_struct */ - handle = conn->vfs_private; + handle = conn->vfs_handles; while(handle) { - /* Only call dlclose for the old modules */ - if (handle->handle) { - /* Close dlopen() handle */ - done_fptr = (void (*)(connection_struct *))sys_dlsym(handle->handle, "vfs_done"); - - if (done_fptr == NULL) { - DEBUG(3, ("No vfs_done() symbol found in module with handle %p, ignoring\n", handle->handle)); - } else { - done_fptr(conn); - } - sys_dlclose(handle->handle); - } - DLIST_REMOVE(conn->vfs_private, handle); + DLIST_REMOVE(conn->vfs_handles, handle); thandle = handle->next; - SAFE_FREE(handle); + if (handle->free_data) + handle->free_data(&handle->data); handle = thandle; } @@ -238,8 +234,9 @@ void conn_free(connection_struct *conn) bitmap_clear(bmap, conn->cnum); num_open--; + mem_ctx = conn->mem_ctx; ZERO_STRUCTP(conn); - SAFE_FREE(conn); + talloc_destroy(mem_ctx); } diff --git a/source/smbd/connection.c b/source/smbd/connection.c index c2718d4d703..5bb76eb3bd8 100644 --- a/source/smbd/connection.c +++ b/source/smbd/connection.c @@ -38,10 +38,17 @@ TDB_CONTEXT *conn_tdb_ctx(void) static void make_conn_key(connection_struct *conn, const char *name, TDB_DATA *pkbuf, struct connections_key *pkey) { ZERO_STRUCTP(pkey); - ZERO_STRUCTP(pkbuf); pkey->pid = sys_getpid(); pkey->cnum = conn?conn->cnum:-1; fstrcpy(pkey->name, name); +#ifdef DEVELOPER + /* valgrind fixer... */ + { + size_t sl = strlen(pkey->name); + if (sizeof(fstring)-sl) + memset(&pkey->name[sl], '\0', sizeof(fstring)-sl); + } +#endif pkbuf->dptr = (char *)pkey; pkbuf->dsize = sizeof(*pkey); diff --git a/source/smbd/dfree.c b/source/smbd/dfree.c index 71b3f2bf772..f93cdf3791e 100644 --- a/source/smbd/dfree.c +++ b/source/smbd/dfree.c @@ -80,7 +80,7 @@ static SMB_BIG_UINT disk_free(const char *path, BOOL small_query, dfree_command = lp_dfree_command(); if (dfree_command && *dfree_command) { - char *p; + const char *p; char **lines; pstring syscmd; @@ -93,15 +93,15 @@ static SMB_BIG_UINT disk_free(const char *path, BOOL small_query, DEBUG (3, ("Read input from dfree, \"%s\"\n", line)); - *dsize = (SMB_BIG_UINT)strtoul(line, &p, 10); - while (p && *p & isspace(*p)) + *dsize = STR_TO_SMB_BIG_UINT(line, &p); + while (p && *p && isspace(*p)) p++; if (p && *p) - *dfree = (SMB_BIG_UINT)strtoul(p, &p, 10); - while (p && *p & isspace(*p)) + *dfree = STR_TO_SMB_BIG_UINT(p, &p); + while (p && *p && isspace(*p)) p++; if (p && *p) - *bsize = (SMB_BIG_UINT)strtoul(p, NULL, 10); + *bsize = STR_TO_SMB_BIG_UINT(p, NULL); else *bsize = 1024; file_lines_free(lines); diff --git a/source/smbd/dir.c b/source/smbd/dir.c index 6cf56fd373b..94b605ee8f9 100644 --- a/source/smbd/dir.c +++ b/source/smbd/dir.c @@ -643,7 +643,7 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname pstrcpy(pathreal,path); pstrcat(path,fname); pstrcat(pathreal,dname); - if (conn->vfs_ops.stat(conn, pathreal, &sbuf) != 0) { + if (SMB_VFS_STAT(conn, pathreal, &sbuf) != 0) { DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) )); continue; } @@ -700,7 +700,7 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S return True; /* If we can't stat it does not show it */ - if (!VALID_STAT(*pst) && (vfs_stat(conn, name, pst) != 0)) + if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) return False; /* Pseudo-open the file (note - no fd's created). */ @@ -715,7 +715,8 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S return False; /* Get NT ACL -allocated in main loop talloc context. No free needed here. */ - sd_size = conn->vfs_ops.fget_nt_acl(fsp, fsp->fd, &psd); + sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd, + (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd); close_file(fsp, True); /* No access if SD get failed. */ @@ -753,7 +754,7 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_ return True; /* If we can't stat it does not show it */ - if (!VALID_STAT(*pst) && (vfs_stat(conn, name, pst) != 0)) + if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) return False; /* Pseudo-open the file (note - no fd's created). */ @@ -768,7 +769,8 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_ return False; /* Get NT ACL -allocated in main loop talloc context. No free needed here. */ - sd_size = conn->vfs_ops.fget_nt_acl(fsp, fsp->fd, &psd); + sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd, + (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd); close_file(fsp, False); /* No access if SD get failed. */ @@ -794,7 +796,7 @@ static BOOL file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT return True; /* If we can't stat it does not show it */ - if (!VALID_STAT(*pst) && (vfs_stat(conn, name, pst) != 0)) + if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) return True; if (S_ISREG(pst->st_mode) || S_ISDIR(pst->st_mode) || S_ISLNK(pst->st_mode)) @@ -811,7 +813,7 @@ void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto) { Dir *dirp; const char *n; - DIR *p = conn->vfs_ops.opendir(conn,name); + DIR *p = SMB_VFS_OPENDIR(conn,name); int used=0; if (!p) @@ -819,7 +821,7 @@ void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto) dirp = (Dir *)malloc(sizeof(Dir)); if (!dirp) { DEBUG(0,("Out of memory in OpenDir\n")); - conn->vfs_ops.closedir(conn,p); + SMB_VFS_CLOSEDIR(conn,p); return(NULL); } dirp->pos = dirp->numentries = dirp->mallocsize = 0; @@ -912,7 +914,7 @@ void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto) dirp->numentries++; } - conn->vfs_ops.closedir(conn,p); + SMB_VFS_CLOSEDIR(conn,p); return((void *)dirp); } diff --git a/source/smbd/dosmode.c b/source/smbd/dosmode.c index 6c21dc04d0f..aaee41b546a 100644 --- a/source/smbd/dosmode.c +++ b/source/smbd/dosmode.c @@ -56,7 +56,7 @@ mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname) dname = parent_dirname(fname); DEBUG(2,("unix_mode(%s) inheriting from %s\n",fname,dname)); - if (vfs_stat(conn,dname,&sbuf) != 0) { + if (SMB_VFS_STAT(conn,dname,&sbuf) != 0) { DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n",fname,dname,strerror(errno))); return(0); /* *** shouldn't happen! *** */ } @@ -191,7 +191,7 @@ int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_ST if (!st) { st = &st1; - if (vfs_stat(conn,fname,st)) + if (SMB_VFS_STAT(conn,fname,st)) return(-1); } @@ -235,7 +235,7 @@ int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_ST unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)); } - if ((ret = vfs_chmod(conn,fname,unixmode)) == 0) + if ((ret = SMB_VFS_CHMOD(conn,fname,unixmode)) == 0) return 0; if((errno != EPERM) && (errno != EACCES)) @@ -262,7 +262,7 @@ int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_ST if (!fsp) return -1; become_root(); - ret = conn->vfs_ops.fchmod(fsp, fsp->fd, unixmode); + ret = SMB_VFS_FCHMOD(fsp, fsp->fd, unixmode); unbecome_root(); close_file_fchmod(fsp); } @@ -283,7 +283,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) errno = 0; - if(conn->vfs_ops.utime(conn,fname, times) == 0) + if(SMB_VFS_UTIME(conn,fname, times) == 0) return 0; if((errno != EPERM) && (errno != EACCES)) @@ -298,7 +298,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) (as DOS does). */ - if(vfs_stat(conn,fname,&sb) != 0) + if(SMB_VFS_STAT(conn,fname,&sb) != 0) return -1; /* Check if we have write access. */ @@ -311,7 +311,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) current_user.ngroups,current_user.groups)))) { /* We are allowed to become root and change the filetime. */ become_root(); - ret = conn->vfs_ops.utime(conn,fname, times); + ret = SMB_VFS_UTIME(conn,fname, times); unbecome_root(); } } diff --git a/source/smbd/fileio.c b/source/smbd/fileio.c index b612b1a4514..6be5f6af7d0 100644 --- a/source/smbd/fileio.c +++ b/source/smbd/fileio.c @@ -32,7 +32,7 @@ static SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos) { SMB_OFF_T seek_ret; - seek_ret = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,pos,SEEK_SET); + seek_ret = SMB_VFS_LSEEK(fsp,fsp->fd,pos,SEEK_SET); if(seek_ret == -1) { DEBUG(0,("seek_file: (%s) sys_lseek failed. Error was %s\n", @@ -101,7 +101,7 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) #ifdef DMF_FIX int numretries = 3; tryagain: - readret = fsp->conn->vfs_ops.read(fsp,fsp->fd,data,n); + readret = SMB_VFS_READ(fsp,fsp->fd,data,n); if (readret == -1) { if ((errno == EAGAIN) && numretries) { DEBUG(3,("read_file EAGAIN retry in 10 seconds\n")); @@ -112,7 +112,7 @@ tryagain: return -1; } #else /* NO DMF fix. */ - readret = fsp->conn->vfs_ops.read(fsp,fsp->fd,data,n); + readret = SMB_VFS_READ(fsp,fsp->fd,data,n); if (readret == -1) return -1; #endif @@ -181,7 +181,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) SMB_STRUCT_STAT st; fsp->modified = True; - if (fsp->conn->vfs_ops.fstat(fsp,fsp->fd,&st) == 0) { + if (SMB_VFS_FSTAT(fsp,fsp->fd,&st) == 0) { int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); fsp->size = (SMB_BIG_UINT)st.st_size; if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) @@ -760,7 +760,7 @@ void sync_file(connection_struct *conn, files_struct *fsp) { if(lp_strict_sync(SNUM(conn)) && fsp->fd != -1) { flush_write_cache(fsp, SYNC_FLUSH); - conn->vfs_ops.fsync(fsp,fsp->fd); + SMB_VFS_FSYNC(fsp,fsp->fd); } } @@ -772,7 +772,7 @@ void sync_file(connection_struct *conn, files_struct *fsp) int fsp_stat(files_struct *fsp, SMB_STRUCT_STAT *pst) { if (fsp->fd == -1) - return vfs_stat(fsp->conn, fsp->fsp_name, pst); + return SMB_VFS_STAT(fsp->conn, fsp->fsp_name, pst); else - return vfs_fstat(fsp,fsp->fd, pst); + return SMB_VFS_FSTAT(fsp,fsp->fd, pst); } diff --git a/source/smbd/filename.c b/source/smbd/filename.c index b9e33e8f934..ad107f9c3e1 100644 --- a/source/smbd/filename.c +++ b/source/smbd/filename.c @@ -178,7 +178,7 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen * stat the name - if it exists then we are all done! */ - if (vfs_stat(conn,name,&st) == 0) { + if (SMB_VFS_STAT(conn,name,&st) == 0) { stat_cache_add(orig_path, name); DEBUG(5,("conversion finished %s -> %s\n",orig_path, name)); *pst = st; @@ -234,7 +234,7 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen * Check if the name exists up to this point. */ - if (vfs_stat(conn,name, &st) == 0) { + if (SMB_VFS_STAT(conn,name, &st) == 0) { /* * It exists. it must either be a directory or this must be * the last part of the path for it to be OK. @@ -342,7 +342,7 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen * JRA. */ - if (vfs_stat(conn,name, &st) == 0) { + if (SMB_VFS_STAT(conn,name, &st) == 0) { *pst = st; } else { ZERO_STRUCT(st); @@ -418,7 +418,7 @@ BOOL check_name(pstring name,connection_struct *conn) #ifdef S_ISLNK if (!lp_symlinks(SNUM(conn))) { SMB_STRUCT_STAT statbuf; - if ( (conn->vfs_ops.lstat(conn,name,&statbuf) != -1) && + if ( (SMB_VFS_LSTAT(conn,name,&statbuf) != -1) && (S_ISLNK(statbuf.st_mode)) ) { DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name)); ret=0; diff --git a/source/smbd/files.c b/source/smbd/files.c index b9b27ad5ff9..f0fd6b7a736 100644 --- a/source/smbd/files.c +++ b/source/smbd/files.c @@ -346,6 +346,10 @@ void file_free(files_struct *fsp) string_free(&fsp->fsp_name); + if (fsp->fake_file_handle) { + destroy_fake_file_handle(&fsp->fake_file_handle); + } + bitmap_clear(file_bmap, fsp->fnum - FILE_HANDLE_OFFSET); files_used--; diff --git a/source/smbd/mangle_hash.c b/source/smbd/mangle_hash.c index e220d2f6d2b..d2eb996899c 100644 --- a/source/smbd/mangle_hash.c +++ b/source/smbd/mangle_hash.c @@ -556,8 +556,8 @@ static void cache_mangled_name( char *mangled_name, char *raw_name ) /* Fill the new cache entry, and add it to the cache. */ s1 = (char *)(new_entry + 1); s2 = (char *)&(s1[mangled_len + 1]); - (void)StrnCpy( s1, mangled_name, mangled_len ); - (void)StrnCpy( s2, raw_name, raw_len ); + safe_strcpy( s1, mangled_name, mangled_len ); + safe_strcpy( s2, raw_name, raw_len ); ubi_cachePut( mangled_cache, i, new_entry, s1 ); } diff --git a/source/smbd/negprot.c b/source/smbd/negprot.c index 66cd8352400..2a2ca25532b 100644 --- a/source/smbd/negprot.c +++ b/source/smbd/negprot.c @@ -100,8 +100,8 @@ static int reply_lanman1(char *inbuf, char *outbuf) SSVAL(outbuf,smb_vwv1,secword); /* Create a token value and add it to the outgoing packet. */ if (global_encrypted_passwords_negotiated) { - SSVAL(outbuf,smb_vwv11, 8); get_challenge(smb_buf(outbuf)); + SSVAL(outbuf,smb_vwv11, 8); } Protocol = PROTOCOL_LANMAN1; @@ -144,8 +144,8 @@ static int reply_lanman2(char *inbuf, char *outbuf) /* Create a token value and add it to the outgoing packet. */ if (global_encrypted_passwords_negotiated) { - SSVAL(outbuf,smb_vwv11, 8); get_challenge(smb_buf(outbuf)); + SSVAL(outbuf,smb_vwv11, 8); } Protocol = PROTOCOL_LANMAN2; @@ -182,6 +182,16 @@ static int negprot_spnego(char *p) ZERO_STRUCT(guid); safe_strcpy((char *)guid, global_myname(), sizeof(guid)-1); + +#ifdef DEVELOPER + /* valgrind fixer... */ + { + size_t sl = strlen(guid); + if (sizeof(guid)-sl) + memset(&guid[sl], '\0', sizeof(guid)-sl); + } +#endif + strlower((char *)guid); #if 0 diff --git a/source/smbd/notify_hash.c b/source/smbd/notify_hash.c index d8b35462acb..810e5079ba5 100644 --- a/source/smbd/notify_hash.c +++ b/source/smbd/notify_hash.c @@ -48,7 +48,7 @@ static BOOL notify_hash(connection_struct *conn, char *path, uint32 flags, ZERO_STRUCTP(data); - if(vfs_stat(conn,path, &st) == -1) + if(SMB_VFS_STAT(conn,path, &st) == -1) return False; data->modify_time = st.st_mtime; @@ -100,7 +100,7 @@ static BOOL notify_hash(connection_struct *conn, char *path, uint32 flags, /* * Do the stat - but ignore errors. */ - vfs_stat(conn,full_name, &st); + SMB_VFS_STAT(conn,full_name, &st); /* * Always sum the times. diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c index 9f7fabb75e4..fa7b78ecc26 100644 --- a/source/smbd/nttrans.c +++ b/source/smbd/nttrans.c @@ -1,7 +1,8 @@ /* Unix SMB/CIFS implementation. SMB NT transaction handling - Copyright (C) Jeremy Allison 1994-1998 + Copyright (C) Jeremy Allison 1994-1998 + Copyright (C) Stefan (metze) Metzmacher 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,6 +27,7 @@ extern int global_oplock_break; extern BOOL case_sensitive; extern BOOL case_preserve; extern BOOL short_case_preserve; +extern struct current_user current_user; static const char *known_nt_pipes[] = { "\\LANMAN", @@ -53,6 +55,24 @@ struct generic_mapping file_generic_mapping = { FILE_GENERIC_ALL }; +char *nttrans_realloc(char **ptr, size_t size) +{ + char *tptr = NULL; + if (ptr==NULL) + smb_panic("nttrans_realloc() called with NULL ptr\n"); + + tptr = Realloc_zero(*ptr, size); + if(tptr == NULL) { + *ptr = NULL; + return NULL; + } + + *ptr = tptr; + + return tptr; +} + + /**************************************************************************** Send the required number of replies back. We assume all fields other than the data fields are @@ -542,6 +562,7 @@ int reply_ntcreate_and_X(connection_struct *conn, { int result; pstring fname; + enum FAKE_FILE_TYPE fake_file_type = 0; uint32 flags = IVAL(inbuf,smb_ntcreate_Flags); uint32 desired_access = IVAL(inbuf,smb_ntcreate_DesiredAccess); uint32 file_attributes = IVAL(inbuf,smb_ntcreate_FileAttributes); @@ -669,8 +690,25 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib */ if( strchr_m(fname, ':')) { - END_PROFILE(SMBntcreateX); - return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); + +#ifdef HAVE_SYS_QUOTAS + if ((fake_file_type=is_fake_file(fname))!=0) { + /* + * here we go! support for changing the disk quotas --metze + * + * we need to fake up to open this MAGIC QUOTA file + * and return a valid FID + * + * w2k close this file directly after openening + * xp also tries a QUERY_FILE_INFO on the file and then close it + */ + } else { +#endif + END_PROFILE(SMBntcreateX); + return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); +#ifdef HAVE_SYS_QUOTAS + } +#endif } } @@ -746,12 +784,21 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib * before issuing an oplock break request to * our client. JRA. */ - fsp = open_file_shared1(conn,fname,&sbuf, + if (fake_file_type==0) { + fsp = open_file_shared1(conn,fname,&sbuf, desired_access, smb_open_mode, smb_ofun,unixmode, oplock_request, &rmode,&smb_action); - + } else { + /* to open a fake_file --metze */ + fsp = open_fake_file_shared1(fake_file_type,conn,fname,&sbuf, + desired_access, + smb_open_mode, + smb_ofun,unixmode, oplock_request, + &rmode,&smb_action); + } + if (!fsp) { /* We cheat here. There are two cases we * care about. One is a directory rename, @@ -917,13 +964,12 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib Reply to a NT_TRANSACT_CREATE call to open a pipe. ****************************************************************************/ -static int do_nt_transact_create_pipe( connection_struct *conn, - char *inbuf, char *outbuf, int length, - int bufsize, char **ppsetup, char **ppparams, - char **ppdata) +static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, + char **ppsetup, uint32 setup_count, + char **ppparams, uint32 parameter_count, + char **ppdata, uint32 data_count) { pstring fname; - int total_parameter_count = (int)IVAL(inbuf, smb_nt_TotalParameterCount); char *params = *ppparams; int ret; int pnum = -1; @@ -933,25 +979,21 @@ static int do_nt_transact_create_pipe( connection_struct *conn, * Ensure minimum number of parameters sent. */ - if(total_parameter_count < 54) { - DEBUG(0,("do_nt_transact_create_pipe - insufficient parameters (%u)\n", (unsigned int)total_parameter_count)); + if(parameter_count < 54) { + DEBUG(0,("do_nt_transact_create_pipe - insufficient parameters (%u)\n", (unsigned int)parameter_count)); return ERROR_DOS(ERRDOS,ERRnoaccess); } - srvstr_pull(inbuf, fname, params+53, sizeof(fname), total_parameter_count-53, STR_TERMINATE); + srvstr_pull(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE); if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0) return ret; /* Realloc the size of parameters and data we will return */ - params = Realloc(*ppparams, 69); + params = nttrans_realloc(ppparams, 69); if(params == NULL) return ERROR_DOS(ERRDOS,ERRnomem); - *ppparams = params; - - memset((char *)params,'\0',69); - p = params; SCVAL(p,0,NO_OPLOCK_RETURN); @@ -1032,7 +1074,7 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu if (psd->off_dacl==0) security_info_sent &= ~DACL_SECURITY_INFORMATION; - ret = fsp->conn->vfs_ops.fset_nt_acl( fsp, fsp->fd, security_info_sent, psd); + ret = SMB_VFS_FSET_NT_ACL( fsp, fsp->fd, security_info_sent, psd); if (!ret) { talloc_destroy(mem_ctx); @@ -1048,15 +1090,14 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu Reply to a NT_TRANSACT_CREATE call (needs to process SD's). ****************************************************************************/ -static int call_nt_transact_create(connection_struct *conn, - char *inbuf, char *outbuf, int length, - int bufsize, char **ppsetup, char **ppparams, - char **ppdata) +static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, + char **ppsetup, uint32 setup_count, + char **ppparams, uint32 parameter_count, + char **ppdata, uint32 data_count) { pstring fname; char *params = *ppparams; char *data = *ppdata; - int total_parameter_count = (int)IVAL(inbuf, smb_nt_TotalParameterCount); /* Breakout the oplock request bits so we can set the reply bits separately. */ int oplock_request = 0; mode_t unixmode; @@ -1092,7 +1133,10 @@ static int call_nt_transact_create(connection_struct *conn, if (IS_IPC(conn)) { if (lp_nt_pipe_support()) return do_nt_transact_create_pipe(conn, inbuf, outbuf, length, - bufsize, ppsetup, ppparams, ppdata); + bufsize, + ppsetup, setup_count, + ppparams, parameter_count, + ppdata, data_count); else return ERROR_DOS(ERRDOS,ERRnoaccess); } @@ -1101,8 +1145,8 @@ static int call_nt_transact_create(connection_struct *conn, * Ensure minimum number of parameters sent. */ - if(total_parameter_count < 54) { - DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)total_parameter_count)); + if(parameter_count < 54) { + DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)parameter_count)); return ERROR_DOS(ERRDOS,ERRnoaccess); } @@ -1146,7 +1190,7 @@ static int call_nt_transact_create(connection_struct *conn, if(!dir_fsp->is_directory) { - srvstr_pull(inbuf, fname, params+53, sizeof(fname), total_parameter_count-53, STR_TERMINATE); + srvstr_pull(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE); /* * Check to see if this is a mac fork of some kind. @@ -1175,9 +1219,9 @@ static int call_nt_transact_create(connection_struct *conn, } srvstr_pull(inbuf, &fname[dir_name_len], params+53, sizeof(fname)-dir_name_len, - total_parameter_count-53, STR_TERMINATE); + parameter_count-53, STR_TERMINATE); } else { - srvstr_pull(inbuf, fname, params+53, sizeof(fname), total_parameter_count-53, STR_TERMINATE); + srvstr_pull(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE); /* * Check to see if this is a mac fork of some kind. @@ -1331,14 +1375,10 @@ static int call_nt_transact_create(connection_struct *conn, } /* Realloc the size of parameters and data we will return */ - params = Realloc(*ppparams, 69); + params = nttrans_realloc(ppparams, 69); if(params == NULL) return ERROR_DOS(ERRDOS,ERRnomem); - *ppparams = params; - - memset((char *)params,'\0',69); - p = params; if (extended_oplock_granted) SCVAL(p,0, BATCH_OPLOCK_RETURN); @@ -1428,11 +1468,10 @@ int reply_nttranss(connection_struct *conn, don't allow a directory to be opened. ****************************************************************************/ -static int call_nt_transact_notify_change(connection_struct *conn, - char *inbuf, char *outbuf, int length, - int bufsize, - char **ppsetup, - char **ppparams, char **ppdata) +static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, + char **ppsetup, uint32 setup_count, + char **ppparams, uint32 parameter_count, + char **ppdata, uint32 data_count) { char *setup = *ppsetup; files_struct *fsp; @@ -1462,17 +1501,22 @@ name = %s\n", fsp->fsp_name )); Reply to an NT transact rename command. ****************************************************************************/ -static int call_nt_transact_rename(connection_struct *conn, - char *inbuf, char *outbuf, int length, - int bufsize, - char **ppsetup, char **ppparams, char **ppdata) +static int call_nt_transact_rename(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, + char **ppsetup, uint32 setup_count, + char **ppparams, uint32 parameter_count, + char **ppdata, uint32 data_count) { char *params = *ppparams; pstring new_name; - files_struct *fsp = file_fsp(params, 0); - BOOL replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False; + files_struct *fsp = NULL; + BOOL replace_if_exists = False; NTSTATUS status; + if(parameter_count < 4) + return ERROR_DOS(ERRDOS,ERRbadfunc); + + fsp = file_fsp(params, 0); + replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False; CHECK_FSP(fsp, conn); srvstr_pull(inbuf, new_name, params+4, sizeof(new_name), -1, STR_TERMINATE); @@ -1518,15 +1562,13 @@ static size_t get_null_nt_acl(TALLOC_CTX *mem_ctx, SEC_DESC **ppsd) } /**************************************************************************** - Reply to query a security descriptor - currently this is not implemented (it - is planned to be though). Right now it just returns the same thing NT would - when queried on a FAT filesystem. JRA. + Reply to query a security descriptor. ****************************************************************************/ -static int call_nt_transact_query_security_desc(connection_struct *conn, - char *inbuf, char *outbuf, - int length, int bufsize, - char **ppsetup, char **ppparams, char **ppdata) +static int call_nt_transact_query_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, + char **ppsetup, uint32 setup_count, + char **ppparams, uint32 parameter_count, + char **ppdata, uint32 data_count) { uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount); char *params = *ppparams; @@ -1534,21 +1576,25 @@ static int call_nt_transact_query_security_desc(connection_struct *conn, prs_struct pd; SEC_DESC *psd = NULL; size_t sd_size; + uint32 security_info_wanted; TALLOC_CTX *mem_ctx; + files_struct *fsp = NULL; - files_struct *fsp = file_fsp(params,0); + if(parameter_count < 8) + return ERROR_DOS(ERRDOS,ERRbadfunc); + fsp = file_fsp(params,0); if(!fsp) return ERROR_DOS(ERRDOS,ERRbadfid); + security_info_wanted = IVAL(params,4); + DEBUG(3,("call_nt_transact_query_security_desc: file = %s\n", fsp->fsp_name )); - params = Realloc(*ppparams, 4); + params = nttrans_realloc(ppparams, 4); if(params == NULL) return ERROR_DOS(ERRDOS,ERRnomem); - *ppparams = params; - if ((mem_ctx = talloc_init("call_nt_transact_query_security_desc")) == NULL) { DEBUG(0,("call_nt_transact_query_security_desc: talloc_init failed.\n")); return ERROR_DOS(ERRDOS,ERRnomem); @@ -1561,7 +1607,7 @@ static int call_nt_transact_query_security_desc(connection_struct *conn, if (!lp_nt_acl_support(SNUM(conn))) sd_size = get_null_nt_acl(mem_ctx, &psd); else - sd_size = conn->vfs_ops.fget_nt_acl(fsp, fsp->fd, &psd); + sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd, security_info_wanted, &psd); if (sd_size == 0) { talloc_destroy(mem_ctx); @@ -1584,16 +1630,12 @@ static int call_nt_transact_query_security_desc(connection_struct *conn, * Allocate the data we will point this at. */ - data = Realloc(*ppdata, sd_size); + data = nttrans_realloc(ppdata, sd_size); if(data == NULL) { talloc_destroy(mem_ctx); return ERROR_DOS(ERRDOS,ERRnomem); } - *ppdata = data; - - memset(data, '\0', sd_size); - /* * Init the parse struct we will marshall into. */ @@ -1632,23 +1674,21 @@ security descriptor.\n")); } /**************************************************************************** - Reply to set a security descriptor. Map to UNIX perms. + Reply to set a security descriptor. Map to UNIX perms or POSIX ACLs. ****************************************************************************/ -static int call_nt_transact_set_security_desc(connection_struct *conn, - char *inbuf, char *outbuf, int length, - int bufsize, char **ppsetup, - char **ppparams, char **ppdata) +static int call_nt_transact_set_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, + char **ppsetup, uint32 setup_count, + char **ppparams, uint32 parameter_count, + char **ppdata, uint32 data_count) { - uint32 total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount); char *params= *ppparams; char *data = *ppdata; - uint32 total_data_count = (uint32)IVAL(inbuf, smb_nts_TotalDataCount); files_struct *fsp = NULL; uint32 security_info_sent = 0; NTSTATUS nt_status; - if(total_parameter_count < 8) + if(parameter_count < 8) return ERROR_DOS(ERRDOS,ERRbadfunc); if((fsp = file_fsp(params,0)) == NULL) @@ -1662,10 +1702,10 @@ static int call_nt_transact_set_security_desc(connection_struct *conn, DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", fsp->fsp_name, (unsigned int)security_info_sent )); - if (total_data_count == 0) + if (data_count == 0) return ERROR_DOS(ERRDOS, ERRnoaccess); - if (!NT_STATUS_IS_OK(nt_status = set_sd( fsp, data, total_data_count, security_info_sent))) + if (!NT_STATUS_IS_OK(nt_status = set_sd( fsp, data, data_count, security_info_sent))) return ERROR_NT(nt_status); done: @@ -1677,15 +1717,15 @@ static int call_nt_transact_set_security_desc(connection_struct *conn, /**************************************************************************** Reply to NT IOCTL ****************************************************************************/ -static int call_nt_transact_ioctl(connection_struct *conn, - char *inbuf, char *outbuf, int length, - int bufsize, - char **ppsetup, int setup_count, - char **ppparams, int parameter_count, - char **ppdata, int data_count) + +static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, + char **ppsetup, uint32 setup_count, + char **ppparams, uint32 parameter_count, + char **ppdata, uint32 data_count) { unsigned fnum, control; static BOOL logged_message; + char *pdata = *ppdata; if (setup_count != 8) { DEBUG(3,("call_nt_transact_ioctl: invalid setup count %d\n", setup_count)); @@ -1695,28 +1735,475 @@ static int call_nt_transact_ioctl(connection_struct *conn, fnum = SVAL(*ppsetup, 4); control = IVAL(*ppsetup, 0); - DEBUG(6,("call_nt_transact_ioctl: fnum=%d control=0x%x\n", + DEBUG(10,("call_nt_transact_ioctl: fnum=%d control=0x%08x\n", fnum, control)); switch (control) { - case NTIOCTL_SET_SPARSE: + case FSCTL_SET_SPARSE: /* pretend this succeeded - tho strictly we should mark the file sparse (if the local fs supports it) so we can know if we need to pre-allocate or not */ + + DEBUG(10,("FSCTL_SET_SPARSE: fnum=%d control=0x%08x\n",fnum,control)); send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0); return -1; + + case FSCTL_0x000900C0: + /* pretend this succeeded - don't know what this really is + but works ok like this --metze + */ + + DEBUG(1,("FSCTL_GET_REPARSE_POINT: fnum=%d control=0x%08x\n",fnum,control)); + send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0); + return -1; + + case FSCTL_GET_REPARSE_POINT: + /* pretend this fail - my winXP does it like this + * --metze + */ + DEBUG(1,("FSCTL_GET_REPARSE_POINT: fnum=%d control=0x%08x\n",fnum,control)); + send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT, NULL, 0, NULL, 0); + return -1; + + case FSCTL_SET_REPARSE_POINT: + /* pretend this fail - I'm assuming this because of the FSCTL_GET_REPARSE_POINT case. + * --metze + */ + + DEBUG(1,("FSCTL_SET_REPARSE_POINT: fnum=%d control=0x%08x\n",fnum,control)); + send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT, NULL, 0, NULL, 0); + return -1; + + case FSCTL_FIND_FILES_BY_SID: /* I hope this name is right */ + { + /* pretend this succeeded - + * + * we have to send back a list with all files owned by this SID + * + * but I have to check that --metze + */ + + DOM_SID sid; + uid_t uid; + size_t sid_len=SID_MAX_SIZE; + + DEBUG(1,("FSCTL_FIND_FILES_BY_SID: fnum=%d control=0x%08x\n",fnum,control)); + + /* this is not the length of the sid :-( so unknown 4 bytes */ + /*sid_len = IVAL(pdata,0); + DEBUGADD(0,("sid_len: (%u)\n",sid_len));*/ + + sid_parse(pdata+4,sid_len,&sid); + DEBUGADD(2,("SID: %s\n",sid_string_static(&sid))); + + if (NT_STATUS_IS_ERR(sid_to_uid(&sid, &uid))) { + DEBUG(0,("sid_to_uid: failed, sid[%s]\n", + sid_string_static(&sid))); + uid = (-1); + } + + /* we can take a look at the find source :-) + * + * find ./ -uid $uid -name '*' is what we need here + * + * + * and send 4bytes len and then NULL terminated unicode strings + * for each file + * + * but I don't know how to deal with the paged results + * + * we don't send all files at once + * and at the next we should *not* start from the beginning, + * so we have to cache the result + * + * --metze + */ + + /* this works for now... */ + send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0); + return -1; + } default: if (!logged_message) { logged_message = True; /* Only print this once... */ - DEBUG(3,("call_nt_transact_ioctl(0x%x): Currently not implemented.\n", + DEBUG(0,("call_nt_transact_ioctl(0x%x): Currently not implemented.\n", control)); } } return ERROR_NT(NT_STATUS_NOT_SUPPORTED); } - + + +#ifdef HAVE_SYS_QUOTAS +/**************************************************************************** + Reply to get user quota +****************************************************************************/ + +static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, + char **ppsetup, uint32 setup_count, + char **ppparams, uint32 parameter_count, + char **ppdata, uint32 data_count) +{ + NTSTATUS nt_status = NT_STATUS_OK; + uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount); + char *params = *ppparams; + char *pdata = *ppdata; + char *entry; + int data_len=0,param_len=0; + int qt_len=0; + int entry_len = 0; + files_struct *fsp = NULL; + uint16 level = 0; + size_t sid_len; + DOM_SID sid; + BOOL start_enum = True; + SMB_NTQUOTA_STRUCT qt; + SMB_NTQUOTA_LIST *tmp_list; + SMB_NTQUOTA_HANDLE *qt_handle = NULL; + + ZERO_STRUCT(qt); + + /* access check */ + if (conn->admin_user != True) { + DEBUG(1,("set_user_quota: access_denied service [%s] user [%s]\n", + lp_servicename(SNUM(conn)),conn->user)); + return ERROR_DOS(ERRDOS,ERRnoaccess); + } + + /* + * Ensure minimum number of parameters sent. + */ + + if (parameter_count < 4) { + DEBUG(0,("TRANSACT_GET_USER_QUOTA: requires %d >= 4 bytes parameters\n",parameter_count)); + return ERROR_DOS(ERRDOS,ERRinvalidparam); + } + + /* maybe we can check the quota_fnum */ + fsp = file_fsp(params,0); + if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) { + DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n")); + return ERROR_NT(NT_STATUS_INVALID_HANDLE); + } + + /* the NULL pointer cheking for fsp->fake_file_handle->pd + * is done by CHECK_NTQUOTA_HANDLE_OK() + */ + qt_handle = (SMB_NTQUOTA_HANDLE *)fsp->fake_file_handle->pd; + + level = SVAL(params,2); + + /* unknown 12 bytes leading in params */ + + switch (level) { + case TRANSACT_GET_USER_QUOTA_LIST_CONTINUE: + /* seems that we should continue with the enum here --metze */ + + if (qt_handle->quota_list!=NULL && + qt_handle->tmp_list==NULL) { + + /* free the list */ + free_ntquota_list(&(qt_handle->quota_list)); + + /* Realloc the size of parameters and data we will return */ + param_len = 4; + params = nttrans_realloc(ppparams, param_len); + if(params == NULL) + return ERROR_DOS(ERRDOS,ERRnomem); + + data_len = 0; + SIVAL(params,0,data_len); + + break; + } + + start_enum = False; + + case TRANSACT_GET_USER_QUOTA_LIST_START: + + if (qt_handle->quota_list==NULL && + qt_handle->tmp_list==NULL) { + start_enum = True; + } + + if (start_enum && vfs_get_user_ntquota_list(fsp,&(qt_handle->quota_list))!=0) + return ERROR_DOS(ERRSRV,ERRerror); + + /* Realloc the size of parameters and data we will return */ + param_len = 4; + params = nttrans_realloc(ppparams, param_len); + if(params == NULL) + return ERROR_DOS(ERRDOS,ERRnomem); + + /* we should not trust the value in max_data_count*/ + max_data_count = MIN(max_data_count,2048); + + pdata = nttrans_realloc(ppdata, max_data_count);/* should be max data count from client*/ + if(pdata == NULL) + return ERROR_DOS(ERRDOS,ERRnomem); + + entry = pdata; + + + /* set params Size of returned Quota Data 4 bytes*/ + /* but set it later when we know it */ + + /* for each entry push the data */ + + if (start_enum) { + qt_handle->tmp_list = qt_handle->quota_list; + } + + tmp_list = qt_handle->tmp_list; + + for (;((tmp_list!=NULL)&&((qt_len +40+SID_MAX_SIZE)<max_data_count)); + tmp_list=tmp_list->next,entry+=entry_len,qt_len+=entry_len) { + + sid_len = sid_size(&tmp_list->quotas->sid); + entry_len = 40 + sid_len; + + /* nextoffset entry 4 bytes */ + SIVAL(entry,0,entry_len); + + /* then the len of the SID 4 bytes */ + SIVAL(entry,4,sid_len); + + /* unknown data 8 bytes SMB_BIG_UINT */ + SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-metze*/ + + /* the used disk space 8 bytes SMB_BIG_UINT */ + SBIG_UINT(entry,16,tmp_list->quotas->usedspace); + + /* the soft quotas 8 bytes SMB_BIG_UINT */ + SBIG_UINT(entry,24,tmp_list->quotas->softlim); + + /* the hard quotas 8 bytes SMB_BIG_UINT */ + SBIG_UINT(entry,32,tmp_list->quotas->hardlim); + + /* and now the SID */ + sid_linearize(entry+40, sid_len, &tmp_list->quotas->sid); + } + + qt_handle->tmp_list = tmp_list; + + /* overwrite the offset of the last entry */ + SIVAL(entry-entry_len,0,0); + + data_len = 4+qt_len; + /* overwrite the params quota_data_len */ + SIVAL(params,0,data_len); + + break; + + case TRANSACT_GET_USER_QUOTA_FOR_SID: + + /* unknown 4 bytes IVAL(pdata,0) */ + + if (data_count < 8) { + DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %d bytes data\n",data_count,8)); + return ERROR_DOS(ERRDOS,ERRunknownlevel); + } + + sid_len = IVAL(pdata,4); + + if (data_count < 8+sid_len) { + DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %d bytes data\n",data_count,8+sid_len)); + return ERROR_DOS(ERRDOS,ERRunknownlevel); + } + + data_len = 4+40+sid_len; + + if (max_data_count < data_len) { + DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: max_data_count(%d) < data_len(%d)\n", + max_data_count, data_len)); + param_len = 4; + SIVAL(params,0,data_len); + data_len = 0; + nt_status = NT_STATUS_BUFFER_TOO_SMALL; + break; + } + + sid_parse(pdata+8,sid_len,&sid); + + + if (vfs_get_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) { + ZERO_STRUCT(qt); + /* + * we have to return zero's in all fields + * instead of returning an error here + * --metze + */ + } + + /* Realloc the size of parameters and data we will return */ + param_len = 4; + params = nttrans_realloc(ppparams, param_len); + if(params == NULL) + return ERROR_DOS(ERRDOS,ERRnomem); + + pdata = nttrans_realloc(ppdata, data_len); + if(pdata == NULL) + return ERROR_DOS(ERRDOS,ERRnomem); + + entry = pdata; + + /* set params Size of returned Quota Data 4 bytes*/ + SIVAL(params,0,data_len); + + /* nextoffset entry 4 bytes */ + SIVAL(entry,0,0); + + /* then the len of the SID 4 bytes */ + SIVAL(entry,4,sid_len); + + /* unknown data 8 bytes SMB_BIG_UINT */ + SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-mezte*/ + + /* the used disk space 8 bytes SMB_BIG_UINT */ + SBIG_UINT(entry,16,qt.usedspace); + + /* the soft quotas 8 bytes SMB_BIG_UINT */ + SBIG_UINT(entry,24,qt.softlim); + + /* the hard quotas 8 bytes SMB_BIG_UINT */ + SBIG_UINT(entry,32,qt.hardlim); + + /* and now the SID */ + sid_linearize(entry+40, sid_len, &sid); + + break; + + default: + DEBUG(0,("do_nt_transact_get_user_quota: fnum %d unknown level 0x%04hX\n",fsp->fnum,level)); + return ERROR_DOS(ERRSRV,ERRerror); + break; + } + + send_nt_replies(inbuf, outbuf, bufsize, nt_status, params, param_len, pdata, data_len); + + return -1; +} + +/**************************************************************************** + Reply to set user quota +****************************************************************************/ + +static int call_nt_transact_set_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, + char **ppsetup, uint32 setup_count, + char **ppparams, uint32 parameter_count, + char **ppdata, uint32 data_count) +{ + char *params = *ppparams; + char *pdata = *ppdata; + int data_len=0,param_len=0; + SMB_NTQUOTA_STRUCT qt; + size_t sid_len; + DOM_SID sid; + files_struct *fsp = NULL; + + ZERO_STRUCT(qt); + + /* access check */ + if (conn->admin_user != True) { + DEBUG(1,("set_user_quota: access_denied service [%s] user [%s]\n", + lp_servicename(SNUM(conn)),conn->user)); + return ERROR_DOS(ERRDOS,ERRnoaccess); + } + + /* + * Ensure minimum number of parameters sent. + */ + + if (parameter_count < 2) { + DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= 2 bytes parameters\n",parameter_count)); + return ERROR_DOS(ERRDOS,ERRinvalidparam); + } + + /* maybe we can check the quota_fnum */ + fsp = file_fsp(params,0); + if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) { + DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n")); + return ERROR_NT(NT_STATUS_INVALID_HANDLE); + } + + if (data_count < 40) { + DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %d bytes data\n",data_count,40)); + return ERROR_DOS(ERRDOS,ERRunknownlevel); + } + + /* offset to next quota record. + * 4 bytes IVAL(pdata,0) + * unused here... + */ + + /* sid len */ + sid_len = IVAL(pdata,4); + + if (data_count < 40+sid_len) { + DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %d bytes data\n",data_count,40+sid_len)); + return ERROR_DOS(ERRDOS,ERRunknownlevel); + } + + /* unknown 8 bytes in pdata + * maybe its the change time in NTTIME + */ + + /* the used space 8 bytes (SMB_BIG_UINT)*/ + qt.usedspace = (SMB_BIG_UINT)IVAL(pdata,16); +#ifdef LARGE_SMB_OFF_T + qt.usedspace |= (((SMB_BIG_UINT)IVAL(pdata,20)) << 32); +#else /* LARGE_SMB_OFF_T */ + if ((IVAL(pdata,20) != 0)&& + ((qt.usedspace != 0xFFFFFFFF)|| + (IVAL(pdata,20)!=0xFFFFFFFF))) { + /* more than 32 bits? */ + return ERROR_DOS(ERRDOS,ERRunknownlevel); + } +#endif /* LARGE_SMB_OFF_T */ + + /* the soft quotas 8 bytes (SMB_BIG_UINT)*/ + qt.softlim = (SMB_BIG_UINT)IVAL(pdata,24); +#ifdef LARGE_SMB_OFF_T + qt.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32); +#else /* LARGE_SMB_OFF_T */ + if ((IVAL(pdata,28) != 0)&& + ((qt.softlim != 0xFFFFFFFF)|| + (IVAL(pdata,28)!=0xFFFFFFFF))) { + /* more than 32 bits? */ + return ERROR_DOS(ERRDOS,ERRunknownlevel); + } +#endif /* LARGE_SMB_OFF_T */ + + /* the hard quotas 8 bytes (SMB_BIG_UINT)*/ + qt.hardlim = (SMB_BIG_UINT)IVAL(pdata,32); +#ifdef LARGE_SMB_OFF_T + qt.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32); +#else /* LARGE_SMB_OFF_T */ + if ((IVAL(pdata,36) != 0)&& + ((qt.hardlim != 0xFFFFFFFF)|| + (IVAL(pdata,36)!=0xFFFFFFFF))) { + /* more than 32 bits? */ + return ERROR_DOS(ERRDOS,ERRunknownlevel); + } +#endif /* LARGE_SMB_OFF_T */ + + sid_parse(pdata+40,sid_len,&sid); + DEBUGADD(8,("SID: %s\n",sid_string_static(&sid))); + + /* 44 unknown bytes left... */ + + if (vfs_set_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) { + return ERROR_DOS(ERRSRV,ERRerror); + } + + send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, param_len, pdata, data_len); + + return -1; +} +#endif /* HAVE_SYS_QUOTAS */ + /**************************************************************************** Reply to a SMBNTtrans. ****************************************************************************/ @@ -1918,8 +2405,10 @@ due to being in oplock break state.\n", (unsigned int)function_code )); case NT_TRANSACT_CREATE: START_PROFILE_NESTED(NT_transact_create); outsize = call_nt_transact_create(conn, inbuf, outbuf, - length, bufsize, - &setup, ¶ms, &data); + length, bufsize, + &setup, setup_count, + ¶ms, total_parameter_count, + &data, total_data_count); END_PROFILE_NESTED(NT_transact_create); break; case NT_TRANSACT_IOCTL: @@ -1927,39 +2416,67 @@ due to being in oplock break state.\n", (unsigned int)function_code )); outsize = call_nt_transact_ioctl(conn, inbuf, outbuf, length, bufsize, &setup, setup_count, - ¶ms, parameter_count, - &data, data_count); + ¶ms, total_parameter_count, + &data, total_data_count); END_PROFILE_NESTED(NT_transact_ioctl); break; case NT_TRANSACT_SET_SECURITY_DESC: START_PROFILE_NESTED(NT_transact_set_security_desc); outsize = call_nt_transact_set_security_desc(conn, inbuf, outbuf, - length, bufsize, - &setup, ¶ms, &data); + length, bufsize, + &setup, setup_count, + ¶ms, total_parameter_count, + &data, total_data_count); END_PROFILE_NESTED(NT_transact_set_security_desc); break; case NT_TRANSACT_NOTIFY_CHANGE: START_PROFILE_NESTED(NT_transact_notify_change); outsize = call_nt_transact_notify_change(conn, inbuf, outbuf, - length, bufsize, - &setup, ¶ms, &data); + length, bufsize, + &setup, setup_count, + ¶ms, total_parameter_count, + &data, total_data_count); END_PROFILE_NESTED(NT_transact_notify_change); break; case NT_TRANSACT_RENAME: START_PROFILE_NESTED(NT_transact_rename); outsize = call_nt_transact_rename(conn, inbuf, outbuf, - length, bufsize, - &setup, ¶ms, &data); + length, bufsize, + &setup, setup_count, + ¶ms, total_parameter_count, + &data, total_data_count); END_PROFILE_NESTED(NT_transact_rename); break; case NT_TRANSACT_QUERY_SECURITY_DESC: START_PROFILE_NESTED(NT_transact_query_security_desc); outsize = call_nt_transact_query_security_desc(conn, inbuf, outbuf, - length, bufsize, - &setup, ¶ms, &data); + length, bufsize, + &setup, setup_count, + ¶ms, total_parameter_count, + &data, total_data_count); END_PROFILE_NESTED(NT_transact_query_security_desc); break; +#ifdef HAVE_SYS_QUOTAS + case NT_TRANSACT_GET_USER_QUOTA: + START_PROFILE_NESTED(NT_transact_get_user_quota); + outsize = call_nt_transact_get_user_quota(conn, inbuf, outbuf, + length, bufsize, + &setup, setup_count, + ¶ms, total_parameter_count, + &data, total_data_count); + END_PROFILE_NESTED(NT_transact_get_user_quota); + break; + case NT_TRANSACT_SET_USER_QUOTA: + START_PROFILE_NESTED(NT_transact_set_user_quota); + outsize = call_nt_transact_set_user_quota(conn, inbuf, outbuf, + length, bufsize, + &setup, setup_count, + ¶ms, total_parameter_count, + &data, total_data_count); + END_PROFILE_NESTED(NT_transact_set_user_quota); + break; +#endif /* HAVE_SYS_QUOTAS */ default: /* Error in request */ DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n", function_code)); diff --git a/source/smbd/open.c b/source/smbd/open.c index 510b28172d2..15171ce9e3d 100644 --- a/source/smbd/open.c +++ b/source/smbd/open.c @@ -38,13 +38,13 @@ static int fd_open(struct connection_struct *conn, char *fname, flags |= O_NOFOLLOW; #endif - fd = conn->vfs_ops.open(conn,fname,flags,mode); + fd = SMB_VFS_OPEN(conn,fname,flags,mode); /* Fix for files ending in '.' */ if((fd == -1) && (errno == ENOENT) && (strchr_m(fname,'.')==NULL)) { pstrcat(fname,"."); - fd = conn->vfs_ops.open(conn,fname,flags,mode); + fd = SMB_VFS_OPEN(conn,fname,flags,mode); } DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n", fname, @@ -186,9 +186,9 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn, int ret; if (fsp->fd == -1) - ret = vfs_stat(conn, fname, psbuf); + ret = SMB_VFS_STAT(conn, fname, psbuf); else { - ret = vfs_fstat(fsp,fsp->fd,psbuf); + ret = SMB_VFS_FSTAT(fsp,fsp->fd,psbuf); /* If we have an fd, this stat should succeed. */ if (ret == -1) DEBUG(0,("Error doing fstat on open file %s (%s)\n", fname,strerror(errno) )); @@ -259,7 +259,7 @@ static int truncate_unless_locked(struct connection_struct *conn, files_struct * unix_ERR_ntstatus = dos_to_ntstatus(ERRDOS, ERRlock); return -1; } else { - return conn->vfs_ops.ftruncate(fsp,fsp->fd,0); + return SMB_VFS_FTRUNCATE(fsp,fsp->fd,0); } } @@ -1073,7 +1073,7 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n", /* * We are modifing the file after open - update the stat struct.. */ - if ((truncate_unless_locked(conn,fsp) == -1) || (vfs_fstat(fsp,fsp->fd,psbuf)==-1)) { + if ((truncate_unless_locked(conn,fsp) == -1) || (SMB_VFS_FSTAT(fsp,fsp->fd,psbuf)==-1)) { unlock_share_entry_fsp(fsp); fd_close(conn,fsp); file_free(fsp); @@ -1148,11 +1148,11 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n", * selected. */ - if (!file_existed && !def_acl && (conn->vfs_ops.fchmod_acl != NULL)) { + if (!file_existed && !def_acl) { int saved_errno = errno; /* We might get ENOSYS in the next call.. */ - if (conn->vfs_ops.fchmod_acl(fsp, fsp->fd, mode) == -1 && errno == ENOSYS) + if (SMB_VFS_FCHMOD_ACL(fsp, fsp->fd, mode) == -1 && errno == ENOSYS) errno = saved_errno; /* Ignore ENOSYS */ } else if (new_mode) { @@ -1161,9 +1161,9 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n", /* Attributes need changing. File already existed. */ - if (conn->vfs_ops.fchmod_acl != NULL) { + { int saved_errno = errno; /* We might get ENOSYS in the next call.. */ - ret = conn->vfs_ops.fchmod_acl(fsp, fsp->fd, new_mode); + ret = SMB_VFS_FCHMOD_ACL(fsp, fsp->fd, new_mode); if (ret == -1 && errno == ENOSYS) { errno = saved_errno; /* Ignore ENOSYS */ @@ -1174,7 +1174,7 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n", } } - if ((ret == -1) && (conn->vfs_ops.fchmod(fsp, fsp->fd, new_mode) == -1)) + if ((ret == -1) && (SMB_VFS_FCHMOD(fsp, fsp->fd, new_mode) == -1)) DEBUG(5, ("open_file_shared: failed to reset attributes of file %s to 0%o\n", fname, (int)new_mode)); } @@ -1280,14 +1280,14 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST return NULL; } - if(vfs_mkdir(conn,fname, unix_mode(conn,aDIR, fname)) < 0) { + 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) )); file_free(fsp); return NULL; } - if(vfs_stat(conn,fname, psbuf) != 0) { + if(SMB_VFS_STAT(conn,fname, psbuf) != 0) { file_free(fsp); return NULL; } diff --git a/source/smbd/oplock.c b/source/smbd/oplock.c index 632dfe9e291..85256877937 100644 --- a/source/smbd/oplock.c +++ b/source/smbd/oplock.c @@ -391,7 +391,7 @@ pid %d, port %d, dev = %x, inode = %.0f, file_id = %lu\n", /* * Keep this as a debug case - eventually we can remove it. */ - case (CMD_REPLY | KERNEL_OPLOCK_BREAK_CMD): + case 0x8001: DEBUG(0,("process_local_message: Received unsolicited break \ reply - dumping info.\n")); diff --git a/source/smbd/posix_acls.c b/source/smbd/posix_acls.c index a362db7d564..12eef46595d 100644 --- a/source/smbd/posix_acls.c +++ b/source/smbd/posix_acls.c @@ -158,9 +158,9 @@ static mode_t convert_permset_to_mode_t(connection_struct *conn, SMB_ACL_PERMSET { mode_t ret = 0; - ret |= (conn->vfs_ops.sys_acl_get_perm(conn, permset, SMB_ACL_READ) ? S_IRUSR : 0); - ret |= (conn->vfs_ops.sys_acl_get_perm(conn, permset, SMB_ACL_WRITE) ? S_IWUSR : 0); - ret |= (conn->vfs_ops.sys_acl_get_perm(conn, permset, SMB_ACL_EXECUTE) ? S_IXUSR : 0); + ret |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? S_IRUSR : 0); + ret |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? S_IWUSR : 0); + ret |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? S_IXUSR : 0); return ret; } @@ -190,18 +190,18 @@ static mode_t unix_perms_to_acl_perms(mode_t mode, int r_mask, int w_mask, int x static int map_acl_perms_to_permset(connection_struct *conn, mode_t mode, SMB_ACL_PERMSET_T *p_permset) { - if (conn->vfs_ops.sys_acl_clear_perms(conn, *p_permset) == -1) + if (SMB_VFS_SYS_ACL_CLEAR_PERMS(conn, *p_permset) == -1) return -1; if (mode & S_IRUSR) { - if (conn->vfs_ops.sys_acl_add_perm(conn, *p_permset, SMB_ACL_READ) == -1) + if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_READ) == -1) return -1; } if (mode & S_IWUSR) { - if (conn->vfs_ops.sys_acl_add_perm(conn, *p_permset, SMB_ACL_WRITE) == -1) + if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_WRITE) == -1) return -1; } if (mode & S_IXUSR) { - if (conn->vfs_ops.sys_acl_add_perm(conn, *p_permset, SMB_ACL_EXECUTE) == -1) + if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_EXECUTE) == -1) return -1; } return 0; @@ -637,62 +637,6 @@ static BOOL ensure_canon_entry_valid(canon_ace **pp_ace, } } - /* - * When setting ACLs and missing one out of SMB_ACL_USER_OBJ, - * SMB_ACL_GROUP_OBJ, SMB_ACL_OTHER, try to retrieve current - * values. For user and other a simple vfs_stat would do, but - * we would get mask instead of group. Let's do it via ACL. - */ - - if (setting_acl && (!got_user || !got_grp || !got_other)) { - - SMB_ACL_ENTRY_T entry; - int entry_id = SMB_ACL_FIRST_ENTRY; - - if(fsp->is_directory || fsp->fd == -1) { - current_posix_acl = conn->vfs_ops.sys_acl_get_file(conn, fsp->fsp_name, SMB_ACL_TYPE_ACCESS); - } else { - current_posix_acl = conn->vfs_ops.sys_acl_get_fd(fsp, fsp->fd); - } - - if (current_posix_acl) { - while (conn->vfs_ops.sys_acl_get_entry(conn, current_posix_acl, entry_id, &entry) == 1) { - SMB_ACL_TAG_T tagtype; - SMB_ACL_PERMSET_T permset; - - /* get_next... */ - if (entry_id == SMB_ACL_FIRST_ENTRY) - entry_id = SMB_ACL_NEXT_ENTRY; - - /* Is this a MASK entry ? */ - if (conn->vfs_ops.sys_acl_get_tag_type(conn, entry, &tagtype) == -1) - continue; - - if (conn->vfs_ops.sys_acl_get_permset(conn, entry, &permset) == -1) - continue; - - switch(tagtype) { - case SMB_ACL_USER_OBJ: - current_user_perms = convert_permset_to_mode_t(conn, permset); - got_current_user = True; - break; - case SMB_ACL_GROUP_OBJ: - current_grp_perms = convert_permset_to_mode_t(conn, permset); - got_current_grp = True; - break; - case SMB_ACL_OTHER: - current_other_perms = convert_permset_to_mode_t(conn, permset); - got_current_other = True; - break; - } - } - conn->vfs_ops.sys_acl_free_acl(conn, current_posix_acl); - } else { - DEBUG(10,("ensure_canon_entry_valid: failed to retrieve current ACL of %s\n", - fsp->fsp_name)); - } - } - if (!got_user) { if ((pace = (canon_ace *)malloc(sizeof(canon_ace))) == NULL) { DEBUG(0,("ensure_canon_entry_valid: malloc fail.\n")); @@ -1684,7 +1628,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_ SMB_ACL_ENTRY_T entry; size_t ace_count; - while ( posix_acl && (conn->vfs_ops.sys_acl_get_entry(conn, posix_acl, entry_id, &entry) == 1)) { + while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) { SMB_ACL_TAG_T tagtype; SMB_ACL_PERMSET_T permset; DOM_SID sid; @@ -1696,10 +1640,10 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_ entry_id = SMB_ACL_NEXT_ENTRY; /* Is this a MASK entry ? */ - if (conn->vfs_ops.sys_acl_get_tag_type(conn, entry, &tagtype) == -1) + if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1) continue; - if (conn->vfs_ops.sys_acl_get_permset(conn, entry, &permset) == -1) + if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) continue; /* Decide which SID to use based on the ACL type. */ @@ -1712,7 +1656,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_ break; case SMB_ACL_USER: { - uid_t *puid = (uid_t *)conn->vfs_ops.sys_acl_get_qualifier(conn, entry); + uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry); if (puid == NULL) { DEBUG(0,("canonicalise_acl: Failed to get uid.\n")); continue; @@ -1729,7 +1673,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_ uid_to_sid( &sid, *puid); unix_ug.uid = *puid; owner_type = UID_ACE; - conn->vfs_ops.sys_acl_free_qualifier(conn, (void *)puid,tagtype); + SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype); break; } case SMB_ACL_GROUP_OBJ: @@ -1740,7 +1684,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_ break; case SMB_ACL_GROUP: { - gid_t *pgid = (gid_t *)conn->vfs_ops.sys_acl_get_qualifier(conn, entry); + gid_t *pgid = (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry); if (pgid == NULL) { DEBUG(0,("canonicalise_acl: Failed to get gid.\n")); continue; @@ -1748,7 +1692,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_ gid_to_sid( &sid, *pgid); unix_ug.gid = *pgid; owner_type = GID_ACE; - conn->vfs_ops.sys_acl_free_qualifier(conn, (void *)pgid,tagtype); + SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)pgid,tagtype); break; } case SMB_ACL_MASK: @@ -1833,7 +1777,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau { connection_struct *conn = fsp->conn; BOOL ret = False; - SMB_ACL_T the_acl = conn->vfs_ops.sys_acl_init(conn, (int)count_canon_ace_list(the_ace) + 1); + SMB_ACL_T the_acl = SMB_VFS_SYS_ACL_INIT(conn, (int)count_canon_ace_list(the_ace) + 1); canon_ace *p_ace; int i; SMB_ACL_ENTRY_T mask_entry; @@ -1891,7 +1835,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau * Get the entry for this ACE. */ - if (conn->vfs_ops.sys_acl_create_entry(conn, &the_acl, &the_entry) == -1) { + if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &the_acl, &the_entry) == -1) { DEBUG(0,("set_canon_ace_list: Failed to create entry %d. (%s)\n", i, strerror(errno) )); goto done; @@ -1917,7 +1861,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau * First tell the entry what type of ACE this is. */ - if (conn->vfs_ops.sys_acl_set_tag_type(conn, the_entry, p_ace->type) == -1) { + if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, the_entry, p_ace->type) == -1) { DEBUG(0,("set_canon_ace_list: Failed to set tag type on entry %d. (%s)\n", i, strerror(errno) )); goto done; @@ -1929,7 +1873,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau */ if ((p_ace->type == SMB_ACL_USER) || (p_ace->type == SMB_ACL_GROUP)) { - if (conn->vfs_ops.sys_acl_set_qualifier(conn, the_entry,(void *)&p_ace->unix_ug.uid) == -1) { + if (SMB_VFS_SYS_ACL_SET_QUALIFIER(conn, the_entry,(void *)&p_ace->unix_ug.uid) == -1) { DEBUG(0,("set_canon_ace_list: Failed to set qualifier on entry %d. (%s)\n", i, strerror(errno) )); goto done; @@ -1940,7 +1884,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau * Convert the mode_t perms in the canon_ace to a POSIX permset. */ - if (conn->vfs_ops.sys_acl_get_permset(conn, the_entry, &the_permset) == -1) { + if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, the_entry, &the_permset) == -1) { DEBUG(0,("set_canon_ace_list: Failed to get permset on entry %d. (%s)\n", i, strerror(errno) )); goto done; @@ -1956,7 +1900,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau * ..and apply them to the entry. */ - if (conn->vfs_ops.sys_acl_set_permset(conn, the_entry, the_permset) == -1) { + if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, the_entry, the_permset) == -1) { DEBUG(0,("set_canon_ace_list: Failed to add permset on entry %d. (%s)\n", i, strerror(errno) )); goto done; @@ -1967,17 +1911,17 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau } if (needs_mask && !got_mask_entry) { - if (conn->vfs_ops.sys_acl_create_entry(conn, &the_acl, &mask_entry) == -1) { + if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &the_acl, &mask_entry) == -1) { DEBUG(0,("set_canon_ace_list: Failed to create mask entry. (%s)\n", strerror(errno) )); goto done; } - if (conn->vfs_ops.sys_acl_set_tag_type(conn, mask_entry, SMB_ACL_MASK) == -1) { + if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, mask_entry, SMB_ACL_MASK) == -1) { DEBUG(0,("set_canon_ace_list: Failed to set tag type on mask entry. (%s)\n",strerror(errno) )); goto done; } - if (conn->vfs_ops.sys_acl_get_permset(conn, mask_entry, &mask_permset) == -1) { + if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, mask_entry, &mask_permset) == -1) { DEBUG(0,("set_canon_ace_list: Failed to get mask permset. (%s)\n", strerror(errno) )); goto done; } @@ -1987,7 +1931,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau goto done; } - if (conn->vfs_ops.sys_acl_set_permset(conn, mask_entry, mask_permset) == -1) { + if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, mask_entry, mask_permset) == -1) { DEBUG(0,("set_canon_ace_list: Failed to add mask permset. (%s)\n", strerror(errno) )); goto done; } @@ -1997,7 +1941,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau * Check if the ACL is valid. */ - if (conn->vfs_ops.sys_acl_valid(conn, the_acl) == -1) { + if (SMB_VFS_SYS_ACL_VALID(conn, the_acl) == -1) { DEBUG(0,("set_canon_ace_list: ACL type (%s) is invalid for set (%s).\n", the_acl_type == SMB_ACL_TYPE_DEFAULT ? "directory default" : "file", strerror(errno) )); @@ -2009,7 +1953,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau */ if(default_ace || fsp->is_directory || fsp->fd == -1) { - if (conn->vfs_ops.sys_acl_set_file(conn, fsp->fsp_name, the_acl_type, the_acl) == -1) { + if (SMB_VFS_SYS_ACL_SET_FILE(conn, fsp->fsp_name, the_acl_type, the_acl) == -1) { /* * Some systems allow all the above calls and only fail with no ACL support * when attempting to apply the acl. HPUX with HFS is an example of this. JRA. @@ -2028,7 +1972,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau goto done; } } else { - if (conn->vfs_ops.sys_acl_set_fd(fsp, fsp->fd, the_acl) == -1) { + if (SMB_VFS_SYS_ACL_SET_FD(fsp, fsp->fd, the_acl) == -1) { /* * Some systems allow all the above calls and only fail with no ACL support * when attempting to apply the acl. HPUX with HFS is an example of this. JRA. @@ -2052,7 +1996,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau done: if (the_acl != NULL) - conn->vfs_ops.sys_acl_free_acl(conn, the_acl); + SMB_VFS_SYS_ACL_FREE_ACL(conn, the_acl); return ret; } @@ -2083,8 +2027,8 @@ SMB_ACL_T free_empty_sys_acl(connection_struct *conn, SMB_ACL_T the_acl) if (!the_acl) return NULL; - if (conn->vfs_ops.sys_acl_get_entry(conn, the_acl, SMB_ACL_FIRST_ENTRY, &entry) != 1) { - conn->vfs_ops.sys_acl_free_acl(conn, the_acl); + if (SMB_VFS_SYS_ACL_GET_ENTRY(conn, the_acl, SMB_ACL_FIRST_ENTRY, &entry) != 1) { + SMB_VFS_SYS_ACL_FREE_ACL(conn, the_acl); return NULL; } return the_acl; @@ -2221,7 +2165,7 @@ static size_t merge_default_aces( SEC_ACE *nt_ace_list, size_t num_aces) the UNIX style get ACL. ****************************************************************************/ -size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc) +size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) { extern DOM_SID global_sid_Builtin_Administrators; extern DOM_SID global_sid_Builtin_Users; @@ -2250,34 +2194,34 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc) if(fsp->is_directory || fsp->fd == -1) { /* Get the stat struct for the owner info. */ - if(vfs_stat(fsp->conn,fsp->fsp_name, &sbuf) != 0) { + if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0) { return 0; } /* * Get the ACL from the path. */ - posix_acl = conn->vfs_ops.sys_acl_get_file(conn, fsp->fsp_name, SMB_ACL_TYPE_ACCESS); + posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_ACCESS); /* * If it's a directory get the default POSIX ACL. */ if(fsp->is_directory) { - dir_acl = conn->vfs_ops.sys_acl_get_file(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT); + dir_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT); dir_acl = free_empty_sys_acl(conn, dir_acl); } } else { /* Get the stat struct for the owner info. */ - if(vfs_fstat(fsp,fsp->fd,&sbuf) != 0) { + if(SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) { return 0; } /* * Get the ACL from the fd. */ - posix_acl = conn->vfs_ops.sys_acl_get_fd(fsp, fsp->fd); + posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fd); } DEBUG(5,("get_nt_acl : file ACL %s, directory ACL %s\n", @@ -2297,182 +2241,182 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc) create_file_sids(&sbuf, &owner_sid, &group_sid); } - /* - * In the optimum case Creator Owner and Creator Group would be used for - * the ACL_USER_OBJ and ACL_GROUP_OBJ entries, respectively, but this - * would lead to usability problems under Windows: The Creator entries - * are only available in browse lists of directories and not for files; - * additionally the identity of the owning group couldn't be determined. - * We therefore use those identities only for Default ACLs. - */ + if (security_info & DACL_SECURITY_INFORMATION) { - /* Create the canon_ace lists. */ - file_ace = canonicalise_acl( fsp, posix_acl, &sbuf, &owner_sid, &group_sid, SMB_ACL_TYPE_ACCESS ); + /* + * In the optimum case Creator Owner and Creator Group would be used for + * the ACL_USER_OBJ and ACL_GROUP_OBJ entries, respectively, but this + * would lead to usability problems under Windows: The Creator entries + * are only available in browse lists of directories and not for files; + * additionally the identity of the owning group couldn't be determined. + * We therefore use those identities only for Default ACLs. + */ - /* We must have *some* ACLS. */ + /* Create the canon_ace lists. */ + file_ace = canonicalise_acl( fsp, posix_acl, &sbuf, &owner_sid, &group_sid, SMB_ACL_TYPE_ACCESS ); - if (count_canon_ace_list(file_ace) == 0) { - DEBUG(0,("get_nt_acl : No ACLs on file (%s) !\n", fsp->fsp_name )); - return 0; - } - - if (fsp->is_directory && dir_acl) { - dir_ace = canonicalise_acl(fsp, dir_acl, &sbuf, - &global_sid_Creator_Owner, - &global_sid_Creator_Group, SMB_ACL_TYPE_DEFAULT ); - } + /* We must have *some* ACLS. */ + + if (count_canon_ace_list(file_ace) == 0) { + DEBUG(0,("get_nt_acl : No ACLs on file (%s) !\n", fsp->fsp_name )); + return 0; + } - /* - * Create the NT ACE list from the canonical ace lists. - */ + if (fsp->is_directory && dir_acl) { + dir_ace = canonicalise_acl(fsp, dir_acl, &sbuf, + &global_sid_Creator_Owner, + &global_sid_Creator_Group, SMB_ACL_TYPE_DEFAULT ); + } - { - canon_ace *ace; - int nt_acl_type; - int i; + /* + * Create the NT ACE list from the canonical ace lists. + */ - if (nt4_compatible_acls() && dir_ace) { - /* - * NT 4 chokes if an ACL contains an INHERIT_ONLY entry - * but no non-INHERIT_ONLY entry for one SID. So we only - * remove entries from the Access ACL if the - * corresponding Default ACL entries have also been - * removed. ACEs for CREATOR-OWNER and CREATOR-GROUP - * are exceptions. We can do nothing - * intelligent if the Default ACL contains entries that - * are not also contained in the Access ACL, so this - * case will still fail under NT 4. - */ + { + canon_ace *ace; + int nt_acl_type; + int i; - ace = canon_ace_entry_for(dir_ace, SMB_ACL_OTHER, NULL); - if (ace && !ace->perms) { - DLIST_REMOVE(dir_ace, ace); - SAFE_FREE(ace); + if (nt4_compatible_acls() && dir_ace) { + /* + * NT 4 chokes if an ACL contains an INHERIT_ONLY entry + * but no non-INHERIT_ONLY entry for one SID. So we only + * remove entries from the Access ACL if the + * corresponding Default ACL entries have also been + * removed. ACEs for CREATOR-OWNER and CREATOR-GROUP + * are exceptions. We can do nothing + * intelligent if the Default ACL contains entries that + * are not also contained in the Access ACL, so this + * case will still fail under NT 4. + */ - ace = canon_ace_entry_for(file_ace, SMB_ACL_OTHER, NULL); + ace = canon_ace_entry_for(dir_ace, SMB_ACL_OTHER, NULL); if (ace && !ace->perms) { - DLIST_REMOVE(file_ace, ace); + DLIST_REMOVE(dir_ace, ace); SAFE_FREE(ace); + + ace = canon_ace_entry_for(file_ace, SMB_ACL_OTHER, NULL); + if (ace && !ace->perms) { + DLIST_REMOVE(file_ace, ace); + SAFE_FREE(ace); + } } - } - /* - * WinNT doesn't usually have Creator Group - * in browse lists, so we send this entry to - * WinNT even if it contains no relevant - * permissions. Once we can add - * Creator Group to browse lists we can - * re-enable this. - */ + /* + * WinNT doesn't usually have Creator Group + * in browse lists, so we send this entry to + * WinNT even if it contains no relevant + * permissions. Once we can add + * Creator Group to browse lists we can + * re-enable this. + */ #if 0 - ace = canon_ace_entry_for(dir_ace, SMB_ACL_GROUP_OBJ, NULL); - if (ace && !ace->perms) { - DLIST_REMOVE(dir_ace, ace); - SAFE_FREE(ace); - } + ace = canon_ace_entry_for(dir_ace, SMB_ACL_GROUP_OBJ, NULL); + if (ace && !ace->perms) { + DLIST_REMOVE(dir_ace, ace); + SAFE_FREE(ace); + } #endif - ace = canon_ace_entry_for(file_ace, SMB_ACL_GROUP_OBJ, NULL); - if (ace && !ace->perms) { - DLIST_REMOVE(file_ace, ace); - SAFE_FREE(ace); - } - } else { - - ace = canon_ace_entry_for(dir_ace, SMB_ACL_OTHER, NULL); - if (ace && !ace->perms) { - DLIST_REMOVE(dir_ace, ace); - SAFE_FREE(ace); - } - ace = canon_ace_entry_for(dir_ace, SMB_ACL_GROUP_OBJ, NULL); - if (ace && !ace->perms) { - DLIST_REMOVE(dir_ace, ace); - SAFE_FREE(ace); + ace = canon_ace_entry_for(file_ace, SMB_ACL_GROUP_OBJ, NULL); + if (ace && !ace->perms) { + DLIST_REMOVE(file_ace, ace); + SAFE_FREE(ace); + } } - } - - num_acls = count_canon_ace_list(file_ace); - num_dir_acls = count_canon_ace_list(dir_ace); - /* Allocate the ace list. */ - if ((nt_ace_list = (SEC_ACE *)malloc((num_acls + num_profile_acls + num_dir_acls)* sizeof(SEC_ACE))) == NULL) { - DEBUG(0,("get_nt_acl: Unable to malloc space for nt_ace_list.\n")); - goto done; - } + num_acls = count_canon_ace_list(file_ace); + num_dir_acls = count_canon_ace_list(dir_ace); - memset(nt_ace_list, '\0', (num_acls + num_dir_acls) * sizeof(SEC_ACE) ); - - /* - * Create the NT ACE list from the canonical ace lists. - */ - - ace = file_ace; + /* Allocate the ace list. */ + if ((nt_ace_list = (SEC_ACE *)malloc((num_acls + num_profile_acls + num_dir_acls)* sizeof(SEC_ACE))) == NULL) { + DEBUG(0,("get_nt_acl: Unable to malloc space for nt_ace_list.\n")); + goto done; + } - for (i = 0; i < num_acls; i++, ace = ace->next) { - SEC_ACCESS acc; + memset(nt_ace_list, '\0', (num_acls + num_dir_acls) * sizeof(SEC_ACE) ); + + /* + * Create the NT ACE list from the canonical ace lists. + */ + + ace = file_ace; - acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace ); - init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc, 0); - } + for (i = 0; i < num_acls; i++, ace = ace->next) { + SEC_ACCESS acc; - /* The User must have access to a profile share - even if we can't map the SID. */ - if (lp_profile_acls(SNUM(fsp->conn))) { - SEC_ACCESS acc; + acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace ); + init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc, 0); + } - init_sec_access(&acc,FILE_GENERIC_ALL); - init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, acc, 0); - } + /* The User must have access to a profile share - even if we can't map the SID. */ + if (lp_profile_acls(SNUM(fsp->conn))) { + SEC_ACCESS acc; - ace = dir_ace; + init_sec_access(&acc,FILE_GENERIC_ALL); + init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, acc, 0); + } - for (i = 0; i < num_dir_acls; i++, ace = ace->next) { - SEC_ACCESS acc; + ace = dir_ace; - acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace ); - init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc, - SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY); - } + for (i = 0; i < num_dir_acls; i++, ace = ace->next) { + SEC_ACCESS acc; + + acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace ); + init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc, + SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY); + } - /* The User must have access to a profile share - even if we can't map the SID. */ - if (lp_profile_acls(SNUM(fsp->conn))) { - SEC_ACCESS acc; + /* The User must have access to a profile share - even if we can't map the SID. */ + if (lp_profile_acls(SNUM(fsp->conn))) { + SEC_ACCESS acc; - init_sec_access(&acc,FILE_GENERIC_ALL); - init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, acc, - SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT| - SEC_ACE_FLAG_INHERIT_ONLY); - } - - /* - * Merge POSIX default ACLs and normal ACLs into one NT ACE. - * Win2K needs this to get the inheritance correct when replacing ACLs - * on a directory tree. Based on work by Jim @ IBM. - */ + init_sec_access(&acc,FILE_GENERIC_ALL); + init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, acc, + SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT| + SEC_ACE_FLAG_INHERIT_ONLY); + } - num_aces = merge_default_aces(nt_ace_list, num_aces); + /* + * Merge POSIX default ACLs and normal ACLs into one NT ACE. + * Win2K needs this to get the inheritance correct when replacing ACLs + * on a directory tree. Based on work by Jim @ IBM. + */ - /* - * Sort to force deny entries to the front. - */ + num_aces = merge_default_aces(nt_ace_list, num_aces); - if (num_aces) - qsort( nt_ace_list, num_aces, sizeof(nt_ace_list[0]), QSORT_CAST nt_ace_comp); - } + /* + * Sort to force deny entries to the front. + */ + + if (num_aces) + qsort( nt_ace_list, num_aces, sizeof(nt_ace_list[0]), QSORT_CAST nt_ace_comp); + } - if (num_aces) { - if((psa = make_sec_acl( main_loop_talloc_get(), ACL_REVISION, num_aces, nt_ace_list)) == NULL) { - DEBUG(0,("get_nt_acl: Unable to malloc space for acl.\n")); - goto done; + if (num_aces) { + if((psa = make_sec_acl( main_loop_talloc_get(), ACL_REVISION, num_aces, nt_ace_list)) == NULL) { + DEBUG(0,("get_nt_acl: Unable to malloc space for acl.\n")); + goto done; + } } - } + } /* security_info & DACL_SECURITY_INFORMATION */ - *ppdesc = make_standard_sec_desc( main_loop_talloc_get(), &owner_sid, &group_sid, psa, &sd_size); + *ppdesc = make_standard_sec_desc( main_loop_talloc_get(), + (security_info & OWNER_SECURITY_INFORMATION) ? &owner_sid : NULL, + (security_info & GROUP_SECURITY_INFORMATION) ? &group_sid : NULL, + psa, + &sd_size); if(!*ppdesc) { DEBUG(0,("get_nt_acl: Unable to malloc space for security descriptor.\n")); sd_size = 0; } else { +#if 1 + /* + * JRA. Setting this flag causes W2K clients not to + * propagate ACL sets down a directory tree correctly. + */ /* * Windows 2000: The DACL_PROTECTED flag in the security * descriptor marks the ACL as non-inheriting, i.e., no @@ -2483,14 +2427,15 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc) * flag doesn't seem to bother Windows NT. */ (*ppdesc)->type |= SE_DESC_DACL_PROTECTED; +#endif } done: if (posix_acl) - conn->vfs_ops.sys_acl_free_acl(conn, posix_acl); + SMB_VFS_SYS_ACL_FREE_ACL(conn, posix_acl); if (dir_acl) - conn->vfs_ops.sys_acl_free_acl(conn, dir_acl); + SMB_VFS_SYS_ACL_FREE_ACL(conn, dir_acl); free_canon_ace_list(file_ace); free_canon_ace_list(dir_ace); SAFE_FREE(nt_ace_list); @@ -2514,14 +2459,14 @@ static int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_ SMB_STRUCT_STAT st; /* try the direct way first */ - ret = vfs_chown(conn, fname, uid, gid); + ret = SMB_VFS_CHOWN(conn, fname, uid, gid); if (ret == 0) return 0; if(!CAN_WRITE(conn) || !lp_dos_filemode(SNUM(conn))) return -1; - if (vfs_stat(conn,fname,&st)) + if (SMB_VFS_STAT(conn,fname,&st)) return -1; fsp = open_file_fchmod(conn,fname,&st); @@ -2536,7 +2481,7 @@ static int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_ become_root(); /* Keep the current file gid the same. */ - ret = vfswrap_fchown(fsp, fsp->fd, uid, (gid_t)-1); + ret = SMB_VFS_FCHOWN(fsp, fsp->fd, uid, (gid_t)-1); unbecome_root(); close_file_fchmod(fsp); @@ -2579,10 +2524,10 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) */ if(fsp->is_directory || fsp->fd == -1) { - if(vfs_stat(fsp->conn,fsp->fsp_name, &sbuf) != 0) + if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0) return False; } else { - if(vfs_fstat(fsp,fsp->fd,&sbuf) != 0) + if(SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) return False; } @@ -2628,7 +2573,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) */ if(fsp->is_directory) { - if(vfs_stat(fsp->conn, fsp->fsp_name, &sbuf) != 0) { + if(SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf) != 0) { return False; } } else { @@ -2636,9 +2581,9 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) int ret; if(fsp->fd == -1) - ret = vfs_stat(fsp->conn, fsp->fsp_name, &sbuf); + ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf); else - ret = vfs_fstat(fsp,fsp->fd,&sbuf); + ret = SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf); if(ret != 0) return False; @@ -2706,7 +2651,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) * No default ACL - delete one if it exists. */ - if (conn->vfs_ops.sys_acl_delete_def_file(conn, fsp->fsp_name) == -1) { + if (SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fsp->fsp_name) == -1) { DEBUG(3,("set_nt_acl: sys_acl_delete_def_file failed (%s)\n", strerror(errno))); free_canon_ace_list(file_ace_list); free_canon_ace_list(dir_ace_list); @@ -2735,7 +2680,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) DEBUG(3,("set_nt_acl: chmod %s. perms = 0%o.\n", fsp->fsp_name, (unsigned int)posix_perms )); - if(conn->vfs_ops.chmod(conn,fsp->fsp_name, posix_perms) == -1) { + if(SMB_VFS_CHMOD(conn,fsp->fsp_name, posix_perms) == -1) { DEBUG(3,("set_nt_acl: chmod %s, 0%o failed. Error = %s.\n", fsp->fsp_name, (unsigned int)posix_perms, strerror(errno) )); free_canon_ace_list(file_ace_list); @@ -2777,7 +2722,7 @@ static int chmod_acl_internals( connection_struct *conn, SMB_ACL_T posix_acl, mo SMB_ACL_ENTRY_T entry; int num_entries = 0; - while ( conn->vfs_ops.sys_acl_get_entry(conn, posix_acl, entry_id, &entry) == 1) { + while ( SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1) { SMB_ACL_TAG_T tagtype; SMB_ACL_PERMSET_T permset; mode_t perms; @@ -2786,10 +2731,10 @@ static int chmod_acl_internals( connection_struct *conn, SMB_ACL_T posix_acl, mo if (entry_id == SMB_ACL_FIRST_ENTRY) entry_id = SMB_ACL_NEXT_ENTRY; - if (conn->vfs_ops.sys_acl_get_tag_type(conn, entry, &tagtype) == -1) + if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1) return -1; - if (conn->vfs_ops.sys_acl_get_permset(conn, entry, &permset) == -1) + if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) return -1; num_entries++; @@ -2820,7 +2765,7 @@ static int chmod_acl_internals( connection_struct *conn, SMB_ACL_T posix_acl, mo if (map_acl_perms_to_permset(conn, perms, &permset) == -1) return -1; - if (conn->vfs_ops.sys_acl_set_permset(conn, entry, permset) == -1) + if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, entry, permset) == -1) return -1; } @@ -2846,17 +2791,17 @@ static int copy_access_acl(connection_struct *conn, const char *from, const char SMB_ACL_T posix_acl = NULL; int ret = -1; - if ((posix_acl = conn->vfs_ops.sys_acl_get_file(conn, from, SMB_ACL_TYPE_ACCESS)) == NULL) + if ((posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, from, SMB_ACL_TYPE_ACCESS)) == NULL) return -1; if ((ret = chmod_acl_internals(conn, posix_acl, mode)) == -1) goto done; - ret = conn->vfs_ops.sys_acl_set_file(conn, to, SMB_ACL_TYPE_ACCESS, posix_acl); + ret = SMB_VFS_SYS_ACL_SET_FILE(conn, to, SMB_ACL_TYPE_ACCESS, posix_acl); done: - conn->vfs_ops.sys_acl_free_acl(conn, posix_acl); + SMB_VFS_SYS_ACL_FREE_ACL(conn, posix_acl); return ret; } @@ -2898,17 +2843,17 @@ int fchmod_acl(files_struct *fsp, int fd, mode_t mode) SMB_ACL_T posix_acl = NULL; int ret = -1; - if ((posix_acl = conn->vfs_ops.sys_acl_get_fd(fsp, fd)) == NULL) + if ((posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fd)) == NULL) return -1; if ((ret = chmod_acl_internals(conn, posix_acl, mode)) == -1) goto done; - ret = conn->vfs_ops.sys_acl_set_fd(fsp, fd, posix_acl); + ret = SMB_VFS_SYS_ACL_SET_FD(fsp, fd, posix_acl); done: - conn->vfs_ops.sys_acl_free_acl(conn, posix_acl); + SMB_VFS_SYS_ACL_FREE_ACL(conn, posix_acl); return ret; } @@ -2918,14 +2863,14 @@ int fchmod_acl(files_struct *fsp, int fd, mode_t mode) BOOL directory_has_default_acl(connection_struct *conn, const char *fname) { - SMB_ACL_T dir_acl = conn->vfs_ops.sys_acl_get_file( conn, fname, SMB_ACL_TYPE_DEFAULT); + SMB_ACL_T dir_acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, SMB_ACL_TYPE_DEFAULT); BOOL has_acl = False; SMB_ACL_ENTRY_T entry; - if (dir_acl != NULL && (conn->vfs_ops.sys_acl_get_entry(conn, dir_acl, SMB_ACL_FIRST_ENTRY, &entry) == 1)) + if (dir_acl != NULL && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, dir_acl, SMB_ACL_FIRST_ENTRY, &entry) == 1)) has_acl = True; if (dir_acl) - conn->vfs_ops.sys_acl_free_acl(conn, dir_acl); + SMB_VFS_SYS_ACL_FREE_ACL(conn, dir_acl); return has_acl; } diff --git a/source/smbd/quotas.c b/source/smbd/quotas.c index 5b843bd09a6..91c952aa902 100644 --- a/source/smbd/quotas.c +++ b/source/smbd/quotas.c @@ -27,6 +27,15 @@ #include "includes.h" +#ifndef HAVE_SYS_QUOTAS + +/* just a quick hack because sysquotas.h is included before linux/quota.h */ +#ifdef QUOTABLOCK_SIZE +#undef QUOTABLOCK_SIZE +#endif + +#ifdef WITH_QUOTAS + #if defined(VXFS_QUOTA) /* @@ -1112,3 +1121,108 @@ BOOL disk_quotas_vxfs(const pstring name, char *path, SMB_BIG_UINT *bsize, SMB_B #endif /* SUNOS5 || ... */ #endif /* VXFS_QUOTA */ + +#else /* WITH_QUOTAS */ + +BOOL disk_quotas(const char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize) +{ + (*bsize) = 512; /* This value should be ignored */ + + /* And just to be sure we set some values that hopefully */ + /* will be larger that any possible real-world value */ + (*dfree) = (SMB_BIG_UINT)-1; + (*dsize) = (SMB_BIG_UINT)-1; + + /* As we have select not to use quotas, allways fail */ + return False; +} +#endif /* WITH_QUOTAS */ + +#else /* HAVE_SYS_QUOTAS */ +/* wrapper to the new sys_quota interface + this file should be removed later + */ +BOOL disk_quotas(const char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize) +{ + int r; + SMB_DISK_QUOTA D; + unid_t id; + + id.uid = geteuid(); + + r=sys_get_quota(path, SMB_USER_QUOTA_TYPE, id, &D); + + /* Use softlimit to determine disk space, except when it has been exceeded */ + *bsize = D.bsize; + if (r == -1) { + if (errno == EDQUOT) { + *dfree =0; + *dsize =D.curblocks; + return (True); + } else { + goto try_group_quota; + } + } + + /* Use softlimit to determine disk space, except when it has been exceeded */ + if ( + (D.softlimit && D.curblocks >= D.softlimit) || + (D.hardlimit && D.curblocks >= D.hardlimit) || + (D.isoftlimit && D.curinodes >= D.isoftlimit) || + (D.ihardlimit && D.curinodes>=D.ihardlimit) + ) { + *dfree = 0; + *dsize = D.curblocks; + } else if (D.softlimit==0 && D.hardlimit==0) { + goto try_group_quota; + } else { + if (D.softlimit == 0) + D.softlimit = D.hardlimit; + *dfree = D.softlimit - D.curblocks; + *dsize = D.softlimit; + } + + return True; + +try_group_quota: +#ifdef HAVE_GROUP_QUOTA + id.gid = getegid(); + + r=sys_get_quota(path, SMB_GROUP_QUOTA_TYPE, id, &D); + + /* Use softlimit to determine disk space, except when it has been exceeded */ + *bsize = D.bsize; + if (r == -1) { + if (errno == EDQUOT) { + *dfree =0; + *dsize =D.curblocks; + return (True); + } else { + return False; + } + } + + /* Use softlimit to determine disk space, except when it has been exceeded */ + if ( + (D.softlimit && D.curblocks >= D.softlimit) || + (D.hardlimit && D.curblocks >= D.hardlimit) || + (D.isoftlimit && D.curinodes >= D.isoftlimit) || + (D.ihardlimit && D.curinodes>=D.ihardlimit) + ) { + *dfree = 0; + *dsize = D.curblocks; + } else if (D.softlimit==0 && D.hardlimit==0) { + return False; + } else { + if (D.softlimit == 0) + D.softlimit = D.hardlimit; + *dfree = D.softlimit - D.curblocks; + *dsize = D.softlimit; + } + + return (True); +#else /* HAVE_GROUP_QUOTA */ + return False; +#endif /* HAVE_GROUP_QUOTA */ +} +#endif /* HAVE_SYS_QUOTAS */ diff --git a/source/smbd/reply.c b/source/smbd/reply.c index b2dab2fea25..be51a328911 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -148,7 +148,7 @@ int reply_tcon(connection_struct *conn, const char *service; pstring service_buf; pstring password; - fstring dev; + pstring dev; int outsize = 0; uint16 vuid = SVAL(inbuf,smb_uid); int pwlen=0; @@ -204,7 +204,7 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt { fstring service; DATA_BLOB password; - + /* what the cleint thinks the device is */ fstring client_devicetype; /* what the server tells the client the share represents */ @@ -283,15 +283,16 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt set_message_end(outbuf,p); } else { /* NT sets the fstype of IPC$ to the null string */ - const char *fsname = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn)); + const char *fstype = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn)); set_message(outbuf,3,0,True); - - p = smb_buf(outbuf); + + p = smb_buf(outbuf); p += srvstr_push(outbuf, p, server_devicetype, -1, - STR_TERMINATE|STR_ASCII); - p += srvstr_push(outbuf, p, fsname, -1, - STR_TERMINATE); + STR_TERMINATE|STR_ASCII); + p += srvstr_push(outbuf, p, fstype, -1, + STR_TERMINATE); + set_message_end(outbuf,p); /* what does setting this bit do? It is set by NT4 and @@ -398,7 +399,7 @@ int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size mode = SVAL(inbuf,smb_vwv0); if (check_name(name,conn)) { - if (VALID_STAT(sbuf) || vfs_stat(conn,name,&sbuf) == 0) + if (VALID_STAT(sbuf) || SMB_VFS_STAT(conn,name,&sbuf) == 0) if (!(ok = S_ISDIR(sbuf.st_mode))) errno = ENOTDIR; } @@ -457,7 +458,7 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size } else { unix_convert(fname,conn,0,&bad_path,&sbuf); if (check_name(fname,conn)) { - if (VALID_STAT(sbuf) || vfs_stat(conn,fname,&sbuf) == 0) { + if (VALID_STAT(sbuf) || SMB_VFS_STAT(conn,fname,&sbuf) == 0) { mode = dos_mode(conn,fname,&sbuf); size = sbuf.st_size; mtime = sbuf.st_mtime; @@ -552,7 +553,7 @@ int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz SMB_BIG_UINT dfree,dsize,bsize; START_PROFILE(SMBdskattr); - conn->vfs_ops.disk_free(conn,".",True,&bsize,&dfree,&dsize); + SMB_VFS_DISK_FREE(conn,".",True,&bsize,&dfree,&dsize); outsize = set_message(outbuf,5,0,True); @@ -1127,7 +1128,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, return(UNIXERROR(ERRDOS,ERRnoaccess)); } - vfs_stat(conn,fname,&sbuf); + SMB_VFS_STAT(conn,fname,&sbuf); /* Open file in dos compatibility share mode. */ /* We should fail if file does not exist. */ @@ -1226,7 +1227,7 @@ static NTSTATUS can_delete(char *fname,connection_struct *conn, int dirtype) if (!CAN_WRITE(conn)) return NT_STATUS_MEDIA_WRITE_PROTECTED; - if (conn->vfs_ops.lstat(conn,fname,&sbuf) != 0) + if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0) return NT_STATUS_OBJECT_NAME_NOT_FOUND; fmode = dos_mode(conn,fname,&sbuf); @@ -1312,7 +1313,7 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name) error = can_delete(directory,conn,dirtype); if (!NT_STATUS_IS_OK(error)) return error; - if (vfs_unlink(conn,directory) == 0) { + if (SMB_VFS_UNLINK(conn,directory) == 0) { count++; } } else { @@ -1342,7 +1343,7 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name) slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname); error = can_delete(fname,conn,dirtype); if (!NT_STATUS_IS_OK(error)) continue; - if (vfs_unlink(conn,fname) == 0) count++; + if (SMB_VFS_UNLINK(conn,fname) == 0) count++; DEBUG(3,("unlink_internals: succesful unlink [%s]\n",fname)); } CloseDir(dirptr); @@ -1428,7 +1429,7 @@ void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T st header.length = 4; header.free = NULL; - if ( conn->vfs_ops.sendfile( smbd_server_fd(), fsp, fsp->fd, &header, startpos, nread) == -1) { + if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, nread) == -1) { /* * Special hack for broken Linux with no 64 bit clean sendfile. If we * return ENOSYS then pretend we just got a normal read. @@ -1463,6 +1464,7 @@ void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T st int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) { + extern struct current_user current_user; ssize_t maxcount,mincount; size_t nread = 0; SMB_OFF_T startpos; @@ -1552,7 +1554,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s if (size < sizeneeded) { SMB_STRUCT_STAT st; - if (vfs_fstat(fsp,fsp->fd,&st) == 0) + if (SMB_VFS_FSTAT(fsp,fsp->fd,&st) == 0) size = st.st_size; if (!fsp->can_write) fsp->size = size; @@ -1721,7 +1723,7 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length SMB_STRUCT_STAT sbuf; DATA_BLOB header; - if(vfs_fstat(fsp,fsp->fd, &sbuf) == -1) + if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1) return(UNIXERROR(ERRDOS,ERRnoaccess)); if (startpos > sbuf.st_size) @@ -1748,7 +1750,7 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length header.length = data - outbuf; header.free = NULL; - if ( conn->vfs_ops.sendfile( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt) == -1) { + if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt) == -1) { /* * Special hack for broken Linux with no 64 bit clean sendfile. If we * return ENOSYS then pretend we just got a normal read. @@ -2260,7 +2262,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int break; } - if((res = conn->vfs_ops.lseek(fsp,fsp->fd,startpos,umode)) == -1) { + if((res = SMB_VFS_LSEEK(fsp,fsp->fd,startpos,umode)) == -1) { /* * Check for the special case where a seek before the start * of the file sets the offset to zero. Added in the CIFS spec, @@ -2272,7 +2274,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int if(umode == SEEK_CUR) { - if((current_pos = conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1) { + if((current_pos = SMB_VFS_LSEEK(fsp,fsp->fd,0,SEEK_CUR)) == -1) { END_PROFILE(SMBlseek); return(UNIXERROR(ERRDOS,ERRnoaccess)); } @@ -2283,7 +2285,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int SMB_STRUCT_STAT sbuf; - if(vfs_fstat(fsp,fsp->fd, &sbuf) == -1) { + if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1) { END_PROFILE(SMBlseek); return(UNIXERROR(ERRDOS,ERRnoaccess)); } @@ -2292,7 +2294,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int } if(current_pos < 0) - res = conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_SET); + res = SMB_VFS_LSEEK(fsp,fsp->fd,0,SEEK_SET); } if(res == -1) { @@ -2360,6 +2362,7 @@ int reply_exit(connection_struct *conn, int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize) { + extern struct current_user current_user; int outsize = 0; time_t mtime; int32 eclass = 0, err = 0; @@ -2380,7 +2383,7 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size, * We can only use CHECK_FSP if we know it's not a directory. */ - if(!fsp || (fsp->conn != conn)) { + if(!fsp || (fsp->conn != conn) || (fsp->vuid != current_user.vuid)) { END_PROFILE(SMBclose); return ERROR_DOS(ERRDOS,ERRbadfid); } @@ -2827,7 +2830,7 @@ NTSTATUS mkdir_internal(connection_struct *conn, pstring directory) unix_convert(directory,conn,0,&bad_path,&sbuf); if (check_name(directory, conn)) - ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory)); + ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory)); if (ret == -1) { NTSTATUS nterr = set_bad_path_error(errno, bad_path); @@ -2898,7 +2901,7 @@ static BOOL recursive_rmdir(connection_struct *conn, char *directory) pstrcat(fullname, "/"); pstrcat(fullname, dname); - if(conn->vfs_ops.lstat(conn,fullname, &st) != 0) { + if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) { ret = True; break; } @@ -2908,11 +2911,11 @@ static BOOL recursive_rmdir(connection_struct *conn, char *directory) ret = True; break; } - if(vfs_rmdir(conn,fullname) != 0) { + if(SMB_VFS_RMDIR(conn,fullname) != 0) { ret = True; break; } - } else if(vfs_unlink(conn,fullname) != 0) { + } else if(SMB_VFS_UNLINK(conn,fullname) != 0) { ret = True; break; } @@ -2929,7 +2932,7 @@ BOOL rmdir_internals(connection_struct *conn, char *directory) { BOOL ok; - ok = (vfs_rmdir(conn,directory) == 0); + ok = (SMB_VFS_RMDIR(conn,directory) == 0); if(!ok && ((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) { /* * Check to see if the only thing in this directory are @@ -2971,21 +2974,21 @@ BOOL rmdir_internals(connection_struct *conn, char *directory) pstrcat(fullname, "/"); pstrcat(fullname, dname); - if(conn->vfs_ops.lstat(conn,fullname, &st) != 0) + if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) break; if(st.st_mode & S_IFDIR) { if(lp_recursive_veto_delete(SNUM(conn))) { if(recursive_rmdir(conn, fullname) != 0) break; } - if(vfs_rmdir(conn,fullname) != 0) + if(SMB_VFS_RMDIR(conn,fullname) != 0) break; - } else if(vfs_unlink(conn,fullname) != 0) + } else if(SMB_VFS_UNLINK(conn,fullname) != 0) break; } CloseDir(dirptr); /* Retry the rmdir */ - ok = (vfs_rmdir(conn,directory) == 0); + ok = (SMB_VFS_RMDIR(conn,directory) == 0); } else { CloseDir(dirptr); } @@ -3104,7 +3107,7 @@ static BOOL resolve_wildcards(const char *name1, char *name2) if (ext2[0]) { snprintf(pname2, available_space - 1, "%s.%s", root2, ext2); } else { - StrnCpy(pname2, root2, available_space - 1); + pstrcpy_base(pname2, root2, name2); } return(True); @@ -3281,7 +3284,7 @@ directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n", return NT_STATUS_OBJECT_NAME_COLLISION; } - if(conn->vfs_ops.rename(conn,directory, newname) == 0) { + if(SMB_VFS_RENAME(conn,directory, newname) == 0) { DEBUG(3,("rename_internals: succeeded doing rename on %s -> %s\n", directory,newname)); return NT_STATUS_OK; @@ -3348,7 +3351,7 @@ directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n", continue; } - if (!conn->vfs_ops.rename(conn,fname,destname)) + if (!SMB_VFS_RENAME(conn,fname,destname)) count++; DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname,destname)); } @@ -3442,7 +3445,7 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun, if (!target_is_directory && count) ofun = FILE_EXISTS_OPEN; - if (vfs_stat(conn,dest,&sbuf2) == -1) + if (SMB_VFS_STAT(conn,dest,&sbuf2) == -1) ZERO_STRUCTP(&sbuf2); fsp2 = open_file_shared(conn,dest,&sbuf2,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY), @@ -3454,7 +3457,7 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun, } if ((ofun&3) == 1) { - if(conn->vfs_ops.lseek(fsp2,fsp2->fd,0,SEEK_END) == -1) { + if(SMB_VFS_LSEEK(fsp2,fsp2->fd,0,SEEK_END) == -1) { DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) )); /* * Stop the copy from occurring. @@ -3938,7 +3941,7 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name)); /* Setup the timeout in seconds. */ - lock_timeout = ((lock_timeout == -1) ? -1 : (lock_timeout+999)/1000); + lock_timeout = ((lock_timeout == -1) ? -1 : (lock_timeout+499)/500); /* Now do any requested locks */ data += ((large_file_format ? 20 : 10)*num_ulocks); @@ -4382,8 +4385,9 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, SIVAL(outbuf,smb_vwv6,0); SIVAL(outbuf,smb_vwv8,0); } else { + uint32 allocation_size = get_allocation_size(fsp, &sbuf); SIVAL(outbuf,smb_vwv6,(uint32)sbuf.st_size); - SIVAL(outbuf,smb_vwv8,SMB_ROUNDUP(sbuf.st_size,1024)); + SIVAL(outbuf,smb_vwv8,allocation_size); } SSVAL(outbuf,smb_vwv10, mode); diff --git a/source/smbd/server.c b/source/smbd/server.c index c24fc5134de..07723cc20e7 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -634,6 +634,12 @@ static BOOL init_structs(void ) main program. ****************************************************************************/ +/* Declare prototype for build_options() to avoid having to run it through + mkproto.h. Mixing $(builddir) and $(srcdir) source files in the current + prototype generation system is too complicated. */ + +void build_options(BOOL screen); + int main(int argc,const char *argv[]) { /* shall I run as a daemon */ @@ -877,10 +883,6 @@ static BOOL init_structs(void ) if (!init_change_notify()) exit(1); - /* Setup privileges database */ - if (!privilege_init()) - exit(1); - /* re-initialise the timezone */ TimeInit(); diff --git a/source/smbd/service.c b/source/smbd/service.c index c9f53305514..31bb343474b 100644 --- a/source/smbd/service.c +++ b/source/smbd/service.c @@ -704,14 +704,12 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, /* Invoke VFS make connection hook */ - if (conn->vfs_ops.connect) { - if (conn->vfs_ops.connect(conn, lp_servicename(snum), user) < 0) { - DEBUG(0,("make_connection: VFS make connection failed!\n")); - change_to_root_user(); - conn_free(conn); - *status = NT_STATUS_UNSUCCESSFUL; - return NULL; - } + if (SMB_VFS_CONNECT(conn, lp_servicename(snum), user) < 0) { + DEBUG(0,("make_connection: VFS make connection failed!\n")); + change_to_root_user(); + conn_free(conn); + *status = NT_STATUS_UNSUCCESSFUL; + return NULL; } /* we've finished with the user stuff - go back to root */ @@ -872,13 +870,8 @@ void close_cnum(connection_struct *conn, uint16 vuid) get_remote_machine_name(),conn->client_address, lp_servicename(SNUM(conn)))); - if (conn->vfs_ops.disconnect != NULL) { - - /* Call VFS disconnect hook */ - - conn->vfs_ops.disconnect(conn); - - } + /* Call VFS disconnect hook */ + SMB_VFS_DISCONNECT(conn); yield_connection(conn, lp_servicename(SNUM(conn))); diff --git a/source/smbd/session.c b/source/smbd/session.c index 07a95042340..b7f3bc43e75 100644 --- a/source/smbd/session.c +++ b/source/smbd/session.c @@ -33,6 +33,8 @@ BOOL session_claim(user_struct *vuser) { int i = 0; TDB_DATA data; + struct sockaddr sa; + struct in_addr *client_ip; struct sessionid sessionid; uint32 pid = (uint32)sys_getpid(); TDB_DATA key; @@ -117,6 +119,8 @@ BOOL session_claim(user_struct *vuser) fstrcpy(sessionid.remote_machine, get_remote_machine_name()); fstrcpy(sessionid.ip_addr, client_addr()); + client_ip = client_inaddr(&sa); + if (!smb_pam_claim_session(sessionid.username, sessionid.id_str, sessionid.hostname)) { DEBUG(1,("pam_session rejected the session for %s [%s]\n", sessionid.username, sessionid.id_str)); @@ -136,6 +140,7 @@ BOOL session_claim(user_struct *vuser) #if WITH_UTMP if (lp_utmp()) { sys_utmp_claim(sessionid.username, sessionid.hostname, + client_ip, sessionid.id_str, sessionid.id_num); } #endif @@ -153,7 +158,8 @@ void session_yield(user_struct *vuser) { TDB_DATA dbuf; struct sessionid sessionid; - TDB_DATA key; + struct in_addr *client_ip; + TDB_DATA key; if (!tdb) return; @@ -171,11 +177,14 @@ void session_yield(user_struct *vuser) memcpy(&sessionid, dbuf.dptr, sizeof(sessionid)); + client_ip = interpret_addr2(sessionid.ip_addr); + SAFE_FREE(dbuf.dptr); #if WITH_UTMP if (lp_utmp()) { sys_utmp_yield(sessionid.username, sessionid.hostname, + client_ip, sessionid.id_str, sessionid.id_num); } #endif diff --git a/source/smbd/statcache.c b/source/smbd/statcache.c index 44bae48990c..79758bcfe2e 100644 --- a/source/smbd/statcache.c +++ b/source/smbd/statcache.c @@ -242,7 +242,7 @@ BOOL stat_cache_lookup(connection_struct *conn, pstring name, pstring dirpath, } else { scp = (stat_cache_entry *)(hash_elem->value); DO_PROFILE_INC(statcache_hits); - if(vfs_stat(conn,scp->translated_path, pst) != 0) { + 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); return False; diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c index de598d67139..2bf250a980f 100644 --- a/source/smbd/trans2.c +++ b/source/smbd/trans2.c @@ -1,7 +1,8 @@ /* Unix SMB/CIFS implementation. SMB transaction2 handling - Copyright (C) Jeremy Allison 1994-2001 + Copyright (C) Jeremy Allison 1994-2001 + Copyright (C) Stefan (metze) Metzmacher 2003 Extensively modified by Andrew Tridgell, 1995 @@ -28,6 +29,7 @@ extern int smb_read_error; extern fstring local_machine; extern int global_oplock_break; extern uint32 global_client_caps; +extern struct current_user current_user; #define get_file_size(sbuf) ((sbuf).st_size) @@ -549,12 +551,12 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, pstrcat(pathreal,dname); if (INFO_LEVEL_IS_UNIX(info_level)) { - if (vfs_lstat(conn,pathreal,&sbuf) != 0) { + if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) { DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n", pathreal,strerror(errno))); continue; } - } else if (vfs_stat(conn,pathreal,&sbuf) != 0) { + } else if (SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) { /* Needed to show the msdfs symlinks as * directories */ @@ -647,8 +649,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, SIVAL(p,l2_cbList,0); /* No extended attributes */ p += l2_achName; nameptr = p; - p += align_string(outbuf, p, 0); - len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE); + len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE | STR_NOALIGN); if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) SCVAL(nameptr, -1, len-2); else @@ -680,14 +681,14 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, pstrcpy(mangled_name, fname); mangle_map(mangled_name,True,True,SNUM(conn)); mangled_name[12] = 0; - len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER); + len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE); SSVAL(p, 0, len); } else { SSVAL(p,0,0); *(p+2) = 0; } p += 2 + 24; - len = srvstr_push(outbuf, p, fname, -1, 0); + len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII); SIVAL(q,0,len); p += len; len = PTR_DIFF(p, pdata); @@ -708,7 +709,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, p += 16; SIVAL(p,0,nt_extmode); p += 4; p += 4; - len = srvstr_push(outbuf, p, fname, -1, 0); + len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII); SIVAL(p, -4, len); p += len; len = PTR_DIFF(p, pdata); @@ -727,13 +728,13 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, SOFF_T(p,0,file_size); SOFF_T(p,8,allocation_size); p += 16; - SIVAL(p,0,nt_extmode); p += 4; + SIVAL(p,0,nt_extmode); p += 4; - SIVAL(p,0,0); p += 4; - len = srvstr_push(outbuf, p, fname, -1, 0); - SIVAL(p, -4, len); - p += len; + SIVAL(p,4,0); /* ea size */ + len = srvstr_push(outbuf, p+8, fname, -1, STR_TERMINATE_ASCII); + SIVAL(p, 0, len); + p += 8 + len; len = PTR_DIFF(p, pdata); len = (len + 3) & ~3; @@ -747,7 +748,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, p += 4; /* this must *not* be null terminated or w2k gets in a loop trying to set an acl on a dir (tridge) */ - len = srvstr_push(outbuf, p, fname, -1, 0); + len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII); SIVAL(p, -4, len); p += len; len = PTR_DIFF(p, pdata); @@ -1318,10 +1319,11 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf char *vname = volume_label(SNUM(conn)); int snum = SNUM(conn); char *fstype = lp_fstype(SNUM(conn)); + int quota_flag = 0; DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level)); - if(vfs_stat(conn,".",&st)!=0) { + if(SMB_VFS_STAT(conn,".",&st)!=0) { DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno))); return ERROR_DOS(ERRSRV,ERRinvdevice); } @@ -1338,7 +1340,7 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf { SMB_BIG_UINT dfree,dsize,bsize; data_len = 18; - conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize); + SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize); SIVAL(pdata,l1_idFileSystem,st.st_dev); SIVAL(pdata,l1_cSectorUnit,bsize/512); SIVAL(pdata,l1_cUnit,dsize); @@ -1357,7 +1359,7 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf * the called hostname and the service name. */ SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) ); - len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_TERMINATE); + len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, 0); SCVAL(pdata,l2_vol_cch,len); data_len = l2_vol_szVolLabel + len; DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n", @@ -1367,19 +1369,26 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf case SMB_QUERY_FS_ATTRIBUTE_INFO: case SMB_FS_ATTRIBUTE_INFORMATION: + +#if defined(HAVE_SYS_QUOTAS) + quota_flag = FILE_VOLUME_QUOTAS; +#endif + SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH| - (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */ + (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)| + quota_flag); /* FS ATTRIBUTES */ + SIVAL(pdata,4,255); /* Max filename component length */ /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it and will think we can't do long filenames */ - len = srvstr_push(outbuf, pdata+12, fstype, -1, 0); + len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_UNICODE); SIVAL(pdata,8,len); data_len = 12 + len; break; case SMB_QUERY_FS_LABEL_INFO: case SMB_FS_LABEL_INFORMATION: - len = srvstr_push(outbuf, pdata+4, vname, -1, STR_TERMINATE); + len = srvstr_push(outbuf, pdata+4, vname, -1, 0); data_len = 4 + len; SIVAL(pdata,0,len); break; @@ -1394,7 +1403,7 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16)); - len = srvstr_push(outbuf, pdata+18, vname, -1, STR_TERMINATE); + len = srvstr_push(outbuf, pdata+18, vname, -1, STR_UNICODE); SIVAL(pdata,12,len); data_len = 18+len; DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n", @@ -1406,7 +1415,7 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf { SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; data_len = 24; - conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize); + SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize); block_size = lp_block_size(snum); if (bsize < block_size) { SMB_BIG_UINT factor = block_size/bsize; @@ -1436,7 +1445,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned { SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; data_len = 32; - conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize); + SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize); block_size = lp_block_size(snum); if (bsize < block_size) { SMB_BIG_UINT factor = block_size/bsize; @@ -1470,6 +1479,78 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned SIVAL(pdata,4,0); /* characteristics */ break; +#ifdef HAVE_SYS_QUOTAS + case SMB_FS_QUOTA_INFORMATION: + /* + * what we have to send --metze: + * + * Unknown1: 24 NULL bytes + * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so + * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so + * Quota Flags: 2 byte : + * Unknown3: 6 NULL bytes + * + * 48 bytes total + * + * details for Quota Flags: + * + * 0x0020 Log Limit: log if the user exceeds his Hard Quota + * 0x0010 Log Warn: log if the user exceeds his Soft Quota + * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota + * 0x0001 Enable Quotas: enable quota for this fs + * + */ + { + /* we need to fake up a fsp here, + * because its not send in this call + */ + files_struct fsp; + SMB_NTQUOTA_STRUCT quotas; + + ZERO_STRUCT(fsp); + ZERO_STRUCT(quotas); + + fsp.conn = conn; + fsp.fnum = -1; + fsp.fd = -1; + + /* access check */ + if (conn->admin_user != True) { + DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n", + lp_servicename(SNUM(conn)),conn->user)); + return ERROR_DOS(ERRDOS,ERRnoaccess); + } + + if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) { + DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn)))); + return ERROR_DOS(ERRSRV,ERRerror); + } + + data_len = 48; + + DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn)))); + + /* Unknown1 24 NULL bytes*/ + SBIG_UINT(pdata,0,(SMB_BIG_UINT)0); + SBIG_UINT(pdata,8,(SMB_BIG_UINT)0); + SBIG_UINT(pdata,16,(SMB_BIG_UINT)0); + + /* Default Soft Quota 8 bytes */ + SBIG_UINT(pdata,24,quotas.softlim); + + /* Default Hard Quota 8 bytes */ + SBIG_UINT(pdata,32,quotas.hardlim); + + /* Quota flag 2 bytes */ + SSVAL(pdata,40,quotas.qflags); + + /* Unknown3 6 NULL bytes */ + SSVAL(pdata,42,0); + SIVAL(pdata,44,0); + + break; + } +#endif /* HAVE_SYS_QUOTAS */ case SMB_FS_OBJECTID_INFORMATION: data_len = 64; break; @@ -1511,6 +1592,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned return -1; } +#ifdef HAVE_SYS_QUOTAS /**************************************************************************** Reply to a TRANS2_SETFSINFO (set filesystem info). ****************************************************************************/ @@ -1519,18 +1601,110 @@ static int call_trans2setfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, char **pparams, int total_params, char **ppdata, int total_data) { - /* Just say yes we did it - there is nothing that - can be set here so it doesn't matter. */ + char *pdata = *ppdata; + char *params = *pparams; + files_struct *fsp = NULL; + uint16 info_level; int outsize; - DEBUG(3,("call_trans2setfsinfo\n")); + SMB_NTQUOTA_STRUCT quotas; + + ZERO_STRUCT(quotas); - if (!CAN_WRITE(conn)) + DEBUG(10,("call_trans2setfsinfo: SET_FS_QUOTA: for service [%s]\n",lp_servicename(SNUM(conn)))); + + /* access check */ + if ((conn->admin_user != True)||!CAN_WRITE(conn)) { + DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n", + lp_servicename(SNUM(conn)),conn->user)); return ERROR_DOS(ERRSRV,ERRaccess); + } + + /* */ + if (total_params < 4) { + DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n", + total_params)); + return ERROR_DOS(ERRDOS,ERRinvalidparam); + } + + fsp = file_fsp(params,0); + + if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) { + DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n")); + return ERROR_NT(NT_STATUS_INVALID_HANDLE); + } + info_level = SVAL(params,2); + + switch(info_level) { + case SMB_FS_QUOTA_INFORMATION: + /* note: normaly there're 48 bytes, + * but we didn't use the last 6 bytes for now + * --metze + */ + if (total_data < 42) { + DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n", + total_data)); + return ERROR_DOS(ERRDOS,ERRunknownlevel); + } + + /* unknown_1 24 NULL bytes in pdata*/ + + /* the soft quotas 8 bytes (SMB_BIG_UINT)*/ + quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24); +#ifdef LARGE_SMB_OFF_T + quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32); +#else /* LARGE_SMB_OFF_T */ + if ((IVAL(pdata,28) != 0)&& + ((quotas.softlim != 0xFFFFFFFF)|| + (IVAL(pdata,28)!=0xFFFFFFFF))) { + /* more than 32 bits? */ + return ERROR_DOS(ERRDOS,ERRunknownlevel); + } +#endif /* LARGE_SMB_OFF_T */ + + /* the hard quotas 8 bytes (SMB_BIG_UINT)*/ + quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32); +#ifdef LARGE_SMB_OFF_T + quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32); +#else /* LARGE_SMB_OFF_T */ + if ((IVAL(pdata,36) != 0)&& + ((quotas.hardlim != 0xFFFFFFFF)|| + (IVAL(pdata,36)!=0xFFFFFFFF))) { + /* more than 32 bits? */ + return ERROR_DOS(ERRDOS,ERRunknownlevel); + } +#endif /* LARGE_SMB_OFF_T */ + + /* quota_flags 2 bytes **/ + quotas.qflags = SVAL(pdata,40); + + /* unknown_2 6 NULL bytes follow*/ + + /* now set the quotas */ + if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) { + DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn)))); + return ERROR_DOS(ERRSRV,ERRerror); + } + + break; + default: + DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n", + info_level)); + return ERROR_DOS(ERRDOS,ERRunknownlevel); + break; + } + + /* + * sending this reply works fine, + * but I'm not sure it's the same + * like windows do... + * --metze + */ outsize = set_message(outbuf,10,0,True); return outsize; } +#endif /* HAVE_SYS_QUOTAS */ /**************************************************************************** * Utility function to set bad path error. @@ -1589,7 +1763,20 @@ static int call_trans2qfilepathinfo(connection_struct *conn, DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level)); - if(fsp && (fsp->is_directory || fsp->fd == -1)) { + if(fsp && (fsp->fake_file_handle)) { + /* + * This is actually for the QUOTA_FAKE_FILE --metze + */ + + pstrcpy(fname, fsp->fsp_name); + unix_convert(fname,conn,0,&bad_path,&sbuf); + if (!check_name(fname,conn)) { + DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed for fake_file(%s)\n",fname,strerror(errno))); + set_bad_path_error(errno, bad_path); + return(UNIXERROR(ERRDOS,ERRbadpath)); + } + + } else if(fsp && (fsp->is_directory || fsp->fd == -1)) { /* * This is actually a QFILEINFO on a directory * handle (returned from an NT SMB). NT5.0 seems @@ -1605,13 +1792,13 @@ static int call_trans2qfilepathinfo(connection_struct *conn, if (INFO_LEVEL_IS_UNIX(info_level)) { /* Always do lstat for UNIX calls. */ - if (vfs_lstat(conn,fname,&sbuf)) { - DEBUG(3,("call_trans2qfilepathinfo: vfs_lstat of %s failed (%s)\n",fname,strerror(errno))); + if (SMB_VFS_LSTAT(conn,fname,&sbuf)) { + DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno))); set_bad_path_error(errno, bad_path); return(UNIXERROR(ERRDOS,ERRbadpath)); } - } else if (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf)) { - DEBUG(3,("call_trans2qfilepathinfo: vfs_stat of %s failed (%s)\n",fname,strerror(errno))); + } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf)) { + DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno))); set_bad_path_error(errno, bad_path); return(UNIXERROR(ERRDOS,ERRbadpath)); } @@ -1624,11 +1811,11 @@ static int call_trans2qfilepathinfo(connection_struct *conn, CHECK_FSP(fsp,conn); pstrcpy(fname, fsp->fsp_name); - if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) { + if (SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) { DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno))); return(UNIXERROR(ERRDOS,ERRbadfid)); } - if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1) + if((pos = SMB_VFS_LSEEK(fsp,fsp->fd,0,SEEK_CUR)) == -1) return(UNIXERROR(ERRDOS,ERRnoaccess)); delete_pending = fsp->delete_on_close; @@ -1655,13 +1842,13 @@ static int call_trans2qfilepathinfo(connection_struct *conn, if (INFO_LEVEL_IS_UNIX(info_level)) { /* Always do lstat for UNIX calls. */ - if (vfs_lstat(conn,fname,&sbuf)) { - DEBUG(3,("call_trans2qfilepathinfo: vfs_lstat of %s failed (%s)\n",fname,strerror(errno))); + if (SMB_VFS_LSTAT(conn,fname,&sbuf)) { + DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno))); set_bad_path_error(errno, bad_path); return(UNIXERROR(ERRDOS,ERRbadpath)); } - } else if (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf)) { - DEBUG(3,("call_trans2qfilepathinfo: vfs_stat of %s failed (%s)\n",fname,strerror(errno))); + } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf)) { + DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno))); set_bad_path_error(errno, bad_path); return(UNIXERROR(ERRDOS,ERRbadpath)); } @@ -1733,9 +1920,17 @@ static int call_trans2qfilepathinfo(connection_struct *conn, SIVAL(pdata,l1_cbFile,(uint32)file_size); SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size); SSVAL(pdata,l1_attrFile,mode); - SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */ + SIVAL(pdata,l1_attrFile+2,0); /* this is what win2003 does */ break; + case SMB_INFO_IS_NAME_VALID: + if (tran_call == TRANSACT2_QFILEINFO) { + /* os/2 needs this ? really ?*/ + return ERROR_DOS(ERRDOS,ERRbadfunc); + } + data_size = 0; + break; + case SMB_INFO_QUERY_EAS_FROM_LIST: data_size = 24; put_dos_date2(pdata,0,c_time); @@ -1748,12 +1943,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn, case SMB_INFO_QUERY_ALL_EAS: data_size = 4; - SIVAL(pdata,0,data_size); + SIVAL(pdata,0,0); /* ea size */ break; - case 6: - return ERROR_DOS(ERRDOS,ERRbadfunc); /* os/2 needs this */ - case SMB_FILE_BASIC_INFORMATION: case SMB_QUERY_FILE_BASIC_INFO: @@ -1836,6 +2028,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, break; case SMB_QUERY_FILE_ALL_INFO: + case SMB_FILE_ALL_INFORMATION: put_long_date(pdata,c_time); put_long_date(pdata+8,sbuf.st_atime); put_long_date(pdata+16,sbuf.st_mtime); /* write time */ @@ -1848,20 +2041,8 @@ static int call_trans2qfilepathinfo(connection_struct *conn, SCVAL(pdata,20,delete_pending); SCVAL(pdata,21,(mode&aDIR)?1:0); pdata += 24; - SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino); - pdata += 8; /* index number */ pdata += 4; /* EA info */ - if (mode & aRONLY) - SIVAL(pdata,0,0xA9); - else - SIVAL(pdata,0,0xd01BF); - pdata += 4; - SOFF_T(pdata,0,pos); /* current offset */ - pdata += 8; - SIVAL(pdata,0,mode); /* is this the right sort of mode info? */ - pdata += 4; - pdata += 4; /* alignment */ - len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_TERMINATE); + len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE); SIVAL(pdata,0,len); pdata += 4 + len; data_size = PTR_DIFF(pdata,(*ppdata)); @@ -1915,28 +2096,6 @@ static int call_trans2qfilepathinfo(connection_struct *conn, break; #if 0 - /* Not yet finished... JRA */ - case 1018: - { - put_long_date(pdata,c_time); - put_long_date(pdata+8,sbuf.st_atime); - put_long_date(pdata+16,sbuf.st_mtime); /* write time */ - put_long_date(pdata+24,sbuf.st_mtime); /* change time */ - SIVAL(pdata,32,mode); - SIVAL(pdata,36,0); /* ??? */ - SIVAL(pdata,40,0x20); /* ??? */ - SIVAL(pdata,44,0); /* ??? */ - SOFF_T(pdata,48,size); - SIVAL(pdata,56,0x1); /* ??? */ - SIVAL(pdata,60,0); /* ??? */ - SIVAL(pdata,64,0); /* ??? */ - SIVAL(pdata,68,length); /* Following string length in bytes. */ - dos_PutUniCode(pdata+72,,False); - break; - } -#endif - -#if 0 /* * NT4 server just returns "invalid query" to this - if we try to answer * it then NTws gets a BSOD! (tridge). @@ -1958,8 +2117,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn, } break; + case SMB_QUERY_COMPRESSION_INFO: case SMB_FILE_COMPRESSION_INFORMATION: - SOFF_T(pdata,0,allocation_size); + SOFF_T(pdata,0,file_size); SIVAL(pdata,8,0); /* ??? */ SIVAL(pdata,12,0); /* ??? */ data_size = 16; @@ -2054,7 +2214,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, #else return(UNIXERROR(ERRDOS,ERRbadlink)); #endif - len = conn->vfs_ops.readlink(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */ + len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */ if (len == -1) return(UNIXERROR(ERRDOS,ERRnoaccess)); buffer[len] = 0; @@ -2178,7 +2338,7 @@ static int ensure_link_is_safe(connection_struct *conn, const char *link_dest_in pstrcpy(link_dest, "./"); } - if (conn->vfs_ops.realpath(conn,link_dest,resolved_name) == NULL) + if (SMB_VFS_REALPATH(conn,link_dest,resolved_name) == NULL) return -1; pstrcpy(link_dest, resolved_name); @@ -2229,7 +2389,13 @@ static int call_trans2setfilepathinfo(connection_struct *conn, gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE; mode_t unixmode = 0; + if (!params) + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + if (tran_call == TRANSACT2_SETFILEINFO) { + if (total_params < 4) + return(ERROR_DOS(ERRDOS,ERRinvalidparam)); + fsp = file_fsp(params,0); info_level = SVAL(params,2); @@ -2269,7 +2435,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, pstrcpy(fname, fsp->fsp_name); fd = fsp->fd; - if (vfs_fstat(fsp,fd,&sbuf) != 0) { + if (SMB_VFS_FSTAT(fsp,fd,&sbuf) != 0) { DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno))); return(UNIXERROR(ERRDOS,ERRbadfid)); } @@ -2461,7 +2627,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, if (new_fsp == NULL) return(UNIXERROR(ERRDOS,ERRbadpath)); ret = vfs_allocate_file_space(new_fsp, allocation_size); - if (vfs_fstat(new_fsp,new_fsp->fd,&new_sbuf) != 0) { + if (SMB_VFS_FSTAT(new_fsp,new_fsp->fd,&new_sbuf) != 0) { DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n", new_fsp->fnum, strerror(errno))); ret = -1; @@ -2469,7 +2635,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, close_file(new_fsp,True); } else { ret = vfs_allocate_file_space(fsp, allocation_size); - if (vfs_fstat(fsp,fd,&new_sbuf) != 0) { + if (SMB_VFS_FSTAT(fsp,fd,&new_sbuf) != 0) { DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno))); ret = -1; @@ -2609,7 +2775,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", 0%o for file %s\n", (double)dev, unixmode, fname )); /* Ok - do the mknod. */ - if (conn->vfs_ops.mknod(conn,dos_to_unix_static(fname), unixmode, dev) != 0) + if (SMB_VFS_MKNOD(conn,dos_to_unix_static(fname), unixmode, dev) != 0) return(UNIXERROR(ERRDOS,ERRnoaccess)); inherit_access_acl(conn, fname, unixmode); @@ -2628,7 +2794,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", if (raw_unixmode != SMB_MODE_NO_CHANGE) { DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n", (unsigned int)unixmode, fname )); - if (vfs_chmod(conn,fname,unixmode) != 0) + if (SMB_VFS_CHMOD(conn,fname,unixmode) != 0) return(UNIXERROR(ERRDOS,ERRnoaccess)); } @@ -2639,7 +2805,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) { DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n", (unsigned int)set_owner, fname )); - if (vfs_chown(conn,fname,set_owner, (gid_t)-1) != 0) + if (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0) return(UNIXERROR(ERRDOS,ERRnoaccess)); } @@ -2650,7 +2816,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) { DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n", (unsigned int)set_owner, fname )); - if (vfs_chown(conn,fname,(uid_t)-1, set_grp) != 0) + if (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0) return(UNIXERROR(ERRDOS,ERRnoaccess)); } break; @@ -2677,7 +2843,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n", fname, link_dest )); - if (conn->vfs_ops.symlink(conn,link_dest,fname) != 0) + if (SMB_VFS_SYMLINK(conn,link_dest,fname) != 0) return(UNIXERROR(ERRDOS,ERRnoaccess)); SSVAL(params,0,0); send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); @@ -2702,7 +2868,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n", fname, link_dest )); - if (conn->vfs_ops.link(conn,link_dest,fname) != 0) + if (SMB_VFS_LINK(conn,link_dest,fname) != 0) return(UNIXERROR(ERRDOS,ERRnoaccess)); SSVAL(params,0,0); send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); @@ -2854,7 +3020,7 @@ static int call_trans2mkdir(connection_struct *conn, unix_convert(directory,conn,0,&bad_path,&sbuf); if (check_name(directory,conn)) - ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory)); + ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory)); if(ret < 0) { DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno))); @@ -3298,13 +3464,14 @@ int reply_trans2(connection_struct *conn, END_PROFILE_NESTED(Trans2_qfsinfo); break; +#ifdef HAVE_SYS_QUOTAS case TRANSACT2_SETFSINFO: START_PROFILE_NESTED(Trans2_setfsinfo); outsize = call_trans2setfsinfo(conn, inbuf, outbuf, length, bufsize, ¶ms, total_params, &data, total_data); END_PROFILE_NESTED(Trans2_setfsinfo); break; - +#endif case TRANSACT2_QPATHINFO: case TRANSACT2_QFILEINFO: START_PROFILE_NESTED(Trans2_qpathinfo); diff --git a/source/smbd/utmp.c b/source/smbd/utmp.c index 6c12cfac626..2c5a1abc824 100644 --- a/source/smbd/utmp.c +++ b/source/smbd/utmp.c @@ -81,11 +81,11 @@ lastlog: Notes: Each connection requires a small number (starting at 0, working up) - to represent the line (unum). This must be unique within and across - all smbd processes. + to represent the line. This must be unique within and across all + smbd processes. It is the 'id_num' from Samba's session.c code. The 4 byte 'ut_id' component is vital to distinguish connections, - of which there could be several hundered or even thousand. + of which there could be several hundred or even thousand. Entries seem to be printable characters, with optional NULL pads. We need to be distinct from other entries in utmp/wtmp. @@ -105,11 +105,8 @@ Notes: Arbitrarily I have chosen to use a distinctive 'SM' for the first two bytes. - The remaining two encode the "unum" (see above). - - For "utmp consolidate" the suggestion was made to encode the pid into - those remaining two bytes (16 bits). But recent UNIX (e.g Solaris 8) - is migrating to pids > 16 bits, so we ought not to do this. + The remaining two bytes encode the session 'id_num' (see above). + Our caller (session.c) should note our 16-bit limitation. ****************************************************************************/ @@ -126,33 +123,6 @@ Notes: #endif /**************************************************************************** - Obtain/release a small number (0 upwards) unique within and across smbds. -****************************************************************************/ -/* - * Need a "small" number to represent this connection, unique within this - * smbd and across all smbds. - * - * claim: - * Start at 0, hunt up for free, unique number "unum" by attempting to - * store it as a key in a tdb database: - * key: unum data: pid+conn - * Also store its inverse, ready for yield function: - * key: pid+conn data: unum - * - * yield: - * Find key: pid+conn; data is unum; delete record - * Find key: unum ; delete record. - * - * Comment: - * The claim algorithm (a "for" loop attempting to store numbers in a tdb - * database) will be increasingly inefficient with larger numbers of - * connections. Is it possible to write a suitable primitive within tdb? - * - * However, by also storing the inverse key/data pair, we at least make - * the yield algorithm efficient. - */ - -/**************************************************************************** Default paths to various {u,w}tmp{,x} files. ****************************************************************************/ @@ -484,6 +454,7 @@ static int ut_id_encode(int i, char *fourbyte) */ static BOOL sys_utmp_fill(struct utmp *u, const char *username, const char *hostname, + struct in_addr *ipaddr, const char *id_str, int id_num) { struct timeval timeval; @@ -503,10 +474,6 @@ static BOOL sys_utmp_fill(struct utmp *u, /* * ut_line: * If size limit proves troublesome, then perhaps use "ut_id_encode()". - * - * Temporary variable "line_tmp" avoids trouble: - * o with unwanted trailing NULL if ut_line full; - * o with overflow if ut_line would be more than full. */ if (strlen(id_str) > sizeof(u->ut_line)) { DEBUG(1,("id_str [%s] is too long for %d char utmp field\n", @@ -538,8 +505,9 @@ static BOOL sys_utmp_fill(struct utmp *u, #if defined(HAVE_UT_UT_HOST) utmp_strcpy(u->ut_host, hostname, sizeof(u->ut_host)); #endif - #if defined(HAVE_UT_UT_ADDR) + if (ipaddr) + u->ut_addr = ipaddr->s_addr; /* * "(unsigned long) ut_addr" apparently exists on at least HP-UX 10.20. * Volunteer to implement, please ... @@ -561,6 +529,7 @@ static BOOL sys_utmp_fill(struct utmp *u, ****************************************************************************/ void sys_utmp_yield(const char *username, const char *hostname, + struct in_addr *ipaddr, const char *id_str, int id_num) { struct utmp u; @@ -576,7 +545,7 @@ void sys_utmp_yield(const char *username, const char *hostname, u.ut_type = DEAD_PROCESS; #endif - if (!sys_utmp_fill(&u, username, hostname, id_str, id_num)) return; + if (!sys_utmp_fill(&u, username, hostname, ipaddr, id_str, id_num)) return; sys_utmp_update(&u, NULL, False); } @@ -586,6 +555,7 @@ void sys_utmp_yield(const char *username, const char *hostname, ****************************************************************************/ void sys_utmp_claim(const char *username, const char *hostname, + struct in_addr *ipaddr, const char *id_str, int id_num) { struct utmp u; @@ -596,7 +566,7 @@ void sys_utmp_claim(const char *username, const char *hostname, u.ut_type = USER_PROCESS; #endif - if (!sys_utmp_fill(&u, username, hostname, id_str, id_num)) return; + if (!sys_utmp_fill(&u, username, hostname, ipaddr, id_str, id_num)) return; sys_utmp_update(&u, hostname, True); } diff --git a/source/smbd/vfs-wrap.c b/source/smbd/vfs-wrap.c index 491fa70e687..8d44a1a0fa1 100644 --- a/source/smbd/vfs-wrap.c +++ b/source/smbd/vfs-wrap.c @@ -30,18 +30,18 @@ is sure to try and execute them. These stubs are used to prevent this possibility. */ -int vfswrap_dummy_connect(connection_struct *conn, const char *service, const char *user) +int vfswrap_dummy_connect(vfs_handle_struct *handle, connection_struct *conn, const char *service, const char *user) { return 0; /* Return >= 0 for success */ } -void vfswrap_dummy_disconnect(connection_struct *conn) +void vfswrap_dummy_disconnect(vfs_handle_struct *handle, connection_struct *conn) { } /* Disk operations */ -SMB_BIG_UINT vfswrap_disk_free(connection_struct *conn, const char *path, BOOL small_query, SMB_BIG_UINT *bsize, +SMB_BIG_UINT vfswrap_disk_free(vfs_handle_struct *handle, connection_struct *conn, const char *path, BOOL small_query, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { SMB_BIG_UINT result; @@ -52,7 +52,7 @@ SMB_BIG_UINT vfswrap_disk_free(connection_struct *conn, const char *path, BOOL s /* Directory operations */ -DIR *vfswrap_opendir(connection_struct *conn, const char *fname) +DIR *vfswrap_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname) { DIR *result; @@ -62,7 +62,7 @@ DIR *vfswrap_opendir(connection_struct *conn, const char *fname) return result; } -struct dirent *vfswrap_readdir(connection_struct *conn, DIR *dirp) +struct dirent *vfswrap_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp) { struct dirent *result; @@ -72,7 +72,7 @@ struct dirent *vfswrap_readdir(connection_struct *conn, DIR *dirp) return result; } -int vfswrap_mkdir(connection_struct *conn, const char *path, mode_t mode) +int vfswrap_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) { int result; BOOL has_dacl = False; @@ -93,17 +93,15 @@ int vfswrap_mkdir(connection_struct *conn, const char *path, mode_t mode) * mess up any inherited ACL bits that were set. JRA. */ int saved_errno = errno; /* We may get ENOSYS */ - if (conn->vfs_ops.chmod_acl != NULL) { - if ((conn->vfs_ops.chmod_acl(conn, path, mode) == -1) && (errno == ENOSYS)) - errno = saved_errno; - } + if ((SMB_VFS_CHMOD_ACL(conn, path, mode) == -1) && (errno == ENOSYS)) + errno = saved_errno; } END_PROFILE(syscall_mkdir); return result; } -int vfswrap_rmdir(connection_struct *conn, const char *path) +int vfswrap_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path) { int result; @@ -113,7 +111,7 @@ int vfswrap_rmdir(connection_struct *conn, const char *path) return result; } -int vfswrap_closedir(connection_struct *conn, DIR *dirp) +int vfswrap_closedir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp) { int result; @@ -125,7 +123,7 @@ int vfswrap_closedir(connection_struct *conn, DIR *dirp) /* File operations */ -int vfswrap_open(connection_struct *conn, const char *fname, int flags, mode_t mode) +int vfswrap_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode) { int result; @@ -135,7 +133,7 @@ int vfswrap_open(connection_struct *conn, const char *fname, int flags, mode_t m return result; } -int vfswrap_close(files_struct *fsp, int fd) +int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp, int fd) { int result; @@ -146,7 +144,7 @@ int vfswrap_close(files_struct *fsp, int fd) return result; } -ssize_t vfswrap_read(files_struct *fsp, int fd, void *data, size_t n) +ssize_t vfswrap_read(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, size_t n) { ssize_t result; @@ -156,7 +154,7 @@ ssize_t vfswrap_read(files_struct *fsp, int fd, void *data, size_t n) return result; } -ssize_t vfswrap_write(files_struct *fsp, int fd, const void *data, size_t n) +ssize_t vfswrap_write(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, size_t n) { ssize_t result; @@ -166,7 +164,7 @@ ssize_t vfswrap_write(files_struct *fsp, int fd, const void *data, size_t n) return result; } -SMB_OFF_T vfswrap_lseek(files_struct *fsp, int filedes, SMB_OFF_T offset, int whence) +SMB_OFF_T vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, int filedes, SMB_OFF_T offset, int whence) { SMB_OFF_T result = 0; @@ -192,7 +190,7 @@ SMB_OFF_T vfswrap_lseek(files_struct *fsp, int filedes, SMB_OFF_T offset, int wh return result; } -ssize_t vfswrap_sendfile(int tofd, struct files_struct *fsp, int fromfd, const DATA_BLOB *hdr, +ssize_t vfswrap_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fsp, int fromfd, const DATA_BLOB *hdr, SMB_OFF_T offset, size_t n) { ssize_t result; @@ -203,7 +201,7 @@ ssize_t vfswrap_sendfile(int tofd, struct files_struct *fsp, int fromfd, const D return result; } -int vfswrap_rename(connection_struct *conn, const char *old, const char *new) +int vfswrap_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new) { int result; @@ -213,7 +211,7 @@ int vfswrap_rename(connection_struct *conn, const char *old, const char *new) return result; } -int vfswrap_fsync(files_struct *fsp, int fd) +int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp, int fd) { #ifdef HAVE_FSYNC int result; @@ -228,7 +226,7 @@ int vfswrap_fsync(files_struct *fsp, int fd) #endif } -int vfswrap_stat(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf) +int vfswrap_stat(vfs_handle_struct *handle, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf) { int result; @@ -238,7 +236,7 @@ int vfswrap_stat(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sb return result; } -int vfswrap_fstat(files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf) +int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf) { int result; @@ -248,7 +246,7 @@ int vfswrap_fstat(files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf) return result; } -int vfswrap_lstat(connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf) +int vfswrap_lstat(vfs_handle_struct *handle, connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf) { int result; @@ -258,7 +256,7 @@ int vfswrap_lstat(connection_struct *conn, const char *path, SMB_STRUCT_STAT *sb return result; } -int vfswrap_unlink(connection_struct *conn, const char *path) +int vfswrap_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path) { int result; @@ -268,7 +266,7 @@ int vfswrap_unlink(connection_struct *conn, const char *path) return result; } -int vfswrap_chmod(connection_struct *conn, const char *path, mode_t mode) +int vfswrap_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) { int result; @@ -281,9 +279,9 @@ int vfswrap_chmod(connection_struct *conn, const char *path, mode_t mode) */ - if (conn->vfs_ops.chmod_acl != NULL) { + { int saved_errno = errno; /* We might get ENOSYS */ - if ((result = conn->vfs_ops.chmod_acl(conn, path, mode)) == 0) { + if ((result = SMB_VFS_CHMOD_ACL(conn, path, mode)) == 0) { END_PROFILE(syscall_chmod); return result; } @@ -296,10 +294,9 @@ int vfswrap_chmod(connection_struct *conn, const char *path, mode_t mode) return result; } -int vfswrap_fchmod(files_struct *fsp, int fd, mode_t mode) +int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode) { int result; - struct vfs_ops *vfs_ops = &fsp->conn->vfs_ops; START_PROFILE(syscall_fchmod); @@ -309,9 +306,9 @@ int vfswrap_fchmod(files_struct *fsp, int fd, mode_t mode) * group owner bits directly. JRA. */ - if (vfs_ops->fchmod_acl != NULL) { + { int saved_errno = errno; /* We might get ENOSYS */ - if ((result = vfs_ops->fchmod_acl(fsp, fd, mode)) == 0) { + if ((result = SMB_VFS_FCHMOD_ACL(fsp, fd, mode)) == 0) { END_PROFILE(syscall_chmod); return result; } @@ -330,7 +327,7 @@ int vfswrap_fchmod(files_struct *fsp, int fd, mode_t mode) return result; } -int vfswrap_chown(connection_struct *conn, const char *path, uid_t uid, gid_t gid) +int vfswrap_chown(vfs_handle_struct *handle, connection_struct *conn, const char *path, uid_t uid, gid_t gid) { int result; @@ -340,7 +337,7 @@ int vfswrap_chown(connection_struct *conn, const char *path, uid_t uid, gid_t gi return result; } -int vfswrap_fchown(files_struct *fsp, int fd, uid_t uid, gid_t gid) +int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, int fd, uid_t uid, gid_t gid) { #ifdef HAVE_FCHOWN int result; @@ -356,7 +353,7 @@ int vfswrap_fchown(files_struct *fsp, int fd, uid_t uid, gid_t gid) #endif } -int vfswrap_chdir(connection_struct *conn, const char *path) +int vfswrap_chdir(vfs_handle_struct *handle, connection_struct *conn, const char *path) { int result; @@ -366,7 +363,7 @@ int vfswrap_chdir(connection_struct *conn, const char *path) return result; } -char *vfswrap_getwd(connection_struct *conn, char *path) +char *vfswrap_getwd(vfs_handle_struct *handle, connection_struct *conn, char *path) { char *result; @@ -376,7 +373,7 @@ char *vfswrap_getwd(connection_struct *conn, char *path) return result; } -int vfswrap_utime(connection_struct *conn, const char *path, struct utimbuf *times) +int vfswrap_utime(vfs_handle_struct *handle, connection_struct *conn, const char *path, struct utimbuf *times) { int result; @@ -391,18 +388,17 @@ int vfswrap_utime(connection_struct *conn, const char *path, struct utimbuf *tim allocate is set. **********************************************************************/ -static int strict_allocate_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len) +static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len) { - struct vfs_ops *vfs_ops = &fsp->conn->vfs_ops; SMB_STRUCT_STAT st; - SMB_OFF_T currpos = vfs_ops->lseek(fsp, fd, 0, SEEK_CUR); + SMB_OFF_T currpos = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR); unsigned char zero_space[4096]; SMB_OFF_T space_to_write; if (currpos == -1) return -1; - if (vfs_ops->fstat(fsp, fd, &st) == -1) + if (SMB_VFS_FSTAT(fsp, fd, &st) == -1) return -1; space_to_write = len - st.st_size; @@ -420,7 +416,7 @@ static int strict_allocate_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len) return sys_ftruncate(fd, len); /* Write out the real space on disk. */ - if (vfs_ops->lseek(fsp, fd, st.st_size, SEEK_SET) != st.st_size) + if (SMB_VFS_LSEEK(fsp, fd, st.st_size, SEEK_SET) != st.st_size) return -1; space_to_write = len - st.st_size; @@ -430,7 +426,7 @@ static int strict_allocate_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len) SMB_OFF_T retlen; SMB_OFF_T current_len_to_write = MIN(sizeof(zero_space),space_to_write); - retlen = vfs_ops->write(fsp,fsp->fd,(char *)zero_space,current_len_to_write); + retlen = SMB_VFS_WRITE(fsp,fsp->fd,(char *)zero_space,current_len_to_write); if (retlen <= 0) return -1; @@ -438,16 +434,15 @@ static int strict_allocate_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len) } /* Seek to where we were */ - if (vfs_ops->lseek(fsp, fd, currpos, SEEK_SET) != currpos) + if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos) return -1; return 0; } -int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len) +int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len) { int result = -1; - struct vfs_ops *vfs_ops = &fsp->conn->vfs_ops; SMB_STRUCT_STAT st; char c = 0; SMB_OFF_T currpos; @@ -455,7 +450,7 @@ int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len) START_PROFILE(syscall_ftruncate); if (lp_strict_allocate(SNUM(fsp->conn))) { - result = strict_allocate_ftruncate(fsp, fd, len); + result = strict_allocate_ftruncate(handle, fsp, fd, len); END_PROFILE(syscall_ftruncate); return result; } @@ -473,7 +468,7 @@ int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len) /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot extend a file with ftruncate. Provide alternate implementation for this */ - currpos = vfs_ops->lseek(fsp, fd, 0, SEEK_CUR); + currpos = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR); if (currpos == -1) { goto done; } @@ -482,7 +477,7 @@ int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len) size in which case the ftruncate above should have succeeded or shorter, in which case seek to len - 1 and write 1 byte of zero */ - if (vfs_ops->fstat(fsp, fd, &st) == -1) { + if (SMB_VFS_FSTAT(fsp, fd, &st) == -1) { goto done; } @@ -503,14 +498,14 @@ int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len) goto done; } - if (vfs_ops->lseek(fsp, fd, len-1, SEEK_SET) != len -1) + if (SMB_VFS_LSEEK(fsp, fd, len-1, SEEK_SET) != len -1) goto done; - if (vfs_ops->write(fsp, fd, &c, 1)!=1) + if (SMB_VFS_WRITE(fsp, fd, &c, 1)!=1) goto done; /* Seek to where we were */ - if (vfs_ops->lseek(fsp, fd, currpos, SEEK_SET) != currpos) + if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos) goto done; result = 0; @@ -520,7 +515,7 @@ int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len) return result; } -BOOL vfswrap_lock(files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type) +BOOL vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type) { BOOL result; @@ -531,7 +526,7 @@ BOOL vfswrap_lock(files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T return result; } -int vfswrap_symlink(connection_struct *conn, const char *oldpath, const char *newpath) +int vfswrap_symlink(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath) { int result; @@ -541,7 +536,7 @@ int vfswrap_symlink(connection_struct *conn, const char *oldpath, const char *ne return result; } -int vfswrap_readlink(connection_struct *conn, const char *path, char *buf, size_t bufsiz) +int vfswrap_readlink(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *buf, size_t bufsiz) { int result; @@ -551,7 +546,7 @@ int vfswrap_readlink(connection_struct *conn, const char *path, char *buf, size_ return result; } -int vfswrap_link(connection_struct *conn, const char *oldpath, const char *newpath) +int vfswrap_link(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath) { int result; @@ -561,7 +556,7 @@ int vfswrap_link(connection_struct *conn, const char *oldpath, const char *newpa return result; } -int vfswrap_mknod(connection_struct *conn, const char *pathname, mode_t mode, SMB_DEV_T dev) +int vfswrap_mknod(vfs_handle_struct *handle, connection_struct *conn, const char *pathname, mode_t mode, SMB_DEV_T dev) { int result; @@ -571,7 +566,7 @@ int vfswrap_mknod(connection_struct *conn, const char *pathname, mode_t mode, SM return result; } -char *vfswrap_realpath(connection_struct *conn, const char *path, char *resolved_path) +char *vfswrap_realpath(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *resolved_path) { char *result; @@ -581,27 +576,27 @@ char *vfswrap_realpath(connection_struct *conn, const char *path, char *resolved return result; } -size_t vfswrap_fget_nt_acl(files_struct *fsp, int fd, SEC_DESC **ppdesc) +size_t vfswrap_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info, SEC_DESC **ppdesc) { size_t result; START_PROFILE(fget_nt_acl); - result = get_nt_acl(fsp, ppdesc); + result = get_nt_acl(fsp, security_info, ppdesc); END_PROFILE(fget_nt_acl); return result; } -size_t vfswrap_get_nt_acl(files_struct *fsp, const char *name, SEC_DESC **ppdesc) +size_t vfswrap_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info, SEC_DESC **ppdesc) { size_t result; START_PROFILE(get_nt_acl); - result = get_nt_acl(fsp, ppdesc); + result = get_nt_acl(fsp, security_info, ppdesc); END_PROFILE(get_nt_acl); return result; } -BOOL vfswrap_fset_nt_acl(files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd) +BOOL vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd) { BOOL result; @@ -611,7 +606,7 @@ BOOL vfswrap_fset_nt_acl(files_struct *fsp, int fd, uint32 security_info_sent, S return result; } -BOOL vfswrap_set_nt_acl(files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd) +BOOL vfswrap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd) { BOOL result; @@ -621,132 +616,236 @@ BOOL vfswrap_set_nt_acl(files_struct *fsp, const char *name, uint32 security_inf return result; } -int vfswrap_chmod_acl(connection_struct *conn, const char *name, mode_t mode) +int vfswrap_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode) { +#ifdef HAVE_NO_ACL + errno = ENOSYS; + return -1; +#else int result; START_PROFILE(chmod_acl); result = chmod_acl(conn, name, mode); END_PROFILE(chmod_acl); return result; +#endif } -int vfswrap_fchmod_acl(files_struct *fsp, int fd, mode_t mode) +int vfswrap_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode) { +#ifdef HAVE_NO_ACL + errno = ENOSYS; + return -1; +#else int result; START_PROFILE(fchmod_acl); result = fchmod_acl(fsp, fd, mode); END_PROFILE(fchmod_acl); return result; +#endif } -int vfswrap_sys_acl_get_entry(struct connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p) +int vfswrap_sys_acl_get_entry(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p) { return sys_acl_get_entry(theacl, entry_id, entry_p); } -int vfswrap_sys_acl_get_tag_type(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p) +int vfswrap_sys_acl_get_tag_type(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p) { return sys_acl_get_tag_type(entry_d, tag_type_p); } -int vfswrap_sys_acl_get_permset(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p) +int vfswrap_sys_acl_get_permset(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p) { return sys_acl_get_permset(entry_d, permset_p); } -void * vfswrap_sys_acl_get_qualifier(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d) +void * vfswrap_sys_acl_get_qualifier(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d) { return sys_acl_get_qualifier(entry_d); } -SMB_ACL_T vfswrap_sys_acl_get_file(struct connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type) +SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle, connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type) { return sys_acl_get_file(path_p, type); } -SMB_ACL_T vfswrap_sys_acl_get_fd(struct files_struct *fsp, int fd) +SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd) { return sys_acl_get_fd(fd); } -int vfswrap_sys_acl_clear_perms(struct connection_struct *conn, SMB_ACL_PERMSET_T permset) +int vfswrap_sys_acl_clear_perms(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset) { return sys_acl_clear_perms(permset); } -int vfswrap_sys_acl_add_perm(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) +int vfswrap_sys_acl_add_perm(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) { return sys_acl_add_perm(permset, perm); } -char * vfswrap_sys_acl_to_text(struct connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen) +char * vfswrap_sys_acl_to_text(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen) { return sys_acl_to_text(theacl, plen); } -SMB_ACL_T vfswrap_sys_acl_init(struct connection_struct *conn, int count) +SMB_ACL_T vfswrap_sys_acl_init(vfs_handle_struct *handle, connection_struct *conn, int count) { return sys_acl_init(count); } -int vfswrap_sys_acl_create_entry(struct connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry) +int vfswrap_sys_acl_create_entry(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry) { return sys_acl_create_entry(pacl, pentry); } -int vfswrap_sys_acl_set_tag_type(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype) +int vfswrap_sys_acl_set_tag_type(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype) { return sys_acl_set_tag_type(entry, tagtype); } -int vfswrap_sys_acl_set_qualifier(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual) +int vfswrap_sys_acl_set_qualifier(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual) { return sys_acl_set_qualifier(entry, qual); } -int vfswrap_sys_acl_set_permset(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset) +int vfswrap_sys_acl_set_permset(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset) { return sys_acl_set_permset(entry, permset); } -int vfswrap_sys_acl_valid(struct connection_struct *conn, SMB_ACL_T theacl ) +int vfswrap_sys_acl_valid(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl ) { return sys_acl_valid(theacl ); } -int vfswrap_sys_acl_set_file(struct connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) +int vfswrap_sys_acl_set_file(vfs_handle_struct *handle, connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) { return sys_acl_set_file(name, acltype, theacl); } -int vfswrap_sys_acl_set_fd(struct files_struct *fsp, int fd, SMB_ACL_T theacl) +int vfswrap_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_ACL_T theacl) { return sys_acl_set_fd(fd, theacl); } -int vfswrap_sys_acl_delete_def_file(struct connection_struct *conn, const char *path) +int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle, connection_struct *conn, const char *path) { return sys_acl_delete_def_file(path); } -int vfswrap_sys_acl_get_perm(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) +int vfswrap_sys_acl_get_perm(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) { return sys_acl_get_perm(permset, perm); } -int vfswrap_sys_acl_free_text(struct connection_struct *conn, char *text) +int vfswrap_sys_acl_free_text(vfs_handle_struct *handle, connection_struct *conn, char *text) { return sys_acl_free_text(text); } -int vfswrap_sys_acl_free_acl(struct connection_struct *conn, SMB_ACL_T posix_acl) +int vfswrap_sys_acl_free_acl(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T posix_acl) { return sys_acl_free_acl(posix_acl); } -int vfswrap_sys_acl_free_qualifier(struct connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype) +int vfswrap_sys_acl_free_qualifier(vfs_handle_struct *handle, connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype) { return sys_acl_free_qualifier(qualifier, tagtype); } + +int vfswrap_get_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt) +{ +#ifdef HAVE_SYS_QUOTAS + int result; + + START_PROFILE(syscall_get_quota); + result = sys_get_quota(conn->connectpath, qtype, id, qt); + END_PROFILE(syscall_get_quota); + return result; +#else + errno = ENOSYS; + return -1; +#endif +} + +int vfswrap_set_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt) +{ +#ifdef HAVE_SYS_QUOTAS + int result; + + START_PROFILE(syscall_set_quota); + result = sys_set_quota(conn->connectpath, qtype, id, qt); + END_PROFILE(syscall_set_quota); + return result; +#else + errno = ENOSYS; + return -1; +#endif +} + +/**************************************************************** + Extended attribute operations. +*****************************************************************/ + +ssize_t vfswrap_getxattr(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size) +{ + return sys_getxattr(path, name, value, size); +} + +ssize_t vfswrap_lgetxattr(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size) +{ + return sys_lgetxattr(path, name, value, size); +} + +ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, void *value, size_t size) +{ + return sys_fgetxattr(fd, name, value, size); +} + +ssize_t vfswrap_listxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size) +{ + return sys_listxattr(path, list, size); +} + +ssize_t vfswrap_llistxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size) +{ + return sys_llistxattr(path, list, size); +} + +ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, char *list, size_t size) +{ + return sys_flistxattr(fd, list, size); +} + +int vfswrap_removexattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name) +{ + return sys_removexattr(path, name); +} + +int vfswrap_lremovexattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name) +{ + return sys_lremovexattr(path, name); +} + +int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name) +{ + return sys_fremovexattr(fd, name); +} + +int vfswrap_setxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags) +{ + return sys_setxattr(path, name, value, size, flags); +} + +int vfswrap_lsetxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags) +{ + return sys_lsetxattr(path, name, value, size, flags); +} + +int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, const void *value, size_t size, int flags) +{ + return sys_fsetxattr(fd, name, value, size, flags); +} diff --git a/source/smbd/vfs.c b/source/smbd/vfs.c index 5fcf9a575e4..5f3abe7efea 100644 --- a/source/smbd/vfs.c +++ b/source/smbd/vfs.c @@ -28,9 +28,9 @@ #define DBGC_CLASS DBGC_VFS struct vfs_init_function_entry { - char *name; - vfs_op_tuple *ops, *(*init)(const struct vfs_ops *, struct smb_vfs_handle_struct *); - struct vfs_init_function_entry *prev, *next; + char *name; + vfs_op_tuple *vfs_op_tuples; + struct vfs_init_function_entry *prev, *next; }; static struct vfs_init_function_entry *backends = NULL; @@ -42,96 +42,106 @@ struct vfs_syminfo { void *fptr; }; -/* - Opaque (final) vfs operations. This is a combination of first-met opaque vfs operations - across all currently processed modules. */ - -static vfs_op_tuple vfs_opaque_ops[SMB_VFS_OP_LAST]; - /* Default vfs hooks. WARNING: The order of these initialisers is very important. They must be in the same order as defined in vfs.h. Change at your own peril. */ -static struct vfs_ops default_vfs_ops = { - - /* Disk operations */ - - vfswrap_dummy_connect, - vfswrap_dummy_disconnect, - vfswrap_disk_free, - - /* Directory operations */ - - vfswrap_opendir, - vfswrap_readdir, - vfswrap_mkdir, - vfswrap_rmdir, - vfswrap_closedir, - - /* File operations */ - - vfswrap_open, - vfswrap_close, - vfswrap_read, - vfswrap_write, - vfswrap_lseek, - vfswrap_sendfile, - vfswrap_rename, - vfswrap_fsync, - vfswrap_stat, - vfswrap_fstat, - vfswrap_lstat, - vfswrap_unlink, - vfswrap_chmod, - vfswrap_fchmod, - vfswrap_chown, - vfswrap_fchown, - vfswrap_chdir, - vfswrap_getwd, - vfswrap_utime, - vfswrap_ftruncate, - vfswrap_lock, - vfswrap_symlink, - vfswrap_readlink, - vfswrap_link, - vfswrap_mknod, - vfswrap_realpath, - - vfswrap_fget_nt_acl, - vfswrap_get_nt_acl, - vfswrap_fset_nt_acl, - vfswrap_set_nt_acl, - - /* POSIX ACL operations. */ -#if defined(HAVE_NO_ACLS) - NULL, - NULL, -#else - vfswrap_chmod_acl, - vfswrap_fchmod_acl, -#endif - vfswrap_sys_acl_get_entry, - vfswrap_sys_acl_get_tag_type, - vfswrap_sys_acl_get_permset, - vfswrap_sys_acl_get_qualifier, - vfswrap_sys_acl_get_file, - vfswrap_sys_acl_get_fd, - vfswrap_sys_acl_clear_perms, - vfswrap_sys_acl_add_perm, - vfswrap_sys_acl_to_text, - vfswrap_sys_acl_init, - vfswrap_sys_acl_create_entry, - vfswrap_sys_acl_set_tag_type, - vfswrap_sys_acl_set_qualifier, - vfswrap_sys_acl_set_permset, - vfswrap_sys_acl_valid, - vfswrap_sys_acl_set_file, - vfswrap_sys_acl_set_fd, - vfswrap_sys_acl_delete_def_file, - vfswrap_sys_acl_get_perm, - vfswrap_sys_acl_free_text, - vfswrap_sys_acl_free_acl, - vfswrap_sys_acl_free_qualifier +static struct vfs_ops default_vfs = { + + { + /* Disk operations */ + + vfswrap_dummy_connect, + vfswrap_dummy_disconnect, + vfswrap_disk_free, + vfswrap_get_quota, + vfswrap_set_quota, + + /* Directory operations */ + + vfswrap_opendir, + vfswrap_readdir, + vfswrap_mkdir, + vfswrap_rmdir, + vfswrap_closedir, + + /* File operations */ + + vfswrap_open, + vfswrap_close, + vfswrap_read, + vfswrap_write, + vfswrap_lseek, + vfswrap_sendfile, + vfswrap_rename, + vfswrap_fsync, + vfswrap_stat, + vfswrap_fstat, + vfswrap_lstat, + vfswrap_unlink, + vfswrap_chmod, + vfswrap_fchmod, + vfswrap_chown, + vfswrap_fchown, + vfswrap_chdir, + vfswrap_getwd, + vfswrap_utime, + vfswrap_ftruncate, + vfswrap_lock, + vfswrap_symlink, + vfswrap_readlink, + vfswrap_link, + vfswrap_mknod, + vfswrap_realpath, + + /* Windows ACL operations. */ + vfswrap_fget_nt_acl, + vfswrap_get_nt_acl, + vfswrap_fset_nt_acl, + vfswrap_set_nt_acl, + + /* POSIX ACL operations. */ + vfswrap_chmod_acl, + vfswrap_fchmod_acl, + + vfswrap_sys_acl_get_entry, + vfswrap_sys_acl_get_tag_type, + vfswrap_sys_acl_get_permset, + vfswrap_sys_acl_get_qualifier, + vfswrap_sys_acl_get_file, + vfswrap_sys_acl_get_fd, + vfswrap_sys_acl_clear_perms, + vfswrap_sys_acl_add_perm, + vfswrap_sys_acl_to_text, + vfswrap_sys_acl_init, + vfswrap_sys_acl_create_entry, + vfswrap_sys_acl_set_tag_type, + vfswrap_sys_acl_set_qualifier, + vfswrap_sys_acl_set_permset, + vfswrap_sys_acl_valid, + vfswrap_sys_acl_set_file, + vfswrap_sys_acl_set_fd, + vfswrap_sys_acl_delete_def_file, + vfswrap_sys_acl_get_perm, + vfswrap_sys_acl_free_text, + vfswrap_sys_acl_free_acl, + vfswrap_sys_acl_free_qualifier, + + /* EA operations. */ + vfswrap_getxattr, + vfswrap_lgetxattr, + vfswrap_fgetxattr, + vfswrap_listxattr, + vfswrap_llistxattr, + vfswrap_flistxattr, + vfswrap_removexattr, + vfswrap_lremovexattr, + vfswrap_fremovexattr, + vfswrap_setxattr, + vfswrap_lsetxattr, + vfswrap_fsetxattr + + } }; /**************************************************************************** @@ -140,52 +150,46 @@ static struct vfs_ops default_vfs_ops = { static struct vfs_init_function_entry *vfs_find_backend_entry(const char *name) { - struct vfs_init_function_entry *entry = backends; - pstring stripped; - - module_path_get_name(name, stripped); - - while(entry) { - if (strequal(entry->name, stripped)) return entry; - entry = entry->next; - } + struct vfs_init_function_entry *entry = backends; + + while(entry) { + if (strcmp(entry->name, name)==0) return entry; + entry = entry->next; + } - return NULL; + return NULL; } -NTSTATUS smb_register_vfs(int version, const char *name, vfs_op_tuple *(*init)(const struct vfs_ops *, struct smb_vfs_handle_struct *)) +NTSTATUS smb_register_vfs(int version, const char *name, vfs_op_tuple *vfs_op_tuples) { - struct vfs_init_function_entry *entry = backends; - - if ((version < SMB_VFS_INTERFACE_CASCADED)) { - DEBUG(0, ("vfs_init() returned wrong interface version info (was %d, should be no less than %d)\n", - version, SMB_VFS_INTERFACE_VERSION )); - return NT_STATUS_OBJECT_TYPE_MISMATCH; - } - - if ((version < SMB_VFS_INTERFACE_VERSION)) { - DEBUG(0, ("Warning: vfs_init() states that module confirms interface version #%d, current interface version is #%d.\n\ - Proceeding in compatibility mode, new operations (since version #%d) will fallback to default ones.\n", - version, SMB_VFS_INTERFACE_VERSION, version )); - return NT_STATUS_OBJECT_TYPE_MISMATCH; - } - - if (!name || !init) { - return NT_STATUS_INVALID_PARAMETER; - } - - if (vfs_find_backend_entry(name)) { - DEBUG(0,("VFS module %s already loaded!\n", name)); - return NT_STATUS_OBJECT_NAME_COLLISION; - } - - entry = smb_xmalloc(sizeof(struct vfs_init_function_entry)); - entry->name = smb_xstrdup(name); - entry->init = init; - - DLIST_ADD(backends, entry); - DEBUG(5, ("Successfully added vfs backend '%s'\n", name)); - return NT_STATUS_OK; + struct vfs_init_function_entry *entry = backends; + + if ((version != SMB_VFS_INTERFACE_VERSION)) { + DEBUG(0, ("Failed to register vfs module.\n" + "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n" + "current SMB_VFS_INTERFACE_VERSION is %d.\n" + "Please recompile against the current Samba Version!\n", + version, SMB_VFS_INTERFACE_VERSION)); + return NT_STATUS_OBJECT_TYPE_MISMATCH; + } + + if (!name || !name[0] || !vfs_op_tuples) { + DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + if (vfs_find_backend_entry(name)) { + DEBUG(0,("VFS module %s already loaded!\n", name)); + return NT_STATUS_OBJECT_NAME_COLLISION; + } + + entry = smb_xmalloc(sizeof(struct vfs_init_function_entry)); + entry->name = smb_xstrdup(name); + entry->vfs_op_tuples = vfs_op_tuples; + + DLIST_ADD(backends, entry); + DEBUG(5, ("Successfully added vfs backend '%s'\n", name)); + return NT_STATUS_OK; } /**************************************************************************** @@ -196,62 +200,10 @@ static void vfs_init_default(connection_struct *conn) { DEBUG(3, ("Initialising default vfs hooks\n")); - memcpy(&conn->vfs_ops, &default_vfs_ops, sizeof(struct vfs_ops)); - conn->vfs_private = NULL; -} - -/*************************************************************************** - Function to load old VFS modules. Should go away after a while. - **************************************************************************/ - -static vfs_op_tuple *vfs_load_old_plugin(connection_struct *conn, const char *vfs_object) -{ - int vfs_version = -1; - vfs_op_tuple *ops, *(*init_fptr)(int *, const struct vfs_ops *, struct smb_vfs_handle_struct *); - /* Open object file */ - - if ((conn->vfs_private->handle = sys_dlopen(vfs_object, RTLD_NOW)) == NULL) { - DEBUG(0, ("Error opening %s: %s\n", vfs_object, sys_dlerror())); - return NULL; - } - - /* Get handle on vfs_init() symbol */ - - init_fptr = (vfs_op_tuple *(*)(int *, const struct vfs_ops *, struct smb_vfs_handle_struct *))sys_dlsym(conn->vfs_private->handle, "vfs_init"); - - if (init_fptr == NULL) { - DEBUG(0, ("No vfs_init() symbol found in %s\n", vfs_object)); - sys_dlclose(conn->vfs_private->handle); - return NULL; - } - - /* Initialise vfs_ops structure */ - if ((ops = init_fptr(&vfs_version, &conn->vfs_ops, conn->vfs_private)) == NULL) { - DEBUG(0, ("vfs_init() function from %s failed\n", vfs_object)); - sys_dlclose(conn->vfs_private->handle); - return NULL; - } - - if ((vfs_version < SMB_VFS_INTERFACE_CASCADED)) { - DEBUG(0, ("vfs_init() returned wrong interface version info (was %d, should be no less than %d)\n", - vfs_version, SMB_VFS_INTERFACE_VERSION )); - sys_dlclose(conn->vfs_private->handle); - return NULL; - } - - if ((vfs_version < SMB_VFS_INTERFACE_VERSION)) { - DEBUG(0, ("Warning: vfs_init() states that module confirms interface version #%d, current interface version is #%d.\n\ - Proceeding in compatibility mode, new operations (since version #%d) will fallback to default ones.\n", - vfs_version, SMB_VFS_INTERFACE_VERSION, vfs_version )); - sys_dlclose(conn->vfs_private->handle); - return NULL; - } - - return ops; + memcpy(&conn->vfs.ops, &default_vfs.ops, sizeof(default_vfs.ops)); + memcpy(&conn->vfs_opaque.ops, &default_vfs.ops, sizeof(default_vfs.ops)); } - - /**************************************************************************** initialise custom vfs hooks ****************************************************************************/ @@ -259,51 +211,82 @@ static vfs_op_tuple *vfs_load_old_plugin(connection_struct *conn, const char *vf BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object) { vfs_op_tuple *ops; + char *module_name = NULL; + char *module_param = NULL, *p; int i; + vfs_handle_struct *handle; struct vfs_init_function_entry *entry; - - DEBUG(3, ("Initialising custom vfs hooks from %s\n", vfs_object)); + + if (!conn||!vfs_object||!vfs_object[0]) { + DEBUG(0,("vfs_init_custon() called with NULL pointer or emtpy vfs_object!\n")); + return False; + } if(!backends) static_init_vfs; + DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object)); + + module_name = smb_xstrdup(vfs_object); + + p = strchr(module_name, ':'); + + if (p) { + *p = 0; + module_param = p+1; + trim_string(module_param, " ", " "); + } + + trim_string(module_name, " ", " "); + /* First, try to load the module with the new module system */ - if((entry = vfs_find_backend_entry(vfs_object)) || - (NT_STATUS_IS_OK(smb_probe_module("vfs", vfs_object)) && - (entry = vfs_find_backend_entry(vfs_object)))) { + if((entry = vfs_find_backend_entry(module_name)) || + (NT_STATUS_IS_OK(smb_probe_module("vfs", module_name)) && + (entry = vfs_find_backend_entry(module_name)))) { - DEBUG(3,("Successfully loaded %s with the new modules system\n", vfs_object)); + DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object)); - if ((ops = entry->init(&conn->vfs_ops, conn->vfs_private)) == NULL) { - DEBUG(0, ("vfs init function from %s failed\n", vfs_object)); - return False; - } + if ((ops = entry->vfs_op_tuples) == NULL) { + DEBUG(0, ("entry->vfs_op_tuples==NULL for [%s] failed\n", vfs_object)); + SAFE_FREE(module_name); + return False; + } } else { - /* If that doesn't work, fall back to the old system - * (This part should go away after a while, it's only here - * for backwards compatibility) */ - DEBUG(2, ("Can't load module %s with new modules system, falling back to compatibility\n", - vfs_object)); - if ((ops = vfs_load_old_plugin(conn, vfs_object)) == NULL) { - DEBUG(0, ("vfs init function from %s failed\n", vfs_object)); - return False; - } + DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object)); + SAFE_FREE(module_name); + return False; + } + + handle = (vfs_handle_struct *)talloc_zero(conn->mem_ctx,sizeof(vfs_handle_struct)); + if (!handle) { + DEBUG(0,("talloc_zero() failed!\n")); + SAFE_FREE(module_name); + return False; } + memcpy(&handle->vfs_next, &conn->vfs, sizeof(struct vfs_ops)); + handle->conn = conn; + if (module_param) { + handle->param = talloc_strdup(conn->mem_ctx, module_param); + } + DLIST_ADD(conn->vfs_handles, handle); for(i=0; ops[i].op != NULL; i++) { - DEBUG(3, ("Checking operation #%d (type %d, layer %d)\n", i, ops[i].type, ops[i].layer)); + DEBUG(5, ("Checking operation #%d (type %d, layer %d)\n", i, ops[i].type, ops[i].layer)); if(ops[i].layer == SMB_VFS_LAYER_OPAQUE) { /* Check whether this operation was already made opaque by different module */ - if(vfs_opaque_ops[ops[i].type].op == ((void**)&default_vfs_ops)[ops[i].type]) { + if(((void**)&conn->vfs_opaque.ops)[ops[i].type] == ((void**)&default_vfs.ops)[ops[i].type]) { /* No, it isn't overloaded yet. Overload. */ - DEBUG(3, ("Making operation type %d opaque [module %s]\n", ops[i].type, vfs_object)); - vfs_opaque_ops[ops[i].type] = ops[i]; + DEBUGADD(5, ("Making operation type %d opaque [module %s]\n", ops[i].type, vfs_object)); + ((void**)&conn->vfs_opaque.ops)[ops[i].type] = ops[i].op; + ((vfs_handle_struct **)&conn->vfs_opaque.handles)[ops[i].type] = handle; } } /* Change current VFS disposition*/ - DEBUG(3, ("Accepting operation type %d from module %s\n", ops[i].type, vfs_object)); - ((void**)&conn->vfs_ops)[ops[i].type] = ops[i].op; + DEBUGADD(5, ("Accepting operation type %d from module %s\n", ops[i].type, vfs_object)); + ((void**)&conn->vfs.ops)[ops[i].type] = ops[i].op; + ((vfs_handle_struct **)&conn->vfs.handles)[ops[i].type] = handle; } + SAFE_FREE(module_name); return True; } @@ -314,71 +297,31 @@ BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object) BOOL smbd_vfs_init(connection_struct *conn) { const char **vfs_objects; - char *vfs_module, *vfs_path; unsigned int i = 0; int j = 0; - struct smb_vfs_handle_struct *handle; /* Normal share - initialise with disk access functions */ vfs_init_default(conn); - vfs_objects = lp_vfsobj(SNUM(conn)); + vfs_objects = lp_vfs_objects(SNUM(conn)); /* Override VFS functions if 'vfs object' was not specified*/ if (!vfs_objects || !vfs_objects[0]) return True; - - for(i=0; i<SMB_VFS_OP_LAST; i++) { - vfs_opaque_ops[i].op = ((void**)&default_vfs_ops)[i]; - vfs_opaque_ops[i].type = i; - vfs_opaque_ops[i].layer = SMB_VFS_LAYER_OPAQUE; + + for (i=0; vfs_objects[i] ;) { + i++; } - vfs_path = lp_vfs_path(SNUM(conn)); - - for (i=0; vfs_objects[i]; i++); /* count passed modules */ - for (j=i-1; j >= 0; j--) { - conn->vfs_private = NULL; - handle = (struct smb_vfs_handle_struct *) smb_xmalloc(sizeof(smb_vfs_handle_struct)); - /* Loadable object file */ - handle->handle = NULL; - DLIST_ADD(conn->vfs_private, handle); - vfs_module = NULL; - if (vfs_path && *vfs_path) { - asprintf(&vfs_module, "%s/%s", vfs_path, vfs_objects[j]); - } else { - asprintf(&vfs_module, "%s", vfs_objects[j]); - } - if (!vfs_init_custom(conn, vfs_module)) { - DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_module)); - SAFE_FREE(vfs_module); - DLIST_REMOVE(conn->vfs_private, handle); - SAFE_FREE(handle); + if (!vfs_init_custom(conn, vfs_objects[j])) { + DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j])); return False; } - SAFE_FREE(vfs_module); } return True; } /******************************************************************* - Create vfs_ops reflecting current vfs_opaque_ops -*******************************************************************/ - -struct vfs_ops *smb_vfs_get_opaque_ops(void) -{ - int i; - struct vfs_ops *ops; - - ops = smb_xmalloc(sizeof(struct vfs_ops)); - - for(i=0; i<SMB_VFS_OP_LAST; i++) { - ((void**)ops)[i] = vfs_opaque_ops[i].op; - } - return ops; -} - -/******************************************************************* Check if directory exists. ********************************************************************/ @@ -390,7 +333,7 @@ BOOL vfs_directory_exist(connection_struct *conn, const char *dname, SMB_STRUCT_ if (!st) st = &st2; - if (vfs_stat(conn,dname,st) != 0) + if (SMB_VFS_STAT(conn,dname,st) != 0) return(False); ret = S_ISDIR(st->st_mode); @@ -401,24 +344,15 @@ BOOL vfs_directory_exist(connection_struct *conn, const char *dname, SMB_STRUCT_ } /******************************************************************* - vfs getwd wrapper -********************************************************************/ - -static char *vfs_getwd(connection_struct *conn, char *path) -{ - return conn->vfs_ops.getwd(conn,path); -} - -/******************************************************************* vfs mkdir wrapper ********************************************************************/ -int vfs_mkdir(connection_struct *conn, const char *name, mode_t mode) +int vfs_MkDir(connection_struct *conn, const char *name, mode_t mode) { int ret; SMB_STRUCT_STAT sbuf; - if(!(ret=conn->vfs_ops.mkdir(conn,name,mode))) { + if(!(ret=SMB_VFS_MKDIR(conn, name, mode))) { inherit_access_acl(conn, name, mode); @@ -428,8 +362,8 @@ int vfs_mkdir(connection_struct *conn, const char *name, mode_t mode) * Consider bits automagically set by UNIX, i.e. SGID bit from parent dir. */ if(mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) && - !vfs_stat(conn,name,&sbuf) && (mode & ~sbuf.st_mode)) - vfs_chmod(conn,name,sbuf.st_mode | (mode & ~sbuf.st_mode)); + !SMB_VFS_STAT(conn,name,&sbuf) && (mode & ~sbuf.st_mode)) + SMB_VFS_CHMOD(conn,name,sbuf.st_mode | (mode & ~sbuf.st_mode)); } return ret; } @@ -447,7 +381,7 @@ BOOL vfs_object_exist(connection_struct *conn,const char *fname,SMB_STRUCT_STAT ZERO_STRUCTP(sbuf); - if (vfs_stat(conn,fname,sbuf) == -1) + if (SMB_VFS_STAT(conn,fname,sbuf) == -1) return(False); return True; } @@ -465,7 +399,7 @@ BOOL vfs_file_exist(connection_struct *conn, const char *fname,SMB_STRUCT_STAT * ZERO_STRUCTP(sbuf); - if (vfs_stat(conn,fname,sbuf) == -1) + if (SMB_VFS_STAT(conn,fname,sbuf) == -1) return False; return(S_ISREG(sbuf->st_mode)); } @@ -480,7 +414,7 @@ ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count) while (total < byte_count) { - ssize_t ret = fsp->conn->vfs_ops.read(fsp, fsp->fd, buf + total, + ssize_t ret = SMB_VFS_READ(fsp, fsp->fd, buf + total, byte_count - total); if (ret == 0) return total; @@ -505,7 +439,7 @@ ssize_t vfs_write_data(files_struct *fsp,const char *buffer,size_t N) ssize_t ret; while (total < N) { - ret = fsp->conn->vfs_ops.write(fsp,fsp->fd,buffer + total,N - total); + ret = SMB_VFS_WRITE(fsp,fsp->fd,buffer + total,N - total); if (ret == -1) return -1; @@ -528,7 +462,6 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len) int ret; SMB_STRUCT_STAT st; connection_struct *conn = fsp->conn; - struct vfs_ops *vfs_ops = &conn->vfs_ops; SMB_BIG_UINT space_avail; SMB_BIG_UINT bsize,dfree,dsize; @@ -545,7 +478,7 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len) return -1; } - ret = vfs_fstat(fsp,fsp->fd,&st); + ret = SMB_VFS_FSTAT(fsp,fsp->fd,&st); if (ret == -1) return ret; @@ -559,7 +492,7 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len) fsp->fsp_name, (double)st.st_size )); flush_write_cache(fsp, SIZECHANGE_FLUSH); - if ((ret = vfs_ops->ftruncate(fsp, fsp->fd, (SMB_OFF_T)len)) != -1) { + if ((ret = SMB_VFS_FTRUNCATE(fsp, fsp->fd, (SMB_OFF_T)len)) != -1) { set_filelen_write_cache(fsp, len); } return ret; @@ -572,7 +505,7 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len) len -= st.st_size; len /= 1024; /* Len is now number of 1k blocks needed. */ - space_avail = conn->vfs_ops.disk_free(conn,fsp->fsp_name,False,&bsize,&dfree,&dsize); + space_avail = SMB_VFS_DISK_FREE(conn,fsp->fsp_name,False,&bsize,&dfree,&dsize); DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, needed blocks = %.0f, space avail = %.0f\n", fsp->fsp_name, (double)st.st_size, (double)len, (double)space_avail )); @@ -598,7 +531,7 @@ int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len) release_level_2_oplocks_on_change(fsp); DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n", fsp->fsp_name, (double)len)); flush_write_cache(fsp, SIZECHANGE_FLUSH); - if ((ret = fsp->conn->vfs_ops.ftruncate(fsp, fsp->fd, len)) != -1) + if ((ret = SMB_VFS_FTRUNCATE(fsp, fsp->fd, len)) != -1) set_filelen_write_cache(fsp, len); return ret; @@ -613,12 +546,12 @@ static files_struct *out_fsp; static ssize_t read_fn(int fd, void *buf, size_t len) { - return in_fsp->conn->vfs_ops.read(in_fsp, fd, buf, len); + return SMB_VFS_READ(in_fsp, fd, buf, len); } static ssize_t write_fn(int fd, const void *buf, size_t len) { - return out_fsp->conn->vfs_ops.write(out_fsp, fd, buf, len); + return SMB_VFS_WRITE(out_fsp, fd, buf, len); } SMB_OFF_T vfs_transfer_file(files_struct *in, files_struct *out, SMB_OFF_T n) @@ -635,13 +568,13 @@ SMB_OFF_T vfs_transfer_file(files_struct *in, files_struct *out, SMB_OFF_T n) char *vfs_readdirname(connection_struct *conn, void *p) { - struct dirent *ptr; + struct dirent *ptr= NULL; char *dname; if (!p) return(NULL); - ptr = (struct dirent *)conn->vfs_ops.readdir(conn,p); + ptr = (struct dirent *)SMB_VFS_READDIR(conn,p); if (!ptr) return(NULL); @@ -660,72 +593,6 @@ char *vfs_readdirname(connection_struct *conn, void *p) return(dname); } -/* VFS options not quite working yet */ - -#if 0 - -/*************************************************************************** - handle the interpretation of the vfs option parameter - *************************************************************************/ -static BOOL handle_vfs_option(char *pszParmValue, char **ptr) -{ - struct vfs_options *new_option, **options = (struct vfs_options **)ptr; - int i; - - /* Create new vfs option */ - - new_option = (struct vfs_options *)malloc(sizeof(*new_option)); - if (new_option == NULL) { - return False; - } - - ZERO_STRUCTP(new_option); - - /* Get name and value */ - - new_option->name = strtok(pszParmValue, "="); - - if (new_option->name == NULL) { - return False; - } - - while(isspace(*new_option->name)) { - new_option->name++; - } - - for (i = strlen(new_option->name); i > 0; i--) { - if (!isspace(new_option->name[i - 1])) break; - } - - new_option->name[i] = '\0'; - new_option->name = strdup(new_option->name); - - new_option->value = strtok(NULL, "="); - - if (new_option->value != NULL) { - - while(isspace(*new_option->value)) { - new_option->value++; - } - - for (i = strlen(new_option->value); i > 0; i--) { - if (!isspace(new_option->value[i - 1])) break; - } - - new_option->value[i] = '\0'; - new_option->value = strdup(new_option->value); - } - - /* Add to list */ - - DLIST_ADD(*options, new_option); - - return True; -} - -#endif - - /******************************************************************* A wrapper for vfs_chdir(). ********************************************************************/ @@ -741,9 +608,9 @@ int vfs_ChDir(connection_struct *conn, const char *path) if (*path == '/' && strcsequal(LastDir,path)) return(0); - DEBUG(3,("vfs_ChDir to %s\n",path)); + DEBUG(4,("vfs_ChDir to %s\n",path)); - res = vfs_chdir(conn,path); + res = SMB_VFS_CHDIR(conn,path); if (!res) pstrcpy(LastDir,path); return(res); @@ -800,7 +667,7 @@ char *vfs_GetWd(connection_struct *conn, char *path) *s = 0; if (!use_getwd_cache) - return(vfs_getwd(conn,path)); + return(SMB_VFS_GETWD(conn,path)); /* init the cache */ if (!getwd_cache_init) { @@ -814,9 +681,9 @@ char *vfs_GetWd(connection_struct *conn, char *path) /* Get the inode of the current directory, if this doesn't work we're in trouble :-) */ - if (vfs_stat(conn, ".",&st) == -1) { + if (SMB_VFS_STAT(conn, ".",&st) == -1) { DEBUG(0,("Very strange, couldn't stat \".\" path=%s\n", path)); - return(vfs_getwd(conn,path)); + return(SMB_VFS_GETWD(conn,path)); } @@ -830,7 +697,7 @@ char *vfs_GetWd(connection_struct *conn, char *path) the same...) */ if (st.st_ino == ino_list[i].inode && st.st_dev == ino_list[i].dev) { - if (vfs_stat(conn,ino_list[i].dos_path,&st2) == 0) { + if (SMB_VFS_STAT(conn,ino_list[i].dos_path,&st2) == 0) { if (st.st_ino == st2.st_ino && st.st_dev == st2.st_dev && (st2.st_mode & S_IFMT) == S_IFDIR) { pstrcpy (path, ino_list[i].dos_path); @@ -852,8 +719,8 @@ char *vfs_GetWd(connection_struct *conn, char *path) The very slow getcwd, which spawns a process on some systems, or the not quite so bad getwd. */ - if (!vfs_getwd(conn,s)) { - DEBUG(0,("vfs_GetWd: vfs_getwd call failed, errno %s\n",strerror(errno))); + if (!SMB_VFS_GETWD(conn,s)) { + DEBUG(0,("vfs_GetWd: SMB_VFS_GETWD call failed, errno %s\n",strerror(errno))); return (NULL); } @@ -909,7 +776,7 @@ static BOOL readlink_check(connection_struct *conn, const char *dir, char *name) realdir[reallen] = 0; } - if (conn->vfs_ops.readlink(conn, name, flink, sizeof(pstring) -1) != -1) { + if (SMB_VFS_READLINK(conn, name, flink, sizeof(pstring) -1) != -1) { DEBUG(3,("reduce_name: file path name %s is a symlink\nChecking it's path\n", name)); if (*flink == '/') { pstrcpy(cleanlink, flink); diff --git a/source/smbwrapper/shared.c b/source/smbwrapper/shared.c index b4cfcf71486..ca8df5841d1 100644 --- a/source/smbwrapper/shared.c +++ b/source/smbwrapper/shared.c @@ -179,8 +179,8 @@ void smbw_setshared(const char *name, const char *val) SSVAL(&variables[shared_size], 0, l1); SSVAL(&variables[shared_size], 2, l2); - pstrcpy(&variables[shared_size] + 4, name); - pstrcpy(&variables[shared_size] + 4 + l1, val); + safe_strcpy(&variables[shared_size] + 4, name, l1-1); + safe_strcpy(&variables[shared_size] + 4 + l1, val, l2-1); shared_size += l1+l2+4; diff --git a/source/smbwrapper/smbw_dir.c b/source/smbwrapper/smbw_dir.c index 31d81a1e7ef..6d55c1d9da2 100644 --- a/source/smbwrapper/smbw_dir.c +++ b/source/smbwrapper/smbw_dir.c @@ -216,7 +216,7 @@ int smbw_dir_open(const char *fname) smbw_NetServerEnum(&srv->cli, srv->server_name, SV_TYPE_ALL, smbw_server_add, NULL); *p = '#'; - } else if (strcmp(srv->cli.dev,"IPC") == 0) { + } else if ((strcmp(srv->cli.dev,"IPC") == 0) || (strcasecmp(share,"IPC$") == 0)) { DEBUG(4,("doing NetShareEnum\n")); smbw_share_add(".",0,"", NULL); smbw_share_add("..",0,"", NULL); @@ -412,7 +412,8 @@ int smbw_chdir(const char *name) goto failed; } - if (strncmp(srv->cli.dev,"IPC",3) && + if (strncmp(srv->cli.dev,"IPC",3) && + strcasecmp(share, "IPC$") && strncmp(srv->cli.dev,"LPT",3) && !smbw_getatr(srv, path, &mode, NULL, NULL, NULL, NULL, NULL)) { diff --git a/source/torture/cmd_vfs.c b/source/torture/cmd_vfs.c index b90c53e9fe3..f74fcedcf49 100644 --- a/source/torture/cmd_vfs.c +++ b/source/torture/cmd_vfs.c @@ -23,37 +23,28 @@ #include "includes.h" #include "vfstest.h" -static char *null_string = ""; +static const char *null_string = ""; -static NTSTATUS cmd_load_module(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_load_module(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - struct smb_vfs_handle_struct *handle; - char *path = lp_vfs_path(0); - char name[PATH_MAX]; + int i; - if (argc != 2) { - printf("Usage: load <module path>\n"); + if (argc < 2) { + printf("Usage: load <modules>\n"); return NT_STATUS_OK; } - if (path != NULL && *path != '\0') { - snprintf(name, PATH_MAX, "%s/%s", path, argv[1]); - } else { - snprintf(name, PATH_MAX, "%s", argv[1]); - } - vfs->conn->vfs_private = NULL; - handle = (struct smb_vfs_handle_struct *) smb_xmalloc(sizeof(smb_vfs_handle_struct)); - handle->handle = NULL; - DLIST_ADD(vfs->conn->vfs_private, handle) - if (!vfs_init_custom(vfs->conn, name)) { - DEBUG(0, ("load: error=-1 (vfs_init_custom failed for %s)\n", argv[1])); - return NT_STATUS_UNSUCCESSFUL; + for (i=argc-1;i>0;i--) { + if (!vfs_init_custom(vfs->conn, argv[i])) { + DEBUG(0, ("load: (vfs_init_custom failed for %s)\n", argv[i])); + return NT_STATUS_UNSUCCESSFUL; + } } printf("load: ok\n"); return NT_STATUS_OK; } -static NTSTATUS cmd_populate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_populate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { char c; size_t size; @@ -73,7 +64,7 @@ static NTSTATUS cmd_populate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg return NT_STATUS_OK; } -static NTSTATUS cmd_show_data(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_show_data(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { size_t offset; size_t len; @@ -101,19 +92,19 @@ static NTSTATUS cmd_show_data(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int ar return NT_STATUS_OK; } -static NTSTATUS cmd_connect(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_connect(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - vfs->conn->vfs_ops.connect(vfs->conn, lp_servicename(vfs->conn->service), "vfstest"); + SMB_VFS_CONNECT(vfs->conn, lp_servicename(vfs->conn->service), "vfstest"); return NT_STATUS_OK; } -static NTSTATUS cmd_disconnect(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_disconnect(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - vfs->conn->vfs_ops.disconnect(vfs->conn); + SMB_VFS_DISCONNECT(vfs->conn); return NT_STATUS_OK; } -static NTSTATUS cmd_disk_free(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_disk_free(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { SMB_BIG_UINT diskfree, bsize, dfree, dsize; if (argc != 2) { @@ -121,7 +112,7 @@ static NTSTATUS cmd_disk_free(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int ar return NT_STATUS_OK; } - diskfree = vfs->conn->vfs_ops.disk_free(vfs->conn, argv[1], False, &bsize, &dfree, &dsize); + diskfree = SMB_VFS_DISK_FREE(vfs->conn, argv[1], False, &bsize, &dfree, &dsize); printf("disk_free: %lu, bsize = %lu, dfree = %lu, dsize = %lu\n", (unsigned long)diskfree, (unsigned long)bsize, @@ -131,14 +122,14 @@ static NTSTATUS cmd_disk_free(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int ar } -static NTSTATUS cmd_opendir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_opendir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { if (argc != 2) { printf("Usage: opendir <fname>\n"); return NT_STATUS_OK; } - vfs->currentdir = vfs->conn->vfs_ops.opendir(vfs->conn, argv[1]); + vfs->currentdir = SMB_VFS_OPENDIR(vfs->conn, argv[1]); if (vfs->currentdir == NULL) { printf("opendir error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; @@ -149,7 +140,7 @@ static NTSTATUS cmd_opendir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc } -static NTSTATUS cmd_readdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_readdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { struct dirent *dent; @@ -158,7 +149,7 @@ static NTSTATUS cmd_readdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc return NT_STATUS_UNSUCCESSFUL; } - dent = vfs->conn->vfs_ops.readdir(vfs->conn, vfs->currentdir); + dent = SMB_VFS_READDIR(vfs->conn, vfs->currentdir); if (dent == NULL) { printf("readdir: NULL\n"); return NT_STATUS_OK; @@ -169,14 +160,14 @@ static NTSTATUS cmd_readdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc } -static NTSTATUS cmd_mkdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_mkdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { if (argc != 2) { printf("Usage: mkdir <path>\n"); return NT_STATUS_OK; } - if (vfs->conn->vfs_ops.mkdir(vfs->conn, argv[1], 00755) == -1) { + if (SMB_VFS_MKDIR(vfs->conn, argv[1], 00755) == -1) { printf("mkdir error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } @@ -186,7 +177,7 @@ static NTSTATUS cmd_mkdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, } -static NTSTATUS cmd_closedir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_closedir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { int ret; @@ -195,7 +186,7 @@ static NTSTATUS cmd_closedir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg return NT_STATUS_UNSUCCESSFUL; } - ret = vfs->conn->vfs_ops.closedir(vfs->conn, vfs->currentdir); + ret = SMB_VFS_CLOSEDIR(vfs->conn, vfs->currentdir); if (ret == -1) { printf("closedir failure: %s\n", strerror(errno)); return NT_STATUS_UNSUCCESSFUL; @@ -207,11 +198,11 @@ static NTSTATUS cmd_closedir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg } -static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { int flags, fd; mode_t mode; - char *flagstr; + const char *flagstr; mode = 00400; @@ -287,7 +278,7 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c } } - fd = vfs->conn->vfs_ops.open(vfs->conn, argv[1], flags, mode); + fd = SMB_VFS_OPEN(vfs->conn, argv[1], flags, mode); if (fd == -1) { printf("open: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; @@ -302,7 +293,7 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c } -static NTSTATUS cmd_pathfunc(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_pathfunc(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { int ret = -1; @@ -312,11 +303,11 @@ static NTSTATUS cmd_pathfunc(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg } if (strcmp("rmdir", argv[0]) == 0 ) { - ret = vfs->conn->vfs_ops.rmdir(vfs->conn, argv[1]); + ret = SMB_VFS_RMDIR(vfs->conn, argv[1]); } else if (strcmp("unlink", argv[0]) == 0 ) { - ret = vfs->conn->vfs_ops.unlink(vfs->conn, argv[1]); + ret = SMB_VFS_UNLINK(vfs->conn, argv[1]); } else if (strcmp("chdir", argv[0]) == 0 ) { - ret = vfs->conn->vfs_ops.chdir(vfs->conn, argv[1]); + ret = SMB_VFS_CHDIR(vfs->conn, argv[1]); } else { printf("%s: error=%d (invalid function name!)\n", argv[0], errno); return NT_STATUS_UNSUCCESSFUL; @@ -332,7 +323,7 @@ static NTSTATUS cmd_pathfunc(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg } -static NTSTATUS cmd_close(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_close(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { int fd, ret; @@ -347,7 +338,7 @@ static NTSTATUS cmd_close(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, return NT_STATUS_OK; } - ret = vfs->conn->vfs_ops.close(vfs->files[fd], fd); + ret = SMB_VFS_CLOSE(vfs->files[fd], fd); if (ret == -1 ) printf("close: error=%d (%s)\n", errno, strerror(errno)); else @@ -360,7 +351,7 @@ static NTSTATUS cmd_close(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, } -static NTSTATUS cmd_read(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_read(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { int fd; size_t size, rsize; @@ -380,7 +371,7 @@ static NTSTATUS cmd_read(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c } vfs->data_size = size; - rsize = vfs->conn->vfs_ops.read(vfs->files[fd], fd, vfs->data, size); + rsize = SMB_VFS_READ(vfs->files[fd], fd, vfs->data, size); if (rsize == -1) { printf("read: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; @@ -391,7 +382,7 @@ static NTSTATUS cmd_read(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c } -static NTSTATUS cmd_write(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_write(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { int fd, size, wsize; @@ -413,7 +404,7 @@ static NTSTATUS cmd_write(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, return NT_STATUS_UNSUCCESSFUL; } - wsize = vfs->conn->vfs_ops.write(vfs->files[fd], fd, vfs->data, size); + wsize = SMB_VFS_WRITE(vfs->files[fd], fd, vfs->data, size); if (wsize == -1) { printf("write: error=%d (%s)\n", errno, strerror(errno)); @@ -425,7 +416,7 @@ static NTSTATUS cmd_write(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, } -static NTSTATUS cmd_lseek(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_lseek(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { int fd, offset, whence; SMB_OFF_T pos; @@ -444,7 +435,7 @@ static NTSTATUS cmd_lseek(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, default: whence = SEEK_END; } - pos = vfs->conn->vfs_ops.lseek(vfs->files[fd], fd, offset, whence); + pos = SMB_VFS_LSEEK(vfs->files[fd], fd, offset, whence); if (pos == (SMB_OFF_T)-1) { printf("lseek: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; @@ -455,7 +446,7 @@ static NTSTATUS cmd_lseek(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, } -static NTSTATUS cmd_rename(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_rename(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { int ret; if (argc != 3) { @@ -463,7 +454,7 @@ static NTSTATUS cmd_rename(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, return NT_STATUS_OK; } - ret = vfs->conn->vfs_ops.rename(vfs->conn, argv[1], argv[2]); + ret = SMB_VFS_RENAME(vfs->conn, argv[1], argv[2]); if (ret == -1) { printf("rename: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; @@ -474,7 +465,7 @@ static NTSTATUS cmd_rename(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, } -static NTSTATUS cmd_fsync(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_fsync(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { int ret, fd; if (argc != 2) { @@ -483,7 +474,7 @@ static NTSTATUS cmd_fsync(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, } fd = atoi(argv[1]); - ret = vfs->conn->vfs_ops.fsync(vfs->files[fd], fd); + ret = SMB_VFS_FSYNC(vfs->files[fd], fd); if (ret == -1) { printf("fsync: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; @@ -494,11 +485,11 @@ static NTSTATUS cmd_fsync(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, } -static NTSTATUS cmd_stat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_stat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { int ret; - char *user; - char *group; + const char *user; + const char *group; struct passwd *pwd; struct group *grp; SMB_STRUCT_STAT st; @@ -508,17 +499,17 @@ static NTSTATUS cmd_stat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c return NT_STATUS_OK; } - ret = vfs->conn->vfs_ops.stat(vfs->conn, argv[1], &st); + ret = SMB_VFS_STAT(vfs->conn, argv[1], &st); if (ret == -1) { printf("stat: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } pwd = sys_getpwuid(st.st_uid); - if (pwd != NULL) user = strdup(pwd->pw_name); + if (pwd != NULL) user = pwd->pw_name; else user = null_string; grp = sys_getgrgid(st.st_gid); - if (grp != NULL) group = strdup(grp->gr_name); + if (grp != NULL) group = grp->gr_name; else group = null_string; printf("stat: ok\n"); @@ -541,17 +532,17 @@ static NTSTATUS cmd_stat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c printf(" Access: %s", ctime(&(st.st_atime))); printf(" Modify: %s", ctime(&(st.st_mtime))); printf(" Change: %s", ctime(&(st.st_ctime))); - if (user != null_string) SAFE_FREE(user); - if (group!= null_string) SAFE_FREE(group); + SAFE_FREE(pwd); + SAFE_FREE(grp); return NT_STATUS_OK; } -static NTSTATUS cmd_fstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_fstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { int fd; - char *user; - char *group; + const char *user; + const char *group; struct passwd *pwd; struct group *grp; SMB_STRUCT_STAT st; @@ -572,16 +563,16 @@ static NTSTATUS cmd_fstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, return NT_STATUS_OK; } - if (vfs->conn->vfs_ops.fstat(vfs->files[fd], fd, &st) == -1) { + if (SMB_VFS_FSTAT(vfs->files[fd], fd, &st) == -1) { printf("fstat: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } pwd = sys_getpwuid(st.st_uid); - if (pwd != NULL) user = strdup(pwd->pw_name); + if (pwd != NULL) user = pwd->pw_name; else user = null_string; grp = sys_getgrgid(st.st_gid); - if (grp != NULL) group = strdup(grp->gr_name); + if (grp != NULL) group = grp->gr_name; else group = null_string; printf("fstat: ok\n"); @@ -603,16 +594,16 @@ static NTSTATUS cmd_fstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, printf(" Access: %s", ctime(&(st.st_atime))); printf(" Modify: %s", ctime(&(st.st_mtime))); printf(" Change: %s", ctime(&(st.st_ctime))); - if (user != null_string) SAFE_FREE(user); - if (group!= null_string) SAFE_FREE(group); + SAFE_FREE(pwd); + SAFE_FREE(grp); return NT_STATUS_OK; } -static NTSTATUS cmd_lstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_lstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - char *user; - char *group; + const char *user; + const char *group; struct passwd *pwd; struct group *grp; SMB_STRUCT_STAT st; @@ -622,16 +613,16 @@ static NTSTATUS cmd_lstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, return NT_STATUS_OK; } - if (vfs->conn->vfs_ops.lstat(vfs->conn, argv[1], &st) == -1) { + if (SMB_VFS_LSTAT(vfs->conn, argv[1], &st) == -1) { printf("lstat: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } pwd = sys_getpwuid(st.st_uid); - if (pwd != NULL) user = strdup(pwd->pw_name); + if (pwd != NULL) user = pwd->pw_name; else user = null_string; grp = sys_getgrgid(st.st_gid); - if (grp != NULL) group = strdup(grp->gr_name); + if (grp != NULL) group = grp->gr_name; else group = null_string; printf("lstat: ok\n"); @@ -653,13 +644,13 @@ static NTSTATUS cmd_lstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, printf(" Access: %s", ctime(&(st.st_atime))); printf(" Modify: %s", ctime(&(st.st_mtime))); printf(" Change: %s", ctime(&(st.st_ctime))); - if (user != null_string) SAFE_FREE(user); - if (group!= null_string) SAFE_FREE(group); + SAFE_FREE(pwd); + SAFE_FREE(grp); return NT_STATUS_OK; } -static NTSTATUS cmd_chmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_chmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { mode_t mode; if (argc != 3) { @@ -668,7 +659,7 @@ static NTSTATUS cmd_chmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, } mode = atoi(argv[2]); - if (vfs->conn->vfs_ops.chmod(vfs->conn, argv[1], mode) == -1) { + if (SMB_VFS_CHMOD(vfs->conn, argv[1], mode) == -1) { printf("chmod: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } @@ -678,7 +669,7 @@ static NTSTATUS cmd_chmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, } -static NTSTATUS cmd_fchmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_fchmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { int fd; mode_t mode; @@ -698,7 +689,7 @@ static NTSTATUS cmd_fchmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, return NT_STATUS_OK; } - if (vfs->conn->vfs_ops.fchmod(vfs->files[fd], fd, mode) == -1) { + if (SMB_VFS_FCHMOD(vfs->files[fd], fd, mode) == -1) { printf("fchmod: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } @@ -708,7 +699,7 @@ static NTSTATUS cmd_fchmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, } -static NTSTATUS cmd_chown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_chown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { uid_t uid; gid_t gid; @@ -719,7 +710,7 @@ static NTSTATUS cmd_chown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, uid = atoi(argv[2]); gid = atoi(argv[3]); - if (vfs->conn->vfs_ops.chown(vfs->conn, argv[1], uid, gid) == -1) { + if (SMB_VFS_CHOWN(vfs->conn, argv[1], uid, gid) == -1) { printf("chown: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } @@ -729,7 +720,7 @@ static NTSTATUS cmd_chown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, } -static NTSTATUS cmd_fchown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_fchown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { uid_t uid; gid_t gid; @@ -750,7 +741,7 @@ static NTSTATUS cmd_fchown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, printf("fchown: error=%d (invalid file descriptor)\n", EBADF); return NT_STATUS_OK; } - if (vfs->conn->vfs_ops.fchown(vfs->files[fd], fd, uid, gid) == -1) { + if (SMB_VFS_FCHOWN(vfs->files[fd], fd, uid, gid) == -1) { printf("fchown error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } @@ -760,10 +751,10 @@ static NTSTATUS cmd_fchown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, } -static NTSTATUS cmd_getwd(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_getwd(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { char buf[PATH_MAX]; - if (vfs->conn->vfs_ops.getwd(vfs->conn, buf) == NULL) { + if (SMB_VFS_GETWD(vfs->conn, buf) == NULL) { printf("getwd: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } @@ -772,7 +763,7 @@ static NTSTATUS cmd_getwd(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, return NT_STATUS_OK; } -static NTSTATUS cmd_utime(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_utime(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { struct utimbuf times; if (argc != 4) { @@ -781,7 +772,7 @@ static NTSTATUS cmd_utime(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, } times.actime = atoi(argv[2]); times.modtime = atoi(argv[3]); - if (vfs->conn->vfs_ops.utime(vfs->conn, argv[1], ×) != 0) { + if (SMB_VFS_UTIME(vfs->conn, argv[1], ×) != 0) { printf("utime: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } @@ -790,7 +781,7 @@ static NTSTATUS cmd_utime(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, return NT_STATUS_OK; } -static NTSTATUS cmd_ftruncate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_ftruncate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { int fd; SMB_OFF_T off; @@ -810,7 +801,7 @@ static NTSTATUS cmd_ftruncate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int ar return NT_STATUS_OK; } - if (vfs->conn->vfs_ops.ftruncate(vfs->files[fd], fd, off) == -1) { + if (SMB_VFS_FTRUNCATE(vfs->files[fd], fd, off) == -1) { printf("ftruncate: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } @@ -819,7 +810,7 @@ static NTSTATUS cmd_ftruncate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int ar return NT_STATUS_OK; } -static NTSTATUS cmd_lock(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_lock(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { BOOL ret; int fd; @@ -827,7 +818,7 @@ static NTSTATUS cmd_lock(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c long offset; long count; int type; - char *typestr; + const char *typestr; if (argc != 6) { printf("Usage: lock <fd> <op> <offset> <count> <type>\n"); @@ -893,7 +884,7 @@ static NTSTATUS cmd_lock(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c printf("lock: debug lock(fd=%d, op=%d, offset=%ld, count=%ld, type=%d))\n", fd, op, offset, count, type); - if ((ret = vfs->conn->vfs_ops.lock(vfs->files[fd], fd, op, offset, count, type)) == False) { + if ((ret = SMB_VFS_LOCK(vfs->files[fd], fd, op, offset, count, type)) == False) { printf("lock: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } @@ -902,14 +893,14 @@ static NTSTATUS cmd_lock(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c return NT_STATUS_OK; } -static NTSTATUS cmd_symlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_symlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { if (argc != 3) { printf("Usage: symlink <path> <link>\n"); return NT_STATUS_OK; } - if (vfs->conn->vfs_ops.symlink(vfs->conn, argv[1], argv[2]) == -1) { + if (SMB_VFS_SYMLINK(vfs->conn, argv[1], argv[2]) == -1) { printf("symlink: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } @@ -919,7 +910,7 @@ static NTSTATUS cmd_symlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc } -static NTSTATUS cmd_readlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_readlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { char buffer[PATH_MAX]; int size; @@ -929,7 +920,7 @@ static NTSTATUS cmd_readlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg return NT_STATUS_OK; } - if ((size = vfs->conn->vfs_ops.readlink(vfs->conn, argv[1], buffer, PATH_MAX)) == -1) { + if ((size = SMB_VFS_READLINK(vfs->conn, argv[1], buffer, PATH_MAX)) == -1) { printf("readlink: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } @@ -940,14 +931,14 @@ static NTSTATUS cmd_readlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg } -static NTSTATUS cmd_link(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_link(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { if (argc != 3) { printf("Usage: link <path> <link>\n"); return NT_STATUS_OK; } - if (vfs->conn->vfs_ops.link(vfs->conn, argv[1], argv[2]) == -1) { + if (SMB_VFS_LINK(vfs->conn, argv[1], argv[2]) == -1) { printf("link: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } @@ -956,7 +947,7 @@ static NTSTATUS cmd_link(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c return NT_STATUS_OK; } -static NTSTATUS cmd_mknod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_mknod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { mode_t mode; unsigned int dev_val; @@ -980,7 +971,7 @@ static NTSTATUS cmd_mknod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, } dev = (SMB_DEV_T)dev_val; - if (vfs->conn->vfs_ops.mknod(vfs->conn, argv[1], mode, dev) == -1) { + if (SMB_VFS_MKNOD(vfs->conn, argv[1], mode, dev) == -1) { printf("mknod: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } @@ -989,7 +980,7 @@ static NTSTATUS cmd_mknod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, return NT_STATUS_OK; } -static NTSTATUS cmd_realpath(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_realpath(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { char respath[PATH_MAX]; @@ -998,7 +989,7 @@ static NTSTATUS cmd_realpath(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg return NT_STATUS_OK; } - if (vfs->conn->vfs_ops.realpath(vfs->conn, argv[1], respath) == NULL) { + if (SMB_VFS_REALPATH(vfs->conn, argv[1], respath) == NULL) { printf("realpath: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } diff --git a/source/torture/vfstest.c b/source/torture/vfstest.c index 3b28a3c496b..88fe3486493 100644 --- a/source/torture/vfstest.c +++ b/source/torture/vfstest.c @@ -106,7 +106,7 @@ static char* next_command(char** cmdstr) /* Load specified configuration file */ static NTSTATUS cmd_conf(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, - int argc, char **argv) + int argc, const char **argv) { if (argc != 2) { printf("Usage: %s <smb.conf>\n", argv[0]); @@ -181,7 +181,7 @@ static NTSTATUS cmd_help(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, } /* Change the debug level */ -static NTSTATUS cmd_debuglevel(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_debuglevel(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { if (argc > 2) { printf("Usage: %s [debuglevel]\n", argv[0]); @@ -197,7 +197,7 @@ static NTSTATUS cmd_debuglevel(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int a return NT_STATUS_OK; } -static NTSTATUS cmd_freemem(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_freemem(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { /* Cleanup */ talloc_destroy(mem_ctx); @@ -207,7 +207,7 @@ static NTSTATUS cmd_freemem(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc return NT_STATUS_OK; } -static NTSTATUS cmd_quit(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv) +static NTSTATUS cmd_quit(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { /* Cleanup */ talloc_destroy(mem_ctx); @@ -261,7 +261,8 @@ static void add_command_set(struct cmd_set *cmd_set) static NTSTATUS do_cmd(struct vfs_state *vfs, struct cmd_set *cmd_entry, char *cmd) { - char *p = cmd, **argv = NULL; + const char *p = cmd; + char **argv = NULL; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; pstring buf; TALLOC_CTX *mem_ctx = NULL; @@ -311,7 +312,7 @@ static NTSTATUS do_cmd(struct vfs_state *vfs, struct cmd_set *cmd_entry, char *c } /* Run command */ - result = cmd_entry->fn(vfs, mem_ctx, argc, argv); + result = cmd_entry->fn(vfs, mem_ctx, argc, (const char **)argv); } else { fprintf (stderr, "Invalid command\n"); @@ -338,7 +339,7 @@ static NTSTATUS process_cmd(struct vfs_state *vfs, char *cmd) struct cmd_list *temp_list; BOOL found = False; pstring buf; - char *p = cmd; + const char *p = cmd; NTSTATUS result = NT_STATUS_OK; int len = 0; @@ -478,7 +479,7 @@ int main(int argc, char *argv[]) struct cmd_set **cmd_set; static struct vfs_state vfs; int i; - static const char *filename = NULL; + static char *filename = NULL; /* make sure the vars that get altered (4th field) are in a fixed location or certain compilers complain */ @@ -520,9 +521,10 @@ int main(int argc, char *argv[]) } /* some basic initialization stuff */ + sec_init(); conn_init(); vfs.conn = conn_new(); - vfs.conn->user = "vfstest"; + string_set(&vfs.conn->user,"vfstest"); for (i=0; i < 1024; i++) vfs.files[i] = NULL; diff --git a/source/torture/vfstest.h b/source/torture/vfstest.h index 5910c5ce37b..1e030fad047 100644 --- a/source/torture/vfstest.h +++ b/source/torture/vfstest.h @@ -39,7 +39,7 @@ struct vfs_state { struct cmd_set { const char *name; NTSTATUS (*fn)(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, - char **argv); + const char **argv); const char *description; const char *usage; }; diff --git a/source/utils/editreg.c b/source/utils/editreg.c index 54148fdcf8e..92a39c39e2a 100644 --- a/source/utils/editreg.c +++ b/source/utils/editreg.c @@ -412,16 +412,16 @@ typedef struct val_list_s { #define MAXSUBAUTHS 15 #endif -typedef struct sid_s { +typedef struct dom_sid_s { unsigned char ver, auths; unsigned char auth[6]; unsigned int sub_auths[MAXSUBAUTHS]; -} sid_t; +} DOM_SID; typedef struct ace_struct_s { unsigned char type, flags; unsigned int perms; /* Perhaps a better def is in order */ - sid_t *trustee; + DOM_SID *trustee; } ACE; typedef struct acl_struct_s { @@ -432,7 +432,7 @@ typedef struct acl_struct_s { typedef struct sec_desc_s { unsigned int rev, type; - sid_t *owner, *group; + DOM_SID *owner, *group; ACL *sacl, *dacl; } SEC_DESC; @@ -537,7 +537,7 @@ typedef struct ace_struct { unsigned char flags; unsigned short length; unsigned int perms; - sid_t trustee; + DOM_SID trustee; } REG_ACE; typedef struct acl_struct { @@ -904,7 +904,7 @@ int nt_delete_key_by_name(REGF *regf, char *name) } static -int nt_delete_sid(sid_t *sid) +int nt_delete_sid(DOM_SID *sid) { if (sid) free(sid); @@ -1173,15 +1173,15 @@ VAL_KEY *nt_delete_reg_value(REG_KEY *key, char *name) * Convert a string of the form S-1-5-x[-y-z-r] to a SID */ static -int sid_string_to_sid(sid_t **sid, const char *sid_str) +int string_to_sid(DOM_SID **sid, const char *sid_str) { int i = 0, auth; const char *lstr; - *sid = (sid_t *)malloc(sizeof(sid_t)); + *sid = (DOM_SID *)malloc(sizeof(DOM_SID)); if (!*sid) return 0; - bzero(*sid, sizeof(sid_t)); + bzero(*sid, sizeof(DOM_SID)); if (strncmp(sid_str, "S-1-5", 5)) { fprintf(stderr, "Does not conform to S-1-5...: %s\n", sid_str); @@ -1226,7 +1226,7 @@ ACE *nt_create_ace(int type, int flags, unsigned int perms, const char *sid) ace->type = type; ace->flags = flags; ace->perms = perms; - if (!sid_string_to_sid(&ace->trustee, sid)) + if (!string_to_sid(&ace->trustee, sid)) goto error; return ace; @@ -1287,8 +1287,8 @@ SEC_DESC *nt_create_def_sec_desc(REGF *regf) tmp->rev = 1; tmp->type = 0x8004; - if (!sid_string_to_sid(&tmp->owner, "S-1-5-32-544")) goto error; - if (!sid_string_to_sid(&tmp->group, "S-1-5-18")) goto error; + if (!string_to_sid(&tmp->owner, "S-1-5-32-544")) goto error; + if (!string_to_sid(&tmp->group, "S-1-5-18")) goto error; tmp->sacl = NULL; tmp->dacl = nt_create_default_acl(regf); @@ -1829,9 +1829,9 @@ KEY_SEC_DESC *lookup_create_sec_key(REGF *regf, SK_MAP *sk_map, int sk_off) * We could allocate the SID to be only the size needed, but I am too lazy. */ static -sid_t *dup_sid(sid_t *sid) +DOM_SID *dup_sid(DOM_SID *sid) { - sid_t *tmp = (sid_t *)malloc(sizeof(sid_t)); + DOM_SID *tmp = (DOM_SID *)malloc(sizeof(DOM_SID)); int i; if (!tmp) return NULL; @@ -1916,12 +1916,12 @@ SEC_DESC *process_sec_desc(REGF *regf, REG_SEC_DESC *sec_desc) IVAL(&sec_desc->group_off)); if (verbose) fprintf(stdout, "SEC_DESC DACL Off: %0X\n", IVAL(&sec_desc->dacl_off)); - tmp->owner = dup_sid((sid_t *)((char *)sec_desc + IVAL(&sec_desc->owner_off))); + tmp->owner = dup_sid((DOM_SID *)((char *)sec_desc + IVAL(&sec_desc->owner_off))); if (!tmp->owner) { free(tmp); return NULL; } - tmp->group = dup_sid((sid_t *)((char *)sec_desc + IVAL(&sec_desc->group_off))); + tmp->group = dup_sid((DOM_SID *)((char *)sec_desc + IVAL(&sec_desc->group_off))); if (!tmp->group) { free(tmp); return NULL; @@ -2618,7 +2618,7 @@ void *nt_alloc_regf_space(REGF *regf, int size, unsigned int *off) * Compute the size of a SID stored ... */ static -unsigned int sid_size(sid_t *sid) +unsigned int sid_size(DOM_SID *sid) { unsigned int size; @@ -2686,7 +2686,7 @@ unsigned int sec_desc_size(SEC_DESC *sd) * Store a SID at the location provided */ static -int nt_store_SID(REGF *regf, sid_t *sid, unsigned char *locn) +int nt_store_SID(REGF *regf, DOM_SID *sid, unsigned char *locn) { int i; unsigned char *p = locn; @@ -3864,7 +3864,7 @@ void print_perms(int perms) } static -void print_sid(sid_t *sid) +void print_sid(DOM_SID *sid) { int i, comps = sid->auths; fprintf(stdout, "S-%u-%u", sid->ver, sid->auth[5]); @@ -3955,7 +3955,7 @@ int main(int argc, char *argv[]) char *cmd_file_name = NULL; char *out_file_name = NULL; CMD_FILE *cmd_file = NULL; - sid_t *lsid; + DOM_SID *lsid; if (argc < 2) { usage(); @@ -3987,7 +3987,7 @@ int main(int argc, char *argv[]) case 'O': def_owner_sid_str = strdup(optarg); regf_opt += 2; - if (!sid_string_to_sid(&lsid, def_owner_sid_str)) { + if (!string_to_sid(&lsid, def_owner_sid_str)) { fprintf(stderr, "Default Owner SID: %s is incorrectly formatted\n", def_owner_sid_str); free(&def_owner_sid_str[0]); diff --git a/source/utils/net_ads.c b/source/utils/net_ads.c index 203d849786b..5051f181881 100644 --- a/source/utils/net_ads.c +++ b/source/utils/net_ads.c @@ -109,6 +109,9 @@ static int net_ads_info(int argc, const char **argv) d_printf("LDAP port: %d\n", ads->ldap_port); d_printf("Server time: %s\n", http_timestring(ads->config.current_time)); + d_printf("KDC server: %s\n", ads->auth.kdc_server ); + d_printf("Server time offset: %d\n", ads->auth.time_offset ); + return 0; } @@ -124,7 +127,7 @@ static ADS_STRUCT *ads_startup(void) ADS_STATUS status; BOOL need_password = False; BOOL second_time = False; - char *realm; + char *cp; ads = ads_init(NULL, NULL, opt_host); @@ -146,22 +149,24 @@ retry: if (opt_password) { use_in_memory_ccache(); - ads->auth.password = strdup(opt_password); + ads->auth.password = smb_xstrdup(opt_password); } - ads->auth.user_name = strdup(opt_user_name); + ads->auth.user_name = smb_xstrdup(opt_user_name); - /* - * If the username is of the form "name@realm", - * extract the realm and convert to upper case. - */ - if ((realm = strchr(ads->auth.user_name, '@'))) { - *realm++ = '\0'; - ads->auth.realm = strdup(realm); - strupper(ads->auth.realm); - } + /* + * If the username is of the form "name@realm", + * extract the realm and convert to upper case. + * This is only used to establish the connection. + */ + if ((cp = strchr(ads->auth.user_name, '@'))!=0) { + *cp++ = '\0'; + ads->auth.realm = smb_xstrdup(cp); + strupper(ads->auth.realm); + } status = ads_connect(ads); + if (!ADS_ERR_OK(status)) { if (!need_password && !second_time) { need_password = True; @@ -230,7 +235,7 @@ static BOOL usergrp_display(char *field, void **values, void *data_area) if (!field) { /* must be end of record */ if (!strchr_m(disp_fields[0], '$')) { if (disp_fields[1]) - d_printf("%-21.21s %-50.50s\n", + d_printf("%-21.21s %s\n", disp_fields[0], disp_fields[1]); else d_printf("%s\n", disp_fields[0]); @@ -295,7 +300,8 @@ static int ads_user_add(int argc, const char **argv) /* try setting the password */ asprintf(&upn, "%s@%s", argv[0], ads->config.realm); - status = krb5_set_password(ads->auth.kdc_server, upn, argv[1], ads->auth.time_offset); + status = ads_krb5_set_password(ads->auth.kdc_server, upn, argv[1], + ads->auth.time_offset); safe_free(upn); if (ADS_ERR_OK(status)) { d_printf("User %s added\n", argv[0]); diff --git a/source/utils/net_ads_cldap.c b/source/utils/net_ads_cldap.c index 86d5abea4be..e74e4b5a4cf 100644 --- a/source/utils/net_ads_cldap.c +++ b/source/utils/net_ads_cldap.c @@ -24,28 +24,28 @@ #ifdef HAVE_ADS -struct netlogon_string { - uint32 comp_len; - char **component; - uint8 extra_flag; -}; +#define MAX_DNS_LABEL 255 + 1 struct cldap_netlogon_reply { uint32 type; uint32 flags; GUID guid; - struct netlogon_string forest; - struct netlogon_string domain; - struct netlogon_string hostname; - - struct netlogon_string netbios_domain; - struct netlogon_string netbios_hostname; + char forest[MAX_DNS_LABEL]; + char unk0[MAX_DNS_LABEL]; + char domain[MAX_DNS_LABEL]; + char hostname[MAX_DNS_LABEL]; - struct netlogon_string user_name; - struct netlogon_string site_name; + char netbios_domain[MAX_DNS_LABEL]; + char unk1[MAX_DNS_LABEL]; + char netbios_hostname[MAX_DNS_LABEL]; - struct netlogon_string unk0; + char unk2[MAX_DNS_LABEL]; + char user_name[MAX_DNS_LABEL]; + char unk3[MAX_DNS_LABEL]; + char site_name[MAX_DNS_LABEL]; + char unk4[MAX_DNS_LABEL]; + char site_name_2[MAX_DNS_LABEL]; uint32 version; uint16 lmnt_token; @@ -53,38 +53,69 @@ struct cldap_netlogon_reply { }; /* - These strings are rather interesting... They are composed of a series of - length encoded strings, terminated by either 1) a zero length string or 2) - a 0xc0 byte with what appears to be a one byte flags immediately following. + These seem to be strings as described in RFC1035 4.1.4 and can be: + + - a sequence of labels ending in a zero octet + - a pointer + - a sequence of labels ending with a pointer + + A label is a byte where the first two bits must be zero and the remaining + bits represent the length of the label followed by the label itself. + Therefore, the length of a label is at max 64 bytes. Under RFC1035, a + sequence of labels cannot exceed 255 bytes. + + A pointer consists of a 14 bit offset from the beginning of the data. + + struct ptr { + unsigned ident:2; // must be 11 + unsigned offset:14; // from the beginning of data + }; + + This is used as a method to compress the packet by eliminated duplicate + domain components. Since a UDP packet should probably be < 512 bytes and a + DNS name can be up to 255 bytes, this actually makes a lot of sense. */ -static unsigned pull_netlogon_string(struct netlogon_string *ret,const char *d) +static unsigned pull_netlogon_string(char *ret, const char *ptr, + const char *data) { - const char *p = (const char *)d; - - ZERO_STRUCTP(ret); + char *pret = ret; + int followed_ptr = 0; + unsigned ret_len = 0; + memset(pret, 0, MAX_DNS_LABEL); do { - unsigned len = (unsigned char)*p; - p++; - - if (len > 0 && len != 0xc0) { - ret->component = realloc(ret->component, - ++ret->comp_len * - sizeof(char *)); - - ret->component[ret->comp_len - 1] = - smb_xstrndup(p, len); - p += len; - } else { - if (len == 0xc0) { - ret->extra_flag = *p; - p++; - }; - break; + if ((*ptr & 0xc0) == 0xc0) { + uint16 len; + + if (!followed_ptr) { + ret_len += 2; + followed_ptr = 1; + } + len = ((ptr[0] & 0x3f) << 8) | ptr[1]; + ptr = data + len; + } else if (*ptr) { + uint8 len = (uint8)*(ptr++); + + if ((pret - ret + len + 1) >= MAX_DNS_LABEL) { + d_printf("DC returning too long DNS name\n"); + return 0; + } + + if (pret != ret) { + *pret = '.'; + pret++; + } + memcpy(pret, ptr, len); + pret += len; + ptr += len; + + if (!followed_ptr) { + ret_len += (len + 1); + } } - } while (1); + } while (*ptr); - return (p - d); + return ret_len ? ret_len : 1; } /* @@ -95,7 +126,11 @@ static int send_cldap_netlogon(int sock, const char *domain, { ASN1_DATA data; char ntver[4]; +#ifdef CLDAP_USER_QUERY + char aac[4]; + SIVAL(aac, 0, 0x00000180); +#endif SIVAL(ntver, 0, ntversion); memset(&data, 0, sizeof(data)); @@ -121,6 +156,18 @@ static int send_cldap_netlogon(int sock, const char *domain, asn1_write_OctetString(&data, hostname, strlen(hostname)); asn1_pop_tag(&data); +#ifdef CLDAP_USER_QUERY + asn1_push_tag(&data, ASN1_CONTEXT(3)); + asn1_write_OctetString(&data, "User", 4); + asn1_write_OctetString(&data, "SAMBA$", 6); + asn1_pop_tag(&data); + + asn1_push_tag(&data, ASN1_CONTEXT(3)); + asn1_write_OctetString(&data, "AAC", 4); + asn1_write_OctetString(&data, aac, 4); + asn1_pop_tag(&data); +#endif + asn1_push_tag(&data, ASN1_CONTEXT(3)); asn1_write_OctetString(&data, "NtVer", 5); asn1_write_OctetString(&data, ntver, 4); @@ -144,7 +191,6 @@ static int send_cldap_netlogon(int sock, const char *domain, d_printf("failed to send cldap query (%s)\n", strerror(errno)); } - file_save("cldap_query.dat", data.data, data.length); asn1_free(&data); return 0; @@ -173,8 +219,6 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) } blob.length = ret; - file_save("cldap_reply.dat", blob.data, blob.length); - asn1_load(&data, blob); asn1_start_tag(&data, ASN1_SEQUENCE(0)); asn1_read_Integer(&data, &i1); @@ -196,8 +240,6 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) return -1; } - file_save("cldap_reply_core.dat", os3.data, os3.length); - p = os3.data; reply->type = IVAL(p, 0); p += 4; @@ -206,15 +248,25 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) memcpy(&reply->guid.info, p, GUID_SIZE); p += GUID_SIZE; - p += pull_netlogon_string(&reply->forest, p); - p += pull_netlogon_string(&reply->domain, p); - p += pull_netlogon_string(&reply->hostname, p); - p += pull_netlogon_string(&reply->netbios_domain, p); - p += pull_netlogon_string(&reply->netbios_hostname, p); - p += pull_netlogon_string(&reply->user_name, p); - p += pull_netlogon_string(&reply->site_name, p); + p += pull_netlogon_string(reply->forest, p, os3.data); + p += pull_netlogon_string(reply->unk0, p, os3.data); + p += pull_netlogon_string(reply->domain, p, os3.data); + p += pull_netlogon_string(reply->hostname, p, os3.data); + p += pull_netlogon_string(reply->netbios_domain, p, os3.data); + p += pull_netlogon_string(reply->unk1, p, os3.data); + p += pull_netlogon_string(reply->netbios_hostname, p, os3.data); + p += pull_netlogon_string(reply->unk2, p, os3.data); + + if (reply->type == SAMLOGON_AD_R) { + p += pull_netlogon_string(reply->user_name, p, os3.data); + } else { + *reply->user_name = 0; + } - p += pull_netlogon_string(&reply->unk0, p); + p += pull_netlogon_string(reply->unk3, p, os3.data); + p += pull_netlogon_string(reply->site_name, p, os3.data); + p += pull_netlogon_string(reply->unk4, p, os3.data); + p += pull_netlogon_string(reply->site_name_2, p, os3.data); reply->version = IVAL(p, 0); reply->lmnt_token = SVAL(p, 4); @@ -229,52 +281,6 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) } /* - free a netlogon string -*/ -static void netlogon_string_free(struct netlogon_string *str) -{ - unsigned int i; - - for (i = 0; i < str->comp_len; ++i) { - SAFE_FREE(str->component[i]); - } - SAFE_FREE(str->component); -} - -/* - free a cldap reply packet -*/ -static void cldap_reply_free(struct cldap_netlogon_reply *reply) -{ - netlogon_string_free(&reply->forest); - netlogon_string_free(&reply->domain); - netlogon_string_free(&reply->hostname); - netlogon_string_free(&reply->netbios_domain); - netlogon_string_free(&reply->netbios_hostname); - netlogon_string_free(&reply->user_name); - netlogon_string_free(&reply->site_name); - netlogon_string_free(&reply->unk0); -} - -static void d_print_netlogon_string(const char *label, - struct netlogon_string *str) -{ - unsigned int i; - - if (str->comp_len) { - d_printf("%s", label); - if (str->extra_flag) { - d_printf("[%d]", str->extra_flag); - } - d_printf(": "); - for (i = 0; i < str->comp_len; ++i) { - d_printf("%s%s", (i ? "." : ""), str->component[i]); - } - d_printf("\n"); - } -} - -/* do a cldap netlogon query */ int ads_cldap_netlogon(ADS_STRUCT *ads) @@ -289,6 +295,7 @@ int ads_cldap_netlogon(ADS_STRUCT *ads) inet_ntoa(ads->ldap_ip), ads->ldap_port); return -1; + } ret = send_cldap_netlogon(sock, ads->config.realm, global_myname(), 6); @@ -305,7 +312,18 @@ int ads_cldap_netlogon(ADS_STRUCT *ads) d_printf("Information for Domain Controller: %s\n\n", ads->config.ldap_server_name); - d_printf("Response Type: 0x%x\n", reply.type); + d_printf("Response Type: "); + switch (reply.type) { + case SAMLOGON_AD_UNK_R: + d_printf("SAMLOGON\n"); + break; + case SAMLOGON_AD_R: + d_printf("SAMLOGON_USER\n"); + break; + default: + d_printf("0x%x\n", reply.type); + break; + } d_printf("GUID: "); print_guid(&reply.guid); d_printf("Flags:\n" @@ -330,23 +348,27 @@ int ads_cldap_netlogon(ADS_STRUCT *ads) (reply.flags & ADS_GOOD_TIMESERV) ? "yes" : "no", (reply.flags & ADS_NDNC) ? "yes" : "no"); - d_print_netlogon_string("Forest", &reply.forest); - d_print_netlogon_string("Domain", &reply.domain); - d_print_netlogon_string("Hostname", &reply.hostname); + printf("Forest:\t\t\t%s\n", reply.forest); + if (*reply.unk0) printf("Unk0:\t\t\t%s\n", reply.unk0); + printf("Domain:\t\t\t%s\n", reply.domain); + printf("Domain Controller:\t%s\n", reply.hostname); - d_print_netlogon_string("Pre-Win2k Domain", &reply.netbios_domain); - d_print_netlogon_string("Pre-Win2k Hostname", &reply.netbios_hostname); + printf("Pre-Win2k Domain:\t%s\n", reply.netbios_domain); + if (*reply.unk1) printf("Unk1:\t\t\t%s\n", reply.unk1); + printf("Pre-Win2k Hostname:\t%s\n", reply.netbios_hostname); - d_print_netlogon_string("User name", &reply.user_name); - d_print_netlogon_string("Site Name", &reply.site_name); - d_print_netlogon_string("Unknown Field", &reply.unk0); + if (*reply.unk2) printf("Unk2:\t\t\t%s\n", reply.unk2); + if (*reply.user_name) printf("User name:\t%s\n", reply.user_name); + + if (*reply.unk3) printf("Unk3:\t\t\t%s\n", reply.unk3); + printf("Site Name:\t\t%s\n", reply.site_name); + if (*reply.unk4) printf("Unk4:\t\t\t%s\n", reply.unk4); + printf("Site Name (2):\t\t%s\n", reply.site_name_2); d_printf("NT Version: %d\n", reply.version); d_printf("LMNT Token: %.2x\n", reply.lmnt_token); d_printf("LM20 Token: %.2x\n", reply.lm20_token); - cldap_reply_free(&reply); - return ret; } diff --git a/source/utils/net_rpc.c b/source/utils/net_rpc.c index 3f5a3399489..544525b705a 100644 --- a/source/utils/net_rpc.c +++ b/source/utils/net_rpc.c @@ -74,7 +74,7 @@ static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli) goto error; } - result = cli_lsa_open_policy(cli, mem_ctx, True, + result = cli_lsa_open_policy(cli, mem_ctx, False, SEC_RIGHTS_MAXIMUM_ALLOWED, &pol); if (!NT_STATUS_IS_OK(result)) { @@ -235,14 +235,25 @@ int net_rpc_changetrustpw(int argc, const char **argv) * @return Normal NTSTATUS return. **/ -static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cli_state *cli, +static NTSTATUS rpc_oldjoin_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { fstring trust_passwd; unsigned char orig_trust_passwd_hash[16]; NTSTATUS result; + uint32 sec_channel_type; + /* + check what type of join - if the user want's to join as + a BDC, the server must agree that we are a BDC. + */ + if (argc >= 0) { + sec_channel_type = get_sec_channel_type(argv[0]); + } else { + sec_channel_type = get_sec_channel_type(NULL); + } + fstrcpy(trust_passwd, global_myname()); strlower(trust_passwd); @@ -257,11 +268,7 @@ static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cl result = trust_pw_change_and_store_it(cli, mem_ctx, opt_target_workgroup, orig_trust_passwd_hash, - SEC_CHAN_WKSTA); - - /* SEC_CHAN_WKSTA specified specifically, as you cannot use this - to join a BDC to the domain (MS won't allow it, and is *really* - insecure) */ + sec_channel_type); if (NT_STATUS_IS_OK(result)) printf("Joined domain %s.\n",opt_target_workgroup); @@ -285,40 +292,11 @@ static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cl * @return A shell status integer (0 for success) **/ -static int net_rpc_join_oldstyle(int argc, const char **argv) -{ - uint32 sec_channel_type; - /* check what type of join */ - if (argc >= 0) { - sec_channel_type = get_sec_channel_type(argv[0]); - } else { - sec_channel_type = get_sec_channel_type(NULL); - } - - if (sec_channel_type != SEC_CHAN_WKSTA) - return 1; - - return run_rpc_command(NULL, PI_NETLOGON, - NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, - rpc_join_oldstyle_internals, - argc, argv); -} - -/** - * Join a domain, the old way. - * - * @param argc Standard main() style argc - * @param argc Standard main() style argv. Initial components are already - * stripped - * - * @return A shell status integer (0 for success) - **/ - static int net_rpc_oldjoin(int argc, const char **argv) { return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, - rpc_join_oldstyle_internals, + rpc_oldjoin_internals, argc, argv); } @@ -351,13 +329,13 @@ static int rpc_join_usage(int argc, const char **argv) * * Main 'net_rpc_join()' (where the admain username/password is used) is * in net_rpc_join.c - * Assume if a -U is specified, it's the new style, otherwise it's the - * old style. If 'oldstyle' is specfied explicity, do it and don't prompt. + * Try to just change the password, but if that doesn't work, use/prompt + * for a username/password. **/ int net_rpc_join(int argc, const char **argv) { - if ((net_rpc_join_oldstyle(argc, argv) == 0)) + if ((net_rpc_oldjoin(argc, argv) == 0)) return 0; return net_rpc_join_newstyle(argc, argv); @@ -862,11 +840,11 @@ rpc_user_list_internals(const DOM_SID *domain_sid, struct cli_state *cli, unistr2_to_ascii(desc, &(&ctr.sam.info1->str[i])->uni_acct_desc, sizeof(desc)-1); if (opt_long_list_entries) - printf("%-21.21s %-50.50s\n", user, desc); + printf("%-21.21s %s\n", user, desc); else printf("%s\n", user); } - } while (!NT_STATUS_IS_OK(result)); + } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); done: return result; @@ -977,7 +955,7 @@ rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli, else printf("%-21.21s\n", groups[i].acct_name); } - } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)); + } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); /* query domain aliases */ do { result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol, @@ -992,7 +970,7 @@ rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli, else printf("%-21.21s\n", groups[i].acct_name); } - } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)); + } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); cli_samr_close(cli, mem_ctx, &domain_pol); /* Get builtin policy handle */ @@ -1016,7 +994,7 @@ rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli, else printf("%s\n", groups[i].acct_name); } - } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)); + } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); done: return result; @@ -1576,8 +1554,8 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli uint16 acb_info; uint32 unknown, user_rid; - if (argc != 1) { - d_printf("Usage: net rpc trustdom add <domain_name>\n"); + if (argc != 2) { + d_printf("Usage: net rpc trustdom add <domain_name> <pw>\n"); return NT_STATUS_INVALID_PARAMETER; } @@ -1608,7 +1586,7 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli /* Create trusting domain's account */ acb_info = ACB_DOMTRUST; - unknown = 0xe005000b; /* No idea what this is - a permission mask? + unknown = 0xe00500b0; /* No idea what this is - a permission mask? mimir: yes, most probably it is */ result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol, @@ -1618,6 +1596,37 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli goto done; } + { + SAM_USERINFO_CTR ctr; + SAM_USER_INFO_24 p24; + fstring ucs2_trust_password; + int ucs2_pw_len; + uchar pwbuf[516]; + + ucs2_pw_len = push_ucs2(NULL, ucs2_trust_password, argv[1], + sizeof(ucs2_trust_password), 0); + + encode_pw_buffer((char *)pwbuf, ucs2_trust_password, + ucs2_pw_len); + + ZERO_STRUCT(ctr); + ZERO_STRUCT(p24); + + init_sam_user_info24(&p24, (char *)pwbuf, 24); + + ctr.switch_value = 24; + ctr.info.id24 = &p24; + + result = cli_samr_set_userinfo(cli, mem_ctx, &user_pol, 24, + cli->user_session_key, &ctr); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(0,("Could not set trust account password: %s\n", + nt_errstr(result))); + goto done; + } + } + done: SAFE_FREE(acct_name); return result; @@ -1785,7 +1794,7 @@ static int rpc_trustdom_establish(int argc, const char **argv) return -1; } - nt_status = cli_lsa_open_policy2(cli, mem_ctx, False, SEC_RIGHTS_QUERY_VALUE, + nt_status = cli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE, &connect_hnd); if (NT_STATUS_IS_ERR(nt_status)) { DEBUG(0, ("Couldn't open policy handle. Error was %s\n", @@ -1804,6 +1813,9 @@ static int rpc_trustdom_establish(int argc, const char **argv) return -1; } + + + /* There should be actually query info level 3 (following nt serv behaviour), but I still don't know if it's _really_ necessary */ diff --git a/source/utils/net_rpc_samsync.c b/source/utils/net_rpc_samsync.c index 42bb480844a..ae6f52ebc41 100644 --- a/source/utils/net_rpc_samsync.c +++ b/source/utils/net_rpc_samsync.c @@ -209,6 +209,11 @@ int rpc_samdump(int argc, const char **argv) fstrcpy(cli->domain, lp_workgroup()); + if (!cli_nt_session_open(cli, PI_NETLOGON)) { + DEBUG(0,("Could not open connection to NETLOGON pipe\n")); + goto fail; + } + if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_password, NULL, &sec_channel)) { @@ -216,7 +221,8 @@ int rpc_samdump(int argc, const char **argv) goto fail; } - if (!cli_nt_open_netlogon(cli, trust_password, sec_channel)) { + if (!NT_STATUS_IS_OK(cli_nt_establish_netlogon(cli, sec_channel, + trust_password))) { DEBUG(0,("Error connecting to NETLOGON pipe\n")); goto fail; } @@ -929,11 +935,17 @@ fetch_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds, db_type, sync_context, &num_deltas, &hdr_deltas, &deltas); - clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), - ret_creds); - for (i = 0; i < num_deltas; i++) { - fetch_sam_entry(&hdr_deltas[i], &deltas[i], dom_sid); - } + + if (NT_STATUS_IS_OK(result) || + NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { + + clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), + ret_creds); + + for (i = 0; i < num_deltas; i++) { + fetch_sam_entry(&hdr_deltas[i], &deltas[i], dom_sid); + } + } sync_context += 1; } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); @@ -947,7 +959,6 @@ int rpc_vampire(int argc, const char **argv) struct cli_state *cli = NULL; uchar trust_password[16]; DOM_CRED ret_creds; - uint32 neg_flags = 0x000001ff; DOM_SID dom_sid; uint32 sec_channel; @@ -971,8 +982,8 @@ int rpc_vampire(int argc, const char **argv) goto fail; } - result = cli_nt_setup_creds(cli, sec_channel, trust_password, - &neg_flags, 2); + result = cli_nt_establish_netlogon(cli, sec_channel, trust_password); + if (!NT_STATUS_IS_OK(result)) { d_printf("Failed to setup BDC creds\n"); goto fail; diff --git a/source/utils/ntlm_auth.c b/source/utils/ntlm_auth.c index 42490190f32..c619936f683 100644 --- a/source/utils/ntlm_auth.c +++ b/source/utils/ntlm_auth.c @@ -38,7 +38,6 @@ enum squid_mode { extern int winbindd_fd; -static const char *helper_protocol; static const char *opt_username; static const char *opt_domain; static const char *opt_workstation; @@ -48,7 +47,6 @@ static DATA_BLOB opt_lm_response; static DATA_BLOB opt_nt_response; static int request_lm_key; static int request_nt_key; -static int diagnostics; static char winbind_separator(void) @@ -184,7 +182,7 @@ static NTSTATUS contact_winbind_auth_crap(const char *username, const DATA_BLOB *lm_response, const DATA_BLOB *nt_response, uint32 flags, - uint8 lm_key[16], + uint8 lm_key[8], uint8 nt_key[16], char **error_string) { @@ -410,9 +408,10 @@ static BOOL check_auth_crap(void) char *hex_lm_key; char *hex_nt_key; char *error_string; - static uint8 zeros[16]; + x_setbuf(x_stdout, NULL); + if (request_lm_key) flags |= WINBIND_PAM_LMKEY; @@ -430,9 +429,9 @@ static BOOL check_auth_crap(void) &error_string); if (!NT_STATUS_IS_OK(nt_status)) { - d_printf("%s (0x%x)\n", - error_string, - NT_STATUS_V(nt_status)); + x_fprintf(x_stdout, "%s (0x%x)\n", + error_string, + NT_STATUS_V(nt_status)); SAFE_FREE(error_string); return False; } @@ -443,7 +442,7 @@ static BOOL check_auth_crap(void) hex_encode(lm_key, sizeof(lm_key), &hex_lm_key); - d_printf("LM_KEY: %s\n", hex_lm_key); + x_fprintf(x_stdout, "LM_KEY: %s\n", hex_lm_key); SAFE_FREE(hex_lm_key); } if (request_nt_key @@ -452,7 +451,7 @@ static BOOL check_auth_crap(void) hex_encode(nt_key, sizeof(nt_key), &hex_nt_key); - d_printf("NT_KEY: %s\n", hex_nt_key); + x_fprintf(x_stdout, "NT_KEY: %s\n", hex_nt_key); SAFE_FREE(hex_nt_key); } @@ -476,6 +475,10 @@ static DATA_BLOB get_challenge(void) return chal; } +/* + * Test LM authentication, no NT response supplied + */ + static BOOL test_lm(void) { NTSTATUS nt_status; @@ -483,13 +486,18 @@ static BOOL test_lm(void) DATA_BLOB lm_response = data_blob(NULL, 24); uchar lm_key[8]; + uchar nt_key[16]; uchar lm_hash[16]; DATA_BLOB chall = get_challenge(); char *error_string; + ZERO_STRUCT(lm_key); + ZERO_STRUCT(nt_key); + flags |= WINBIND_PAM_LMKEY; + flags |= WINBIND_PAM_NTKEY; - SMBencrypt(opt_password,chall.data,lm_response.data); + SMBencrypt(opt_password, chall.data, lm_response.data); E_deshash(opt_password, lm_hash); nt_status = contact_winbind_auth_crap(opt_username, opt_domain, opt_workstation, @@ -498,7 +506,7 @@ static BOOL test_lm(void) NULL, flags, lm_key, - NULL, + nt_key, &error_string); data_blob_free(&lm_response); @@ -518,9 +526,20 @@ static BOOL test_lm(void) DEBUG(1, ("expected:\n")); dump_data(1, lm_hash, 8); } + if (memcmp(lm_hash, nt_key, 8) != 0) { + DEBUG(1, ("Session Key (first 8, lm hash) does not match expectations!\n")); + DEBUG(1, ("nt_key:\n")); + dump_data(1, nt_key, 8); + DEBUG(1, ("expected:\n")); + dump_data(1, lm_hash, 8); + } return True; } +/* + * Test the normal 'LM and NTLM' combination + */ + static BOOL test_lm_ntlm(void) { BOOL pass = True; @@ -537,6 +556,9 @@ static BOOL test_lm_ntlm(void) DATA_BLOB chall = get_challenge(); char *error_string; + ZERO_STRUCT(lm_key); + ZERO_STRUCT(nt_key); + flags |= WINBIND_PAM_LMKEY; flags |= WINBIND_PAM_NTKEY; @@ -589,6 +611,10 @@ static BOOL test_lm_ntlm(void) return pass; } +/* + * Test the NTLM response only, no LM. + */ + static BOOL test_ntlm(void) { BOOL pass = True; @@ -597,24 +623,170 @@ static BOOL test_ntlm(void) DATA_BLOB nt_response = data_blob(NULL, 24); DATA_BLOB session_key = data_blob(NULL, 16); + char lm_key[8]; char nt_key[16]; + char lm_hash[16]; char nt_hash[16]; DATA_BLOB chall = get_challenge(); char *error_string; + ZERO_STRUCT(lm_key); + ZERO_STRUCT(nt_key); + + flags |= WINBIND_PAM_LMKEY; flags |= WINBIND_PAM_NTKEY; SMBNTencrypt(opt_password,chall.data,nt_response.data); E_md4hash(opt_password, nt_hash); SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); + E_deshash(opt_password, lm_hash); + nt_status = contact_winbind_auth_crap(opt_username, opt_domain, opt_workstation, &chall, NULL, &nt_response, flags, + lm_key, + nt_key, + &error_string); + + data_blob_free(&nt_response); + + if (!NT_STATUS_IS_OK(nt_status)) { + d_printf("%s (0x%x)\n", + error_string, + NT_STATUS_V(nt_status)); + SAFE_FREE(error_string); + return False; + } + + if (memcmp(lm_hash, lm_key, + sizeof(lm_key)) != 0) { + DEBUG(1, ("LM Key does not match expectations!\n")); + DEBUG(1, ("lm_key:\n")); + dump_data(1, lm_key, 8); + DEBUG(1, ("expected:\n")); + dump_data(1, lm_hash, 8); + pass = False; + } + if (memcmp(session_key.data, nt_key, + sizeof(nt_key)) != 0) { + DEBUG(1, ("NT Session Key does not match expectations!\n")); + DEBUG(1, ("nt_key:\n")); + dump_data(1, nt_key, 16); + DEBUG(1, ("expected:\n")); + dump_data(1, session_key.data, session_key.length); + pass = False; + } + return pass; +} + +/* + * Test the NTLM response only, but in the LM field. + */ + +static BOOL test_ntlm_in_lm(void) +{ + BOOL pass = True; + NTSTATUS nt_status; + uint32 flags = 0; + DATA_BLOB nt_response = data_blob(NULL, 24); + + uchar lm_key[8]; + uchar lm_hash[16]; + uchar nt_key[16]; + DATA_BLOB chall = get_challenge(); + char *error_string; + + ZERO_STRUCT(nt_key); + + flags |= WINBIND_PAM_LMKEY; + flags |= WINBIND_PAM_NTKEY; + + SMBNTencrypt(opt_password,chall.data,nt_response.data); + + E_deshash(opt_password, lm_hash); + + nt_status = contact_winbind_auth_crap(opt_username, opt_domain, + opt_workstation, + &chall, + &nt_response, NULL, + flags, + lm_key, + nt_key, + &error_string); + + data_blob_free(&nt_response); + + if (!NT_STATUS_IS_OK(nt_status)) { + d_printf("%s (0x%x)\n", + error_string, + NT_STATUS_V(nt_status)); + SAFE_FREE(error_string); + return False; + } + + if (memcmp(lm_hash, lm_key, + sizeof(lm_key)) != 0) { + DEBUG(1, ("LM Key does not match expectations!\n")); + DEBUG(1, ("lm_key:\n")); + dump_data(1, lm_key, 8); + DEBUG(1, ("expected:\n")); + dump_data(1, lm_hash, 8); + pass = False; + } + if (memcmp(lm_hash, nt_key, 8) != 0) { + DEBUG(1, ("Session Key (first 8 lm hash) does not match expectations!\n")); + DEBUG(1, ("nt_key:\n")); + dump_data(1, nt_key, 16); + DEBUG(1, ("expected:\n")); + dump_data(1, lm_hash, 8); + pass = False; + } + return pass; +} + +/* + * Test the NTLM response only, but in the both the NT and LM fields. + */ + +static BOOL test_ntlm_in_both(void) +{ + BOOL pass = True; + NTSTATUS nt_status; + uint32 flags = 0; + DATA_BLOB nt_response = data_blob(NULL, 24); + DATA_BLOB session_key = data_blob(NULL, 16); + + char lm_key[8]; + char lm_hash[16]; + char nt_key[16]; + char nt_hash[16]; + DATA_BLOB chall = get_challenge(); + char *error_string; + + ZERO_STRUCT(lm_key); + ZERO_STRUCT(nt_key); + + flags |= WINBIND_PAM_LMKEY; + flags |= WINBIND_PAM_NTKEY; + + SMBNTencrypt(opt_password,chall.data,nt_response.data); + E_md4hash(opt_password, nt_hash); + SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); + + E_deshash(opt_password, lm_hash); + + nt_status = contact_winbind_auth_crap(opt_username, opt_domain, + opt_workstation, + &chall, + &nt_response, + &nt_response, + flags, + lm_key, nt_key, &error_string); @@ -628,6 +800,267 @@ static BOOL test_ntlm(void) return False; } + if (memcmp(lm_hash, lm_key, + sizeof(lm_key)) != 0) { + DEBUG(1, ("LM Key does not match expectations!\n")); + DEBUG(1, ("lm_key:\n")); + dump_data(1, lm_key, 8); + DEBUG(1, ("expected:\n")); + dump_data(1, lm_hash, 8); + pass = False; + } + if (memcmp(session_key.data, nt_key, + sizeof(nt_key)) != 0) { + DEBUG(1, ("NT Session Key does not match expectations!\n")); + DEBUG(1, ("nt_key:\n")); + dump_data(1, nt_key, 16); + DEBUG(1, ("expected:\n")); + dump_data(1, session_key.data, session_key.length); + pass = False; + } + + + return pass; +} + +/* + * Test the NTLMv2 response only + */ + +static BOOL test_ntlmv2(void) +{ + BOOL pass = True; + NTSTATUS nt_status; + uint32 flags = 0; + DATA_BLOB ntlmv2_response = data_blob(NULL, 0); + DATA_BLOB nt_session_key = data_blob(NULL, 0); + DATA_BLOB names_blob = NTLMv2_generate_names_blob(get_winbind_netbios_name(), get_winbind_domain()); + + uchar nt_key[16]; + DATA_BLOB chall = get_challenge(); + char *error_string; + + ZERO_STRUCT(nt_key); + + flags |= WINBIND_PAM_NTKEY; + + if (!SMBNTLMv2encrypt(opt_username, opt_domain, opt_password, &chall, + &names_blob, + NULL, &ntlmv2_response, + &nt_session_key)) { + data_blob_free(&names_blob); + return False; + } + data_blob_free(&names_blob); + + nt_status = contact_winbind_auth_crap(opt_username, opt_domain, + opt_workstation, + &chall, + NULL, + &ntlmv2_response, + flags, + NULL, + nt_key, + &error_string); + + data_blob_free(&ntlmv2_response); + + if (!NT_STATUS_IS_OK(nt_status)) { + d_printf("%s (0x%x)\n", + error_string, + NT_STATUS_V(nt_status)); + SAFE_FREE(error_string); + return False; + } + + if (memcmp(nt_session_key.data, nt_key, + sizeof(nt_key)) != 0) { + DEBUG(1, ("NT Session Key does not match expectations!\n")); + DEBUG(1, ("nt_key:\n")); + dump_data(1, nt_key, 16); + DEBUG(1, ("expected:\n")); + dump_data(1, nt_session_key.data, nt_session_key.length); + pass = False; + } + return pass; +} + +/* + * Test the NTLMv2 and LMv2 responses + */ + +static BOOL test_lmv2_ntlmv2(void) +{ + BOOL pass = True; + NTSTATUS nt_status; + uint32 flags = 0; + DATA_BLOB ntlmv2_response = data_blob(NULL, 0); + DATA_BLOB lmv2_response = data_blob(NULL, 0); + DATA_BLOB nt_session_key = data_blob(NULL, 0); + DATA_BLOB names_blob = NTLMv2_generate_names_blob(get_winbind_netbios_name(), get_winbind_domain()); + + uchar nt_key[16]; + DATA_BLOB chall = get_challenge(); + char *error_string; + + ZERO_STRUCT(nt_key); + + flags |= WINBIND_PAM_NTKEY; + + if (!SMBNTLMv2encrypt(opt_username, opt_domain, opt_password, &chall, + &names_blob, + &lmv2_response, &ntlmv2_response, + &nt_session_key)) { + data_blob_free(&names_blob); + return False; + } + data_blob_free(&names_blob); + + nt_status = contact_winbind_auth_crap(opt_username, opt_domain, + opt_workstation, + &chall, + &lmv2_response, + &ntlmv2_response, + flags, + NULL, + nt_key, + &error_string); + + data_blob_free(&lmv2_response); + data_blob_free(&ntlmv2_response); + + if (!NT_STATUS_IS_OK(nt_status)) { + d_printf("%s (0x%x)\n", + error_string, + NT_STATUS_V(nt_status)); + SAFE_FREE(error_string); + return False; + } + + if (memcmp(nt_session_key.data, nt_key, + sizeof(nt_key)) != 0) { + DEBUG(1, ("NT Session Key does not match expectations!\n")); + DEBUG(1, ("nt_key:\n")); + dump_data(1, nt_key, 16); + DEBUG(1, ("expected:\n")); + dump_data(1, nt_session_key.data, nt_session_key.length); + pass = False; + } + return pass; +} + +/* + * Test the LMv2 response only + */ + +static BOOL test_lmv2(void) +{ + BOOL pass = True; + NTSTATUS nt_status; + uint32 flags = 0; + DATA_BLOB lmv2_response = data_blob(NULL, 0); + + DATA_BLOB chall = get_challenge(); + char *error_string; + + if (!SMBNTLMv2encrypt(opt_username, opt_domain, opt_password, &chall, + NULL, + &lmv2_response, NULL, + NULL)) { + return False; + } + + nt_status = contact_winbind_auth_crap(opt_username, opt_domain, + opt_workstation, + &chall, + &lmv2_response, + NULL, + flags, + NULL, + NULL, + &error_string); + + data_blob_free(&lmv2_response); + + if (!NT_STATUS_IS_OK(nt_status)) { + d_printf("%s (0x%x)\n", + error_string, + NT_STATUS_V(nt_status)); + SAFE_FREE(error_string); + return False; + } + + return pass; +} + +/* + * Test the normal 'LM and NTLM' combination but deliberately break one + */ + +static BOOL test_ntlm_broken(BOOL break_lm) +{ + BOOL pass = True; + NTSTATUS nt_status; + uint32 flags = 0; + DATA_BLOB lm_response = data_blob(NULL, 24); + DATA_BLOB nt_response = data_blob(NULL, 24); + DATA_BLOB session_key = data_blob(NULL, 16); + + uchar lm_key[8]; + uchar nt_key[16]; + uchar lm_hash[16]; + uchar nt_hash[16]; + DATA_BLOB chall = get_challenge(); + char *error_string; + + ZERO_STRUCT(lm_key); + ZERO_STRUCT(nt_key); + + flags |= WINBIND_PAM_LMKEY; + flags |= WINBIND_PAM_NTKEY; + + SMBencrypt(opt_password,chall.data,lm_response.data); + E_deshash(opt_password, lm_hash); + + SMBNTencrypt(opt_password,chall.data,nt_response.data); + + E_md4hash(opt_password, nt_hash); + SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); + + if (break_lm) + lm_response.data[0]++; + else + nt_response.data[0]++; + + nt_status = contact_winbind_auth_crap(opt_username, opt_domain, + opt_workstation, + &chall, + &lm_response, + &nt_response, + flags, + lm_key, + nt_key, + &error_string); + + data_blob_free(&lm_response); + + if (!NT_STATUS_IS_OK(nt_status)) { + d_printf("%s (0x%x)\n", + error_string, + NT_STATUS_V(nt_status)); + SAFE_FREE(error_string); + return False; + } + + if (memcmp(lm_hash, lm_key, + sizeof(lm_key)) != 0) { + DEBUG(1, ("LM Key does not match expectations!\n")); + DEBUG(1, ("lm_key:\n")); + dump_data(1, lm_key, 8); + DEBUG(1, ("expected:\n")); + dump_data(1, lm_hash, 8); + pass = False; + } if (memcmp(session_key.data, nt_key, sizeof(nt_key)) != 0) { DEBUG(1, ("NT Session Key does not match expectations!\n")); @@ -640,12 +1073,92 @@ static BOOL test_ntlm(void) return pass; } +static BOOL test_ntlm_lm_broken(void) +{ + return test_ntlm_broken(True); +} + +static BOOL test_ntlm_ntlm_broken(void) +{ + return test_ntlm_broken(False); +} + +static BOOL test_ntlmv2_broken(BOOL break_lmv2) +{ + BOOL pass = True; + NTSTATUS nt_status; + uint32 flags = 0; + DATA_BLOB ntlmv2_response = data_blob(NULL, 0); + DATA_BLOB lmv2_response = data_blob(NULL, 0); + DATA_BLOB nt_session_key = data_blob(NULL, 0); + DATA_BLOB names_blob = NTLMv2_generate_names_blob(get_winbind_netbios_name(), get_winbind_domain()); + + uchar nt_key[16]; + DATA_BLOB chall = get_challenge(); + char *error_string; + + ZERO_STRUCT(nt_key); + + flags |= WINBIND_PAM_NTKEY; + + if (!SMBNTLMv2encrypt(opt_username, opt_domain, opt_password, &chall, + &names_blob, + &lmv2_response, &ntlmv2_response, + &nt_session_key)) { + data_blob_free(&names_blob); + return False; + } + data_blob_free(&names_blob); + + /* Heh - this should break the appropriate password hash nicely! */ + + if (break_lmv2) + lmv2_response.data[0]++; + else + ntlmv2_response.data[0]++; + + nt_status = contact_winbind_auth_crap(opt_username, opt_domain, + opt_workstation, + &chall, + &lmv2_response, + &ntlmv2_response, + flags, + NULL, + nt_key, + &error_string); + + data_blob_free(&lmv2_response); + data_blob_free(&ntlmv2_response); + + if (!NT_STATUS_IS_OK(nt_status)) { + d_printf("%s (0x%x)\n", + error_string, + NT_STATUS_V(nt_status)); + SAFE_FREE(error_string); + return False; + } + + return pass; +} + +static BOOL test_ntlmv2_lmv2_broken(void) +{ + return test_ntlmv2_broken(True); +} + +static BOOL test_ntlmv2_ntlmv2_broken(void) +{ + return test_ntlmv2_broken(False); +} + /* Tests: - LM only - NT and LM - NT + - NT in LM field + - NT in both fields - NTLMv2 - NTLMv2 and LMv2 - LMv2 @@ -659,12 +1172,18 @@ struct ntlm_tests { BOOL (*fn)(void); const char *name; } test_table[] = { - {test_lm, "test LM"}, - {test_lm_ntlm, "test LM and NTLM"}, - {test_ntlm, "test NTLM"} -/* {test_lm_ntlmv2, "test NTLMv2"}, */ -/* {test_lm_ntlmv2, "test NTLMv2 and LMv2"}, */ -/* {test_lm_ntlmv2, "test LMv2"} */ + {test_lm, "LM"}, + {test_lm_ntlm, "LM and NTLM"}, + {test_ntlm, "NTLM"}, + {test_ntlm_in_lm, "NTLM in LM"}, + {test_ntlm_in_both, "NTLM in both"}, + {test_ntlmv2, "NTLMv2"}, + {test_lmv2_ntlmv2, "NTLMv2 and LMv2"}, + {test_lmv2, "LMv2"}, + {test_ntlmv2_lmv2_broken, "NTLMv2 and LMv2, LMv2 broken"}, + {test_ntlmv2_ntlmv2_broken, "NTLMv2 and LMv2, NTLMv2 broken"}, + {test_ntlm_lm_broken, "NTLM and LM, LM broken"}, + {test_ntlm_ntlm_broken, "NTLM and LM, NTLM broken"} }; static BOOL diagnose_ntlm_auth(void) @@ -701,6 +1220,8 @@ enum { int main(int argc, const char **argv) { int opt; + static const char *helper_protocol; + static int diagnostics; static const char *hex_challenge; static const char *hex_lm_response; @@ -743,6 +1264,14 @@ enum { dbf = x_stderr; + /* Samba client initialisation */ + + if (!lp_load(dyn_CONFIGFILE, True, False, False)) { + d_fprintf(stderr, "wbinfo: error opening config file %s. Error was %s\n", + dyn_CONFIGFILE, strerror(errno)); + exit(1); + } + /* Parse options */ pc = poptGetContext("ntlm_auth", argc, argv, long_options, 0); @@ -760,7 +1289,7 @@ enum { while((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_CHALLENGE: - challenge = smb_xmalloc((strlen(hex_challenge)+1)/2); + challenge = smb_xmalloc((strlen(hex_challenge))/2+1); if ((challenge_len = strhex_to_str(challenge, strlen(hex_challenge), hex_challenge)) != 8) { @@ -772,7 +1301,7 @@ enum { SAFE_FREE(challenge); break; case OPT_LM: - lm_response = smb_xmalloc((strlen(hex_lm_response)+1)/2); + lm_response = smb_xmalloc((strlen(hex_lm_response))/2+1); lm_response_len = strhex_to_str(lm_response, strlen(hex_lm_response), hex_lm_response); @@ -784,7 +1313,7 @@ enum { SAFE_FREE(lm_response); break; case OPT_NT: - nt_response = smb_xmalloc((strlen(hex_nt_response)+1)/2); + nt_response = smb_xmalloc((strlen(hex_nt_response)+2)/2+1); nt_response_len = strhex_to_str(nt_response, strlen(hex_nt_response), hex_nt_response); diff --git a/source/web/swat.c b/source/web/swat.c index 7f9492933a5..d97278c4859 100644 --- a/source/web/swat.c +++ b/source/web/swat.c @@ -31,8 +31,6 @@ #include "includes.h" #include "../web/swat_proto.h" -#define GLOBALS_SNUM -1 - static BOOL demo_mode = False; static BOOL have_write_access = False; static BOOL have_read_access = False; @@ -579,7 +577,7 @@ static void wizard_params_page(void) d_printf("<H2>Wizard Parameter Edit Page</H2>\n"); if (cgi_variable("Commit")) { - commit_parameters(GLOBALS_SNUM); + commit_parameters(GLOBAL_SECTION_SNUM); save_reload(0); } @@ -593,7 +591,7 @@ static void wizard_params_page(void) d_printf("<p>\n"); d_printf("<table>\n"); - show_parameters(GLOBALS_SNUM, 1, parm_filter, 0); + show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0); d_printf("</table>\n"); d_printf("</form>\n"); } @@ -603,7 +601,7 @@ static void wizard_params_page(void) ****************************************************************************/ static void rewritecfg_file(void) { - commit_parameters(GLOBALS_SNUM); + commit_parameters(GLOBAL_SECTION_SNUM); save_reload(0); d_printf("<H2>Note: smb.conf %s</H2>\n", _("file has been read and rewritten")); } @@ -637,37 +635,37 @@ static void wizard_page(void) HomeExpo = atoi(cgi_variable("HomeExpo")); /* Plain text passwords are too badly broken - use encrypted passwords only */ - lp_do_parameter( GLOBALS_SNUM, "encrypt passwords", "Yes"); + lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes"); switch ( SerType ){ case 0: /* Stand-alone Server */ - lp_do_parameter( GLOBALS_SNUM, "security", "USER" ); - lp_do_parameter( GLOBALS_SNUM, "domain logons", "No" ); + lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" ); + lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" ); break; case 1: /* Domain Member */ - lp_do_parameter( GLOBALS_SNUM, "security", "DOMAIN" ); - lp_do_parameter( GLOBALS_SNUM, "domain logons", "No" ); + lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" ); + lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" ); break; case 2: /* Domain Controller */ - lp_do_parameter( GLOBALS_SNUM, "security", "USER" ); - lp_do_parameter( GLOBALS_SNUM, "domain logons", "Yes" ); + lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" ); + lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" ); break; } switch ( winstype ) { case 0: - lp_do_parameter( GLOBALS_SNUM, "wins support", "No" ); - lp_do_parameter( GLOBALS_SNUM, "wins server", "" ); + lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" ); + lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" ); break; case 1: - lp_do_parameter( GLOBALS_SNUM, "wins support", "Yes" ); - lp_do_parameter( GLOBALS_SNUM, "wins server", "" ); + lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" ); + lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" ); break; case 2: - lp_do_parameter( GLOBALS_SNUM, "wins support", "No" ); - lp_do_parameter( GLOBALS_SNUM, "wins server", cgi_variable("WINSAddr")); + lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" ); + lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable("WINSAddr")); break; } @@ -677,7 +675,7 @@ static void wizard_page(void) pstrcpy(unix_share,HOMES_NAME); load_config(False); - lp_copy_service(GLOBALS_SNUM, unix_share); + lp_copy_service(GLOBAL_SECTION_SNUM, unix_share); iNumNonAutoPrintServices = lp_numservices(); have_home = lp_servicenumber(HOMES_NAME); lp_do_parameter( have_home, "read only", "No"); @@ -692,7 +690,7 @@ static void wizard_page(void) have_home = -1; } - commit_parameters(GLOBALS_SNUM); + commit_parameters(GLOBAL_SECTION_SNUM); save_reload(0); } else @@ -778,7 +776,7 @@ static void globals_page(void) d_printf("<H2>%s</H2>\n", _("Global Variables")); if (cgi_variable("Commit")) { - commit_parameters(GLOBALS_SNUM); + commit_parameters(GLOBAL_SECTION_SNUM); save_reload(0); } @@ -810,7 +808,7 @@ static void globals_page(void) d_printf("<p>\n"); d_printf("<table>\n"); - show_parameters(GLOBALS_SNUM, 1, parm_filter, 0); + show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0); d_printf("</table>\n"); d_printf("</form>\n"); } @@ -847,7 +845,7 @@ static void shares_page(void) if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) { load_config(False); - lp_copy_service(GLOBALS_SNUM, share); + lp_copy_service(GLOBAL_SECTION_SNUM, share); iNumNonAutoPrintServices = lp_numservices(); save_reload(0); snum = lp_servicenumber(share); @@ -1186,7 +1184,7 @@ static void printers_page(void) if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) { load_config(False); - lp_copy_service(GLOBALS_SNUM, share); + lp_copy_service(GLOBAL_SECTION_SNUM, share); iNumNonAutoPrintServices = lp_numservices(); snum = lp_servicenumber(share); lp_do_parameter(snum, "print ok", "Yes"); |