summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2003-11-07 15:52:30 +0000
committerGerald Carter <jerry@samba.org>2003-11-07 15:52:30 +0000
commit16609b588b9703f9e12a0b6252dc31bfa9911b99 (patch)
tree3f7212610daef334f063a424e49036dba763e853 /source
parent53d8dfad13e2063ee1161ad4e8ff98683725cbdf (diff)
downloadsamba-16609b588b9703f9e12a0b6252dc31bfa9911b99.tar.gz
syncing tree with SAMBA_3_0
Diffstat (limited to 'source')
-rw-r--r--source/Makefile.in192
-rw-r--r--source/VERSION2
-rw-r--r--source/aclocal.m437
-rw-r--r--source/auth/auth_builtin.c2
-rw-r--r--source/auth/auth_sam.c16
-rw-r--r--source/auth/auth_util.c31
-rw-r--r--source/client/client.c5
-rwxr-xr-xsource/client/mount.cifs.c2
-rw-r--r--source/configure.in126
-rw-r--r--source/include/includes.h15
-rw-r--r--source/include/libsmbclient.h875
-rw-r--r--source/include/local.h3
-rw-r--r--source/include/ntdomain.h1
-rw-r--r--source/include/safe_string.h14
-rw-r--r--source/include/smb.h4
-rw-r--r--source/include/smb_acls.h2
-rw-r--r--source/intl/lang_tdb.c2
-rw-r--r--source/lib/access.c20
-rw-r--r--source/lib/afs.c10
-rw-r--r--source/lib/charcnv.c2
-rw-r--r--source/lib/getsmbpass.c5
-rw-r--r--source/lib/iconv.c6
-rw-r--r--source/lib/privileges.c1
-rw-r--r--source/lib/sendfile.c2
-rw-r--r--source/lib/smbldap.c5
-rw-r--r--source/lib/snprintf.c4
-rw-r--r--source/lib/substitute.c7
-rw-r--r--source/lib/talloctort.c4
-rw-r--r--source/lib/time.c9
-rw-r--r--source/lib/username.c19
-rw-r--r--source/lib/util.c3
-rw-r--r--source/lib/util_sec.c7
-rw-r--r--source/lib/util_sock.c34
-rw-r--r--source/lib/util_str.c5
-rw-r--r--source/libads/ads_struct.c4
-rw-r--r--source/libads/kerberos_verify.c16
-rw-r--r--source/libads/ldap.c6
-rw-r--r--source/libsmb/clidgram.c7
-rw-r--r--source/libsmb/clientgen.c2
-rw-r--r--source/libsmb/clilist.c2
-rw-r--r--source/libsmb/clisecdesc.c2
-rw-r--r--source/libsmb/clitrans.c11
-rw-r--r--source/libsmb/errormap.c4
-rw-r--r--source/libsmb/libsmb_compat.c187
-rw-r--r--source/libsmb/libsmbclient.c2144
-rw-r--r--source/libsmb/namequery_dc.c2
-rw-r--r--source/libsmb/ntlmssp_parse.c7
-rw-r--r--source/libsmb/ntlmssp_sign.c4
-rw-r--r--source/libsmb/smb_signing.c81
-rw-r--r--source/msdfs/msdfs.c100
-rw-r--r--source/nmbd/nmbd.c4
-rw-r--r--source/nmbd/nmbd_elections.c2
-rw-r--r--source/nmbd/nmbd_packets.c2
-rw-r--r--source/nmbd/nmbd_processlogon.c5
-rw-r--r--source/nsswitch/wb_common.c16
-rw-r--r--source/nsswitch/wbinfo.c9
-rw-r--r--source/nsswitch/winbind_nss_aix.c480
-rw-r--r--source/nsswitch/winbind_nss_hpux.h6
-rw-r--r--source/nsswitch/winbindd.c13
-rw-r--r--source/nsswitch/winbindd_ads.c2
-rw-r--r--source/nsswitch/winbindd_rpc.c2
-rw-r--r--source/nsswitch/winbindd_sid.c240
-rw-r--r--source/nsswitch/winbindd_util.c8
-rw-r--r--source/param/loadparm.c6
-rw-r--r--source/passdb/lookup_sid.c30
-rw-r--r--source/passdb/pdb_guest.c10
-rw-r--r--source/passdb/pdb_ldap.c10
-rw-r--r--source/passdb/pdb_smbpasswd.c2
-rw-r--r--source/printing/notify.c2
-rw-r--r--source/printing/nt_printing.c42
-rw-r--r--source/printing/print_generic.c2
-rw-r--r--source/rpc_client/cli_lsarpc.c1
-rw-r--r--source/rpc_client/cli_samr.c6
-rw-r--r--source/rpc_parse/parse_prs.c4
-rw-r--r--source/rpc_parse/parse_rpc.c10
-rw-r--r--source/rpc_server/srv_dfs_nt.c58
-rw-r--r--source/rpc_server/srv_lsa_hnd.c4
-rw-r--r--source/rpc_server/srv_pipe_hnd.c2
-rw-r--r--source/rpc_server/srv_spoolss_nt.c3
-rw-r--r--source/rpcclient/cmd_spoolss.c17
-rw-r--r--source/rpcclient/rpcclient.c2
-rw-r--r--source/rpcclient/rpcclient.h2
-rw-r--r--source/sam/idmap_ldap.c172
-rw-r--r--source/script/mkbuildoptions.awk16
-rw-r--r--source/smbd/blocking.c2
-rw-r--r--source/smbd/dosmode.c2
-rw-r--r--source/smbd/fileio.c6
-rw-r--r--source/smbd/ipc.c30
-rw-r--r--source/smbd/lanman.c14
-rw-r--r--source/smbd/mangle_hash2.c2
-rw-r--r--source/smbd/notify.c2
-rw-r--r--source/smbd/nttrans.c24
-rw-r--r--source/smbd/open.c2
-rw-r--r--source/smbd/oplock_linux.c4
-rw-r--r--source/smbd/posix_acls.c2
-rw-r--r--source/smbd/process.c4
-rw-r--r--source/smbd/reply.c16
-rw-r--r--source/smbd/server.c4
-rw-r--r--source/smbd/sesssetup.c25
-rw-r--r--source/smbd/statcache.c4
-rw-r--r--source/smbd/trans2.c25
-rw-r--r--source/smbwrapper/smbw.c8
-rw-r--r--source/smbwrapper/smbw_dir.c4
-rw-r--r--source/smbwrapper/smbw_stat.c4
-rw-r--r--source/tdb/spinlock.c2
-rw-r--r--source/tdb/spinlock.h4
-rw-r--r--source/tdb/tdb.c13
-rw-r--r--source/tdb/tdbtorture.c1
-rw-r--r--source/torture/cmd_vfs.c12
-rw-r--r--source/torture/denytest.c2
-rw-r--r--source/torture/mangle_test.c2
-rw-r--r--source/torture/torture.c24
-rw-r--r--source/torture/utable.c4
-rw-r--r--source/utils/net.c12
-rw-r--r--source/utils/net.h1
-rw-r--r--source/utils/net_ads.c2
-rw-r--r--source/utils/net_rpc.c53
-rw-r--r--source/utils/net_rpc_samsync.c3
-rw-r--r--source/utils/ntlm_auth.c4
-rw-r--r--source/utils/profiles.c1
-rw-r--r--source/utils/smbcontrol.c3
-rw-r--r--source/utils/smbcquotas.c14
-rw-r--r--source/utils/smbfilter.c2
-rw-r--r--source/utils/testparm.c80
-rw-r--r--source/web/cgi.c25
125 files changed, 4291 insertions, 1398 deletions
diff --git a/source/Makefile.in b/source/Makefile.in
index 4769604243b..83f266955b7 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -126,7 +126,7 @@ SBIN_PROGS = bin/smbd@EXEEXT@ bin/nmbd@EXEEXT@ bin/swat@EXEEXT@ @EXTRA_SBIN_PROG
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/tdbdump@EXEEXT@
BIN_PROGS3 = bin/smbpasswd@EXEEXT@ bin/rpcclient@EXEEXT@ bin/smbcacls@EXEEXT@ \
bin/profiles@EXEEXT@ bin/ntlm_auth@EXEEXT@ \
bin/smbcquotas@EXEEXT@
@@ -233,7 +233,8 @@ LIBMSRPC_OBJ = rpc_client/cli_lsarpc.o rpc_client/cli_samr.o \
rpc_client/cli_wkssvc.o rpc_client/cli_dfs.o \
rpc_client/cli_reg.o rpc_client/cli_pipe.o \
rpc_client/cli_spoolss.o rpc_client/cli_spoolss_notify.o \
- rpc_client/cli_ds.o rpc_client/cli_echo.o
+ rpc_client/cli_ds.o rpc_client/cli_echo.o \
+ rpc_client/cli_shutdown.o
REGOBJS_OBJ = registry/reg_objects.o
REGISTRY_OBJ = registry/reg_frontend.o registry/reg_cachehook.o registry/reg_printing.o \
@@ -274,7 +275,7 @@ RPC_PARSE_OBJ = rpc_parse/parse_lsa.o rpc_parse/parse_net.o \
rpc_parse/parse_samr.o rpc_parse/parse_srv.o \
rpc_parse/parse_wks.o rpc_parse/parse_ds.o \
rpc_parse/parse_spoolss.o rpc_parse/parse_dfs.o \
- rpc_parse/parse_echo.o \
+ rpc_parse/parse_echo.o rpc_parse/parse_shutdown.o \
$(REGOBJS_OBJ)
@@ -291,8 +292,8 @@ PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \
XML_OBJ = passdb/pdb_xml.o
MYSQL_OBJ = passdb/pdb_mysql.o
DEVEL_HELP_WEIRD_OBJ = modules/weird.o
-DEVEL_HELP_CP850_OBJ = modules/CP850.o
-DEVEL_HELP_CP437_OBJ = modules/CP437.o
+CP850_OBJ = modules/CP850.o
+CP437_OBJ = modules/CP437.o
GROUPDB_OBJ = groupdb/mapping.o
@@ -393,7 +394,8 @@ WREPL_OBJ1 = wrepld/server.o wrepld/process.o wrepld/parser.o wrepld/socket.o \
wrepld/partners.o
WREPL_OBJ = $(WREPL_OBJ1) $(PARAM_OBJ) $(UBIQX_OBJ) \
- $(PROFILE_OBJ) $(LIB_OBJ) $(POPT_LIB_OBJ)
+ $(PROFILE_OBJ) $(LIB_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ) \
+ $(LIBSAMBA_OBJ)
SWAT_OBJ1 = web/cgi.o web/diagnose.o web/startstop.o web/statuspage.o \
web/swat.o web/neg_lang.o
@@ -440,7 +442,7 @@ RPCCLIENT_OBJ1 = rpcclient/rpcclient.o rpcclient/cmd_lsarpc.o \
rpcclient/cmd_netlogon.o rpcclient/cmd_srvsvc.o \
rpcclient/cmd_dfs.o rpcclient/cmd_reg.o \
rpcclient/display_sec.o rpcclient/cmd_ds.o \
- rpcclient/cmd_echo.o
+ rpcclient/cmd_echo.o rpcclient/cmd_shutdown.o
RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \
$(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
@@ -449,7 +451,9 @@ RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \
$(LIBADS_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) \
$(SMBLDAP_OBJ) $(DCUTIL_OBJ) lib/dummyroot.o
-PAM_WINBIND_PICOBJ = nsswitch/pam_winbind.po nsswitch/wb_common.po lib/replace1.po lib/snprintf.po
+PAM_WINBIND_PICOBJ = nsswitch/pam_winbind.@PICSUFFIX@ \
+ nsswitch/wb_common.@PICSUFFIX@ lib/replace1.@PICSUFFIX@ \
+ lib/snprintf.@PICSUFFIX@
SMBW_OBJ1 = smbwrapper/smbw.o \
smbwrapper/smbw_dir.o smbwrapper/smbw_stat.o \
@@ -464,8 +468,10 @@ SMBWRAPPER_OBJ1 = smbwrapper/wrapped.o
SMBWRAPPER_OBJ = $(SMBW_OBJ) $(SMBWRAPPER_OBJ1)
LIBSMBCLIENT_OBJ = libsmb/libsmbclient.o libsmb/libsmb_compat.o \
- libsmb/libsmb_cache.o $(PARAM_OBJ) $(LIB_OBJ) \
- $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(UBIQX_OBJ)
+ libsmb/libsmb_cache.o \
+ $(PARAM_OBJ) $(LIB_OBJ) \
+ $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(UBIQX_OBJ) \
+ $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ)
# This shared library is intended for linking with unit test programs
# to test Samba internals. It's called libbigballofmud.so to
@@ -477,7 +483,7 @@ LIBBIGBALLOFMUD_OBJ = $(PARAM_OBJ) $(LIB_OBJ) $(UBIQX_OBJ) $(SECRETS_OBJ) \
$(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) \
$(GROUPDB_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ) lib/dummyroot.o
-LIBBIGBALLOFMUD_PICOBJS = $(LIBBIGBALLOFMUD_OBJ:.o=.po)
+LIBBIGBALLOFMUD_PICOBJS = $(LIBBIGBALLOFMUD_OBJ:.o=.@PICSUFFIX@)
CLIENT_OBJ1 = client/client.o client/clitar.o
@@ -581,17 +587,17 @@ PROTO_OBJ = $(SMBD_OBJ_MAIN) \
WINBIND_WINS_NSS_OBJ = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) \
$(LIBSMB_OBJ) $(LIB_OBJ) $(NSSWINS_OBJ) $(KRBCLIENT_OBJ)
-WINBIND_WINS_NSS_PICOBJS = $(WINBIND_WINS_NSS_OBJ:.o=.po)
+WINBIND_WINS_NSS_PICOBJS = $(WINBIND_WINS_NSS_OBJ:.o=.@PICSUFFIX@)
-PICOBJS = $(SMBWRAPPER_OBJ:.o=.po)
-LIBSMBCLIENT_PICOBJS = $(LIBSMBCLIENT_OBJ:.o=.po)
+PICOBJS = $(SMBWRAPPER_OBJ:.o=.@PICSUFFIX@)
+LIBSMBCLIENT_PICOBJS = $(LIBSMBCLIENT_OBJ:.o=.@PICSUFFIX@)
PAM_SMBPASS_OBJ_0 = pam_smbpass/pam_smb_auth.o pam_smbpass/pam_smb_passwd.o \
pam_smbpass/pam_smb_acct.o pam_smbpass/support.o \
lib/dummyroot.o $(PARAM_OBJ) $(LIB_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
$(SECRETS_OBJ) $(UBIQX_OBJ) $(SMBLDAP_OBJ) $(LIBSAMBA_OBJ)
-PAM_SMBPASS_PICOOBJ = $(PAM_SMBPASS_OBJ_0:.o=.po)
+PAM_SMBPASS_PICOOBJ = $(PAM_SMBPASS_OBJ_0:.o=.@PICSUFFIX@)
IDMAP_OBJ = sam/idmap.o sam/idmap_util.o @IDMAP_STATIC@
@@ -624,12 +630,14 @@ WBINFO_OBJ = nsswitch/wbinfo.o $(LIBSAMBA_OBJ) $(PARAM_OBJ) $(LIB_OBJ) \
WINBIND_NSS_OBJ = nsswitch/wb_common.o lib/replace1.o @WINBIND_NSS_EXTRA_OBJS@
-WINBIND_NSS_PICOBJS = $(WINBIND_NSS_OBJ:.o=.po) lib/snprintf.po
+WINBIND_NSS_PICOBJS = $(WINBIND_NSS_OBJ:.o=.@PICSUFFIX@) lib/snprintf.@PICSUFFIX@
POPT_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
popt/popthelp.o popt/poptparse.o
-TDBBACKUP_OBJ = tdb/tdbbackup.o tdb/tdbback.o $(TDBBASE_OBJ)
+TDBBACKUP_OBJ = tdb/tdbbackup.o tdb/tdbback.o lib/snprintf.o $(TDBBASE_OBJ)
+
+TDBDUMP_OBJ = tdb/tdbdump.o $(TDBBASE_OBJ)
NTLM_AUTH_OBJ = utils/ntlm_auth.o $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ) \
libsmb/asn1.o libsmb/spnego.o libsmb/clikrb5.o libads/kerberos.o \
@@ -682,7 +690,7 @@ everything: all libsmbclient debug2html smbfilter talloctort modules torture \
$(EVERYTHING_PROGS)
.SUFFIXES:
-.SUFFIXES: .c .o .po .lo
+.SUFFIXES: .c .o .@PICSUFFIX@ .lo
SHOWFLAGS:
@echo "Using FLAGS = $(FLAGS)"
@@ -716,25 +724,25 @@ dynconfig.o: dynconfig.c Makefile
@echo Compiling $*.c
@$(CC) $(FLAGS) $(PATH_FLAGS) -c $< -o $@
-dynconfig.po: dynconfig.c Makefile
+dynconfig.@PICSUFFIX@: dynconfig.c Makefile
@if (: >> $@ || : > $@) >/dev/null 2>&1; then rm -f $@; else \
dir=`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` $(MAKEDIR); fi
- @echo Compiling $*.c with @PICFLAG@
- @$(CC) -I. -I$(srcdir) $(FLAGS) $(PATH_FLAGS) @PICFLAG@ -c $< -o $*.@PICSUFFIX@
-@BROKEN_CC@ -mv `echo $@ | sed -e 's%^.*/%%g' -e 's%\.po$$%.o%'` $@
-@POBAD_CC@ @mv $*.po.o $@
+ @echo Compiling $*.c with @PICFLAGS@
+ @$(CC) -I. -I$(srcdir) $(FLAGS) $(PATH_FLAGS) @PICFLAGS@ -c $< -o $*.@PICSUFFIX@
+@BROKEN_CC@ -mv `echo $@ | sed -e 's%^.*/%%g' -e 's%\.@PICSUFFIX@$$%.o%'` $@
+@POBAD_CC@ @mv $*.@PICSUFFIX@.o $@
lib/version.o: lib/version.c include/version.h
@echo Compiling $*.c
@$(CC) -I. -I$(srcdir) $(FLAGS) $(PATH_FLAGS) -c $< -o $@
-lib/version.po: lib/version.c include/version.h
+lib/version.@PICSUFFIX@: lib/version.c include/version.h
@if (: >> $@ || : > $@) >/dev/null 2>&1; then rm -f $@; else \
dir=`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` $(MAKEDIR); fi
- @echo Compiling $*.c with @PICFLAG@
- @$(CC) -I. -I$(srcdir) $(FLAGS) $(PATH_FLAGS) @PICFLAG@ -c $< -o $*.@PICSUFFIX@
-@BROKEN_CC@ -mv `echo $@ | sed -e 's%^.*/%%g' -e 's%\.po$$%.o%'` $@
-@POBAD_CC@ @mv $*.po.o $@
+ @echo Compiling $*.c with @PICFLAGS@
+ @$(CC) -I. -I$(srcdir) $(FLAGS) $(PATH_FLAGS) @PICFLAGS@ -c $< -o $*.@PICSUFFIX@
+@BROKEN_CC@ -mv `echo $@ | sed -e 's%^.*/%%g' -e 's%\.@PICSUFFIX@$$%.o%'` $@
+@POBAD_CC@ @mv $*.@PICSUFFIX@.o $@
smbd/build_options.o: smbd/build_options.c Makefile include/config.h include/build_env.h include/proto.h
@echo Compiling $*.c
@@ -744,13 +752,13 @@ 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:
+.c.@PICSUFFIX@:
@if (: >> $@ || : > $@) >/dev/null 2>&1; then rm -f $@; else \
dir=`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` $(MAKEDIR); fi
- @echo Compiling $*.c with @PICFLAG@
- @$(CC) -I. -I$(srcdir) $(FLAGS) @PICFLAG@ -c $< -o $*.@PICSUFFIX@
-@BROKEN_CC@ -mv `echo $@ | sed -e 's%^.*/%%g' -e 's%\.po$$%.o%'` $@
-@POBAD_CC@ @mv $*.po.o $@
+ @echo Compiling $*.c with @PICFLAGS@
+ @$(CC) -I. -I$(srcdir) $(FLAGS) @PICFLAGS@ -c $< -o $*.@PICSUFFIX@
+@BROKEN_CC@ -mv `echo $@ | sed -e 's%^.*/%%g' -e 's%\.@PICSUFFIX@$$%.o%'` $@
+@POBAD_CC@ @mv $*.@PICSUFFIX@.o $@
bin/.dummy:
@if (: >> $@ || : > $@) >/dev/null 2>&1; then :; else \
@@ -759,8 +767,9 @@ bin/.dummy:
bin/smbd@EXEEXT@: $(SMBD_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBD_OBJ) $(KRB5LIBS) $(LDAP_LIBS) $(LDFLAGS) $(DYNEXP) $(PRINT_LIBS) \
- $(AUTH_LIBS) $(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) @POPTLIBS@
+ @$(CC) $(FLAGS) -o $@ $(SMBD_OBJ) $(LDFLAGS) $(LDAP_LIBS) \
+ $(KRB5LIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) \
+ $(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) @POPTLIBS@
bin/nmbd@EXEEXT@: $(NMBD_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@@ -777,7 +786,9 @@ bin/swat@EXEEXT@: $(SWAT_OBJ) @BUILD_POPT@ bin/.dummy
bin/rpcclient@EXEEXT@: $(RPCCLIENT_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(PASSDB_LIBS) $(RPCCLIENT_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS)
+ @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(PASSDB_LIBS) $(RPCCLIENT_OBJ) \
+ $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ \
+ $(KRB5LIBS) $(LDAP_LIBS)
bin/smbclient@EXEEXT@: $(CLIENT_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@@ -836,11 +847,12 @@ bin/smbtree@EXEEXT@: $(SMBTREE_OBJ) @BUILD_POPT@ bin/.dummy
bin/smbpasswd@EXEEXT@: $(SMBPASSWD_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBPASSWD_OBJ) $(PASSDB_LIBS) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS)
+ @$(CC) $(FLAGS) -o $@ $(SMBPASSWD_OBJ) $(LDFLAGS) $(PASSDB_LIBS) \
+ $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS)
bin/pdbedit@EXEEXT@: $(PDBEDIT_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(PDBEDIT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDB_LIBS)
+ @$(CC) $(FLAGS) -o $@ $(PDBEDIT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDB_LIBS) $(LDAP_LIBS)
bin/samtest@EXEEXT@: $(SAMTEST_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@@ -926,7 +938,7 @@ bin/smbwrapper.@SHLIBEXT@: $(PICOBJS) bin/.dummy
bin/libsmbclient.@SHLIBEXT@: $(LIBSMBCLIENT_PICOBJS)
@echo Linking libsmbclient shared library $@
- @$(SHLD) $(LDSHFLAGS) -o $@ $(LIBSMBCLIENT_PICOBJS) $(LDFLAGS) $(LIBS) \
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(LIBSMBCLIENT_PICOBJS) $(LDFLAGS) $(DYNEXP) $(LIBS) \
$(KRB5LIBS) $(LDAP_LIBS) \
@SONAMEFLAG@`basename $@`.$(LIBSMBCLIENT_MAJOR)
@@ -1022,112 +1034,112 @@ nsswitch/pam_winbind.@SHLIBEXT@: $(PAM_WINBIND_PICOBJ) bin/.dummy
@$(SHLD) $(LDSHFLAGS) -o $@ $(PAM_WINBIND_PICOBJ) \
@SONAMEFLAG@`basename $@` -lpam
-bin/rhosts.@SHLIBEXT@: $(AUTH_RHOSTS_OBJ:.o=.po)
+bin/rhosts.@SHLIBEXT@: $(AUTH_RHOSTS_OBJ:.o=.@PICSUFFIX@)
@echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_RHOSTS_OBJ:.o=.po) @SONAMEFLAG@`basename $@`
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_RHOSTS_OBJ:.o=.@PICSUFFIX@) @SONAMEFLAG@`basename $@`
-bin/builtin.@SHLIBEXT@: $(AUTH_BUILTIN_OBJ:.o=.po)
+bin/builtin.@SHLIBEXT@: $(AUTH_BUILTIN_OBJ:.o=.@PICSUFFIX@)
@echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_BUILTIN_OBJ:.o=.po) @SONAMEFLAG@`basename $@`
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_BUILTIN_OBJ:.o=.@PICSUFFIX@) @SONAMEFLAG@`basename $@`
-bin/domain.@SHLIBEXT@: $(AUTH_DOMAIN_OBJ:.o=.po)
+bin/domain.@SHLIBEXT@: $(AUTH_DOMAIN_OBJ:.o=.@PICSUFFIX@)
@echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_DOMAIN_OBJ:.o=.po) @SONAMEFLAG@`basename $@`
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_DOMAIN_OBJ:.o=.@PICSUFFIX@) @SONAMEFLAG@`basename $@`
-bin/smbserver.@SHLIBEXT@: $(AUTH_SERVER_OBJ:.o=.po)
+bin/smbserver.@SHLIBEXT@: $(AUTH_SERVER_OBJ:.o=.@PICSUFFIX@)
@echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_SERVER_OBJ:.o=.po) @SONAMEFLAG@`basename $@`
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_SERVER_OBJ:.o=.@PICSUFFIX@) @SONAMEFLAG@`basename $@`
-bin/winbind.@SHLIBEXT@: $(AUTH_WINBIND_OBJ:.o=.po)
+bin/winbind.@SHLIBEXT@: $(AUTH_WINBIND_OBJ:.o=.@PICSUFFIX@)
@echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_WINBIND_OBJ:.o=.po) @SONAMEFLAG@`basename $@`
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_WINBIND_OBJ:.o=.@PICSUFFIX@) @SONAMEFLAG@`basename $@`
-bin/unix.@SHLIBEXT@: $(AUTH_UNIX_OBJ:.o=.po)
+bin/unix.@SHLIBEXT@: $(AUTH_UNIX_OBJ:.o=.@PICSUFFIX@)
@echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_UNIX_OBJ:.o=.po) @SONAMEFLAG@`basename $@`
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_UNIX_OBJ:.o=.@PICSUFFIX@) @SONAMEFLAG@`basename $@`
-bin/sam.@SHLIBEXT@: $(AUTH_SAM_OBJ:.o=.po)
+bin/sam.@SHLIBEXT@: $(AUTH_SAM_OBJ:.o=.@PICSUFFIX@)
@echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_SAM_OBJ:.o=.po) @SONAMEFLAG@`basename $@`
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_SAM_OBJ:.o=.@PICSUFFIX@) @SONAMEFLAG@`basename $@`
-bin/mysql.@SHLIBEXT@: $(MYSQL_OBJ:.o=.po)
+bin/mysql.@SHLIBEXT@: $(MYSQL_OBJ:.o=.@PICSUFFIX@)
@echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(MYSQL_OBJ:.o=.po) @MYSQL_LIBS@ \
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(MYSQL_OBJ:.o=.@PICSUFFIX@) @MYSQL_LIBS@ \
@SONAMEFLAG@`basename $@`
-bin/ldapsam.@SHLIBEXT@: passdb/pdb_ldap.po
+bin/ldapsam.@SHLIBEXT@: passdb/pdb_ldap.@PICSUFFIX@
@echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) $(LDAP_LIBS) -o $@ passdb/pdb_ldap.po \
+ @$(SHLD) $(LDSHFLAGS) $(LDAP_LIBS) -o $@ passdb/pdb_ldap.@PICSUFFIX@ \
@SONAMEFLAG@`basename $@`
-bin/tdbsam.@SHLIBEXT@: passdb/pdb_tdb.po
+bin/tdbsam.@SHLIBEXT@: passdb/pdb_tdb.@PICSUFFIX@
@echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ passdb/pdb_tdb.po \
+ @$(SHLD) $(LDSHFLAGS) -o $@ passdb/pdb_tdb.@PICSUFFIX@ \
@SONAMEFLAG@`basename $@`
-bin/smbpasswd.@SHLIBEXT@: passdb/pdb_smbpasswd.po
+bin/smbpasswd.@SHLIBEXT@: passdb/pdb_smbpasswd.@PICSUFFIX@
@echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ passdb/pdb_smbpasswd.po \
+ @$(SHLD) $(LDSHFLAGS) -o $@ passdb/pdb_smbpasswd.@PICSUFFIX@ \
@SONAMEFLAG@`basename $@`
-bin/weird.@SHLIBEXT@: $(DEVEL_HELP_WEIRD_OBJ:.o=.po)
+bin/weird.@SHLIBEXT@: $(DEVEL_HELP_WEIRD_OBJ:.o=.@PICSUFFIX@)
@echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(DEVEL_HELP_WEIRD_OBJ:.o=.po) \
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(DEVEL_HELP_WEIRD_OBJ:.o=.@PICSUFFIX@) \
@SONAMEFLAG@`basename $@`
-bin/CP850.@SHLIBEXT@: $(DEVEL_HELP_CP850_OBJ:.o=.po)
+bin/CP850.@SHLIBEXT@: $(CP850_OBJ:.o=.@PICSUFFIX@)
@echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(DEVEL_HELP_CP850_OBJ:.o=.po) \
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(CP850_OBJ:.o=.@PICSUFFIX@) \
@SONAMEFLAG@`basename $@`
-bin/CP437.@SHLIBEXT@: $(DEVEL_HELP_CP437_OBJ:.o=.po)
+bin/CP437.@SHLIBEXT@: $(CP437_OBJ:.o=.@PICSUFFIX@)
@echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(DEVEL_HELP_CP437_OBJ:.o=.po) \
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(CP437_OBJ:.o=.@PICSUFFIX@) \
@SONAMEFLAG@`basename $@`
-bin/xml.@SHLIBEXT@: $(XML_OBJ:.o=.po)
+bin/xml.@SHLIBEXT@: $(XML_OBJ:.o=.@PICSUFFIX@)
@echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(XML_OBJ:.o=.po) @XML_LIBS@ \
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(XML_OBJ:.o=.@PICSUFFIX@) @XML_LIBS@ \
@SONAMEFLAG@`basename $@`
-bin/audit.@SHLIBEXT@: $(VFS_AUDIT_OBJ:.o=.po)
+bin/audit.@SHLIBEXT@: $(VFS_AUDIT_OBJ:.o=.@PICSUFFIX@)
@echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_AUDIT_OBJ:.o=.po) \
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_AUDIT_OBJ:.o=.@PICSUFFIX@) \
@SONAMEFLAG@`basename $@`
-bin/extd_audit.@SHLIBEXT@: $(VFS_EXTD_AUDIT_OBJ:.o=.po)
+bin/extd_audit.@SHLIBEXT@: $(VFS_EXTD_AUDIT_OBJ:.o=.@PICSUFFIX@)
@echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_EXTD_AUDIT_OBJ:.o=.po) \
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_EXTD_AUDIT_OBJ:.o=.@PICSUFFIX@) \
@SONAMEFLAG@`basename $@`
-bin/recycle.@SHLIBEXT@: $(VFS_RECYCLE_OBJ:.o=.po)
+bin/recycle.@SHLIBEXT@: $(VFS_RECYCLE_OBJ:.o=.@PICSUFFIX@)
@echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_RECYCLE_OBJ:.o=.po) \
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_RECYCLE_OBJ:.o=.@PICSUFFIX@) \
@SONAMEFLAG@`basename $@`
-bin/netatalk.@SHLIBEXT@: $(VFS_NETATALK_OBJ:.o=.po)
+bin/netatalk.@SHLIBEXT@: $(VFS_NETATALK_OBJ:.o=.@PICSUFFIX@)
@echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_NETATALK_OBJ:.o=.po) \
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_NETATALK_OBJ:.o=.@PICSUFFIX@) \
@SONAMEFLAG@`basename $@`
-bin/fake_perms.@SHLIBEXT@: $(VFS_FAKE_PERMS_OBJ:.o=.po)
+bin/fake_perms.@SHLIBEXT@: $(VFS_FAKE_PERMS_OBJ:.o=.@PICSUFFIX@)
@echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_FAKE_PERMS_OBJ:.o=.po) \
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_FAKE_PERMS_OBJ:.o=.@PICSUFFIX@) \
@SONAMEFLAG@`basename $@`
-bin/default_quota.@SHLIBEXT@: $(VFS_DEFAULT_QUOTA_OBJ:.o=.po)
+bin/default_quota.@SHLIBEXT@: $(VFS_DEFAULT_QUOTA_OBJ:.o=.@PICSUFFIX@)
@echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_DEFAULT_QUOTA_OBJ:.o=.po) \
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_DEFAULT_QUOTA_OBJ:.o=.@PICSUFFIX@) \
@SONAMEFLAG@`basename $@`
-bin/readonly.@SHLIBEXT@: $(VFS_READONLY_OBJ:.o=.po)
+bin/readonly.@SHLIBEXT@: $(VFS_READONLY_OBJ:.o=.@PICSUFFIX@)
@echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_READONLY_OBJ:.o=.po) \
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_READONLY_OBJ:.o=.@PICSUFFIX@) \
@SONAMEFLAG@`basename $@`
-bin/cap.@SHLIBEXT@: $(VFS_CAP_OBJ:.o=.po)
+bin/cap.@SHLIBEXT@: $(VFS_CAP_OBJ:.o=.@PICSUFFIX@)
@echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_CAP_OBJ:.o=.po) \
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_CAP_OBJ:.o=.@PICSUFFIX@) \
@SONAMEFLAG@`basename $@`
bin/wbinfo@EXEEXT@: $(WBINFO_OBJ) @BUILD_POPT@ bin/.dummy
@@ -1151,6 +1163,10 @@ bin/tdbbackup@EXEEXT@: $(TDBBACKUP_OBJ) bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(TDBBACKUP_OBJ)
+bin/tdbdump@EXEEXT@: $(TDBDUMP_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(CC) $(FLAGS) -o $@ $(TDBDUMP_OBJ)
+
bin/t_strcmp@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_strcmp.o
$(CC) $(FLAGS) -o $@ $(LIBS) torture/t_strcmp.o -L ./bin -lbigballofmud
@@ -1226,7 +1242,7 @@ PYTHON_OBJS = $(PARAM_OBJ) $(LIB_OBJ) $(LIBSMB_OBJ) $(RPC_PARSE_OBJ) \
$(UBIQX_OBJ) $(LIBMSRPC_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
$(SECRETS_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ) lib/dummyroot.o
-PYTHON_PICOBJS = $(PYTHON_OBJS:.o=.po)
+PYTHON_PICOBJS = $(PYTHON_OBJS:.o=.@PICSUFFIX@)
python_ext: $(PYTHON_PICOBJS)
@if test -z "$(PYTHON)"; then \
@@ -1291,10 +1307,10 @@ uninstallscripts:
@$(SHELL) $(srcdir)/script/uninstallscripts.sh $(INSTALLPERMS) $(DESTDIR)$(BINDIR) $(SCRIPTS)
# Toplevel clean files
-TOPFILES=dynconfig.o dynconfig.po
+TOPFILES=dynconfig.o dynconfig.@PICSUFFIX@
clean: delheaders python_clean
- -rm -f core */*~ *~ */*.o */*.po */*.@SHLIBEXT@ \
+ -rm -f core */*~ *~ */*.o */*.@PICSUFFIX@ */*.@SHLIBEXT@ \
$(TOPFILES) $(BIN_PROGS) $(SBIN_PROGS) $(MODULES) $(TORTURE_PROGS) \
$(LIBSMBCLIENT) $(EVERYTHING_PROGS) .headers.stamp
diff --git a/source/VERSION b/source/VERSION
index 5acae18c7d6..ea654aa76d6 100644
--- a/source/VERSION
+++ b/source/VERSION
@@ -41,7 +41,7 @@ SAMBA_VERSION_REVISION=
# e.g. SAMBA_VERSION_PRE_RELEASE=1 #
# -> "2.2.9pre1" #
########################################################
-SAMBA_VERSION_PRE_RELEASE=1
+SAMBA_VERSION_PRE_RELEASE=2
########################################################
# For 'rc' releases the version will be #
diff --git a/source/aclocal.m4 b/source/aclocal.m4
index c7831c58caa..96f265daf26 100644
--- a/source/aclocal.m4
+++ b/source/aclocal.m4
@@ -125,11 +125,11 @@ AC_DEFUN(AC_LIBTESTFUNC,
# may have different results.
#
# Note that using directly AS_VAR_PUSHDEF([ac_Lib], [ac_cv_lib_$1_$3])
-# is asking for troubles, since AC_CHECK_LIB($lib, fun) would give
+# is asking for trouble, since AC_CHECK_LIB($lib, fun) would give
# ac_cv_lib_$lib_fun, which is definitely not what was meant. Hence
# the AS_LITERAL_IF indirection.
#
-# FIXME: This macro is extremely suspicious. It DEFINEs unconditionnally,
+# FIXME: This macro is extremely suspicious. It DEFINEs unconditionally,
# whatever the FUNCTION, in addition to not being a *S macro. Note
# that the cache does depend upon the function we are looking for.
#
@@ -516,7 +516,7 @@ AC_DEFUN(jm_ICONV,
dnl those with the standalone portable libiconv installed).
AC_MSG_CHECKING(for iconv in $1)
jm_cv_func_iconv="no"
- jm_cv_lib_iconv=no
+ jm_cv_lib_iconv=""
jm_cv_giconv=no
jm_save_LIBS="$LIBS"
LIBS="$LIBS -lbiconv"
@@ -528,9 +528,10 @@ AC_DEFUN(jm_ICONV,
jm_cv_func_iconv=yes
jm_cv_biconv=yes
jm_cv_include="biconv.h"
- jm_cv_lib_iconv="yes")
+ jm_cv_lib_iconv="biconv")
LIBS="$jm_save_LIBS"
+ dnl Check for include in funny place but no lib needed
if test "$jm_cv_func_iconv" != yes; then
AC_TRY_LINK([#include <stdlib.h>
#include <giconv.h>],
@@ -539,8 +540,10 @@ AC_DEFUN(jm_ICONV,
iconv_close(cd);],
jm_cv_func_iconv=yes
jm_cv_include="giconv.h"
- jm_cv_giconv="yes")
+ jm_cv_giconv="yes"
+ jm_cv_lib_iconv="")
+ dnl Standard iconv.h include, lib in glibc or libc ...
if test "$jm_cv_func_iconv" != yes; then
AC_TRY_LINK([#include <stdlib.h>
#include <iconv.h>],
@@ -548,7 +551,8 @@ AC_DEFUN(jm_ICONV,
iconv(cd,NULL,NULL,NULL,NULL);
iconv_close(cd);],
jm_cv_include="iconv.h"
- jm_cv_func_iconv=yes)
+ jm_cv_func_iconv=yes
+ jm_cv_lib_iconv="")
if test "$jm_cv_lib_iconv" != yes; then
jm_save_LIBS="$LIBS"
@@ -561,8 +565,10 @@ AC_DEFUN(jm_ICONV,
jm_cv_lib_iconv=yes
jm_cv_func_iconv=yes
jm_cv_include="giconv.h"
- jm_cv_giconv=yes)
- LIBS="$jm_save_LIBS"
+ jm_cv_giconv=yes
+ jm_cv_lib_iconv="giconv")
+
+ LIBS="$jm_save_LIBS"
if test "$jm_cv_func_iconv" != yes; then
jm_save_LIBS="$LIBS"
@@ -572,9 +578,9 @@ AC_DEFUN(jm_ICONV,
[iconv_t cd = iconv_open("","");
iconv(cd,NULL,NULL,NULL,NULL);
iconv_close(cd);],
- jm_cv_lib_iconv=yes
jm_cv_include="iconv.h"
- jm_cv_func_iconv=yes)
+ jm_cv_func_iconv=yes
+ jm_cv_lib_iconv="iconv")
LIBS="$jm_save_LIBS"
fi
fi
@@ -599,17 +605,6 @@ AC_DEFUN(jm_ICONV,
else
AC_MSG_RESULT(no)
fi
- if test "$jm_cv_lib_iconv" = yes; then
- if test "$jm_cv_giconv" = yes; then
- LIBS="$LIBS -lgiconv"
- else
- if test "$jm_cv_biconv" = yes; then
- LIBS="$LIBS -lbiconv"
- else
- LIBS="$LIBS -liconv"
- fi
- fi
- fi
])
AC_DEFUN(rjs_CHARSET,[
diff --git a/source/auth/auth_builtin.c b/source/auth/auth_builtin.c
index f7cdfe3fd2e..96c2221652e 100644
--- a/source/auth/auth_builtin.c
+++ b/source/auth/auth_builtin.c
@@ -86,7 +86,7 @@ static NTSTATUS check_name_to_ntstatus_security(const struct auth_context *auth_
long error_num;
fstrcpy(user, user_info->smb_name.str);
- if (strncasecmp("NT_STATUS", user, strlen("NT_STATUS")) == 0) {
+ if (strnequal("NT_STATUS", user, strlen("NT_STATUS"))) {
strupper_m(user);
return nt_status_string_to_code(user);
}
diff --git a/source/auth/auth_sam.c b/source/auth/auth_sam.c
index ce97bd7df26..2a00b6fb807 100644
--- a/source/auth/auth_sam.c
+++ b/source/auth/auth_sam.c
@@ -172,6 +172,22 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
pdb_get_username(sampass)));
/* No return, we want to check the LM hash below in this case */
auth_flags &= (~(AUTH_FLAG_NTLMv2_RESP | AUTH_FLAG_NTLM_RESP));
+ } else {
+ /* Check for cleartext netlogon. Used by Exchange 5.5. */
+ unsigned char zeros[8];
+
+ memset(zeros,'\0',sizeof(zeros));
+ if (auth_context->challenge.length == sizeof(zeros) &&
+ (memcmp(auth_context->challenge.data, zeros, auth_context->challenge.length) == 0 ) &&
+ user_info->nt_resp.length) {
+ if ((nt_pw = pdb_get_nt_passwd(sampass)) != NULL) {
+ unsigned char pwhash[16];
+ mdfour(pwhash, user_info->nt_resp.data, user_info->nt_resp.length);
+ if (memcmp(pwhash, nt_pw, sizeof(pwhash)) == 0) {
+ return NT_STATUS_OK;
+ }
+ }
+ }
}
if (auth_flags & AUTH_FLAG_NTLMv2_RESP) {
diff --git a/source/auth/auth_util.c b/source/auth/auth_util.c
index 38037414661..dd0c0b02dde 100644
--- a/source/auth/auth_util.c
+++ b/source/auth/auth_util.c
@@ -942,7 +942,7 @@ static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx,
/* This is pointless -- there is no suport for differeing
unix and windows names. Make sure to always store the
- one we actuall looked up and succeeded. Have I mentioned
+ one we actually looked up and succeeded. Have I mentioned
why I hate the 'winbind use default domain' parameter?
--jerry */
@@ -951,6 +951,35 @@ static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx,
return pdb_init_sam_pw(sam_account, passwd);
}
+/****************************************************************************
+ Wrapper to allow the getpwnam() call to strip the domain name and
+ try again in case a local UNIX user is already there. Also run through
+ the username if we fallback to the username only.
+ ****************************************************************************/
+
+struct passwd *smb_getpwnam( char *domuser )
+{
+ struct passwd *pw;
+ char *p;
+ fstring mapped_username;
+
+ pw = Get_Pwnam( domuser );
+ if ( pw )
+ return pw;
+
+ /* fallback to looking up just the username */
+
+ p = strchr( domuser, *lp_winbind_separator() );
+
+ if ( p ) {
+ fstrcpy( mapped_username, p );
+ map_username( mapped_username );
+ return Get_Pwnam(mapped_username);
+ }
+
+ return NULL;
+}
+
/***************************************************************************
Make a server_info struct from the info3 returned by a domain logon
***************************************************************************/
diff --git a/source/client/client.c b/source/client/client.c
index ecece8942ec..5ee6913374a 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -2403,10 +2403,9 @@ static char **completion_fn(const char *text, int start, int end)
return matches;
cleanup:
- while (i >= 0) {
+ for (i = 0; i < count; i++)
free(matches[i]);
- i--;
- }
+
free(matches);
return NULL;
}
diff --git a/source/client/mount.cifs.c b/source/client/mount.cifs.c
index 7ab17a2b028..43b20e9d502 100755
--- a/source/client/mount.cifs.c
+++ b/source/client/mount.cifs.c
@@ -501,7 +501,7 @@ int main(int argc, char ** argv)
ipaddr = parse_server(share_name);
/* if(share_name == NULL)
return 1; */
- if (parse_options(strdup(orgoptions)))
+ if (orgoptions && parse_options(strdup(orgoptions)))
return 1;
if(got_user == 0)
diff --git a/source/configure.in b/source/configure.in
index 1bb97460ac1..db9f3d45987 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -141,7 +141,7 @@ AC_SUBST(LDSHFLAGS)
AC_SUBST(SONAMEFLAG)
AC_SUBST(SHLD)
AC_SUBST(HOST_OS)
-AC_SUBST(PICFLAG)
+AC_SUBST(PICFLAGS)
AC_SUBST(PICSUFFIX)
AC_SUBST(POBAD_CC)
AC_SUBST(SHLIBEXT)
@@ -266,19 +266,19 @@ 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`
+UNAME_S=`(uname -s) 2>/dev/null` || UNAME_S="unknown"
AC_MSG_CHECKING(uname -s)
AC_MSG_RESULT(${UNAME_S})
-UNAME_R=`uname -r`
+UNAME_R=`(uname -r) 2>/dev/null` || UNAME_R="unknown"
AC_MSG_CHECKING(uname -r)
AC_MSG_RESULT(${UNAME_R})
-UNAME_M=`uname -m`
+UNAME_M=`(uname -m) 2>/dev/null` || UNAME_M="unknown"
AC_MSG_CHECKING(uname -m)
AC_MSG_RESULT(${UNAME_M})
-UNAME_P=`uname -p`
+UNAME_P=`(uname -p) 2>/dev/null` || UNAME_P="unknown"
AC_MSG_CHECKING(uname -p)
AC_MSG_RESULT(${UNAME_P})
@@ -564,7 +564,7 @@ AC_HEADER_TIME
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(arpa/inet.h sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h)
AC_CHECK_HEADERS(unistd.h utime.h grp.h sys/id.h limits.h memory.h net/if.h)
-AC_CHECK_HEADERS(compat.h rpc/rpc.h rpcsvc/nis.h rpcsvc/yp_prot.h rpcsvc/ypclnt.h)
+AC_CHECK_HEADERS(rpc/rpc.h rpcsvc/nis.h rpcsvc/yp_prot.h rpcsvc/ypclnt.h)
AC_CHECK_HEADERS(sys/param.h ctype.h sys/wait.h sys/resource.h sys/ioctl.h sys/ipc.h sys/mode.h)
AC_CHECK_HEADERS(sys/mman.h sys/filio.h sys/priv.h sys/shm.h string.h strings.h stdlib.h sys/socket.h)
AC_CHECK_HEADERS(sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h termio.h)
@@ -591,7 +591,7 @@ case "$host_os" in
;;
esac
AC_CHECK_HEADERS(shadow.h netinet/ip.h netinet/tcp.h netinet/in_systm.h netinet/in_ip.h)
-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(nss.h nss_common.h nsswitch.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/attributes.h attr/xattr.h sys/cdefs.h glob.h)
@@ -1031,7 +1031,7 @@ HOST_OS="$host_os"
LDSHFLAGS="-shared"
SONAMEFLAG="#"
SHLD="\${CC} \${CFLAGS}"
-PICFLAG=""
+PICFLAGS=""
PICSUFFIX="po"
POBAD_CC="#"
SHLIBEXT="so"
@@ -1049,7 +1049,7 @@ if test "$enable_shared" = "yes"; then
BLDSHARED="true"
LDSHFLAGS="-shared"
DYNEXP="-Wl,--export-dynamic"
- PICFLAG="-fPIC"
+ PICFLAGS="-fPIC"
SONAMEFLAG="-Wl,-soname="
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
;;
@@ -1058,12 +1058,12 @@ if test "$enable_shared" = "yes"; then
LDSHFLAGS="-G"
SONAMEFLAG="-h "
if test "${GCC}" = "yes"; then
- PICFLAG="-fPIC"
+ PICFLAGS="-fPIC"
if test "${ac_cv_prog_gnu_ld}" = "yes"; then
DYNEXP="-Wl,-E"
fi
else
- PICFLAG="-KPIC"
+ PICFLAGS="-KPIC"
## ${CFLAGS} added for building 64-bit shared
## libs using Sun's Compiler
LDSHFLAGS="-G \${CFLAGS}"
@@ -1077,7 +1077,7 @@ if test "$enable_shared" = "yes"; then
BLDSHARED="true"
LDSHFLAGS="-G"
SONAMEFLAG="-Wl,-h,"
- PICFLAG="-KPIC" # Is this correct for SunOS
+ PICFLAGS="-KPIC" # Is this correct for SunOS
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
AC_DEFINE(BROKEN_GETGRNAM,1,[Does getgrnam work correctly])
;;
@@ -1085,7 +1085,7 @@ if test "$enable_shared" = "yes"; then
LDSHFLAGS="-shared"
DYNEXP="-Wl,--export-dynamic"
SONAMEFLAG="-Wl,-soname,"
- PICFLAG="-fPIC -DPIC"
+ PICFLAGS="-fPIC -DPIC"
AC_DEFINE(STAT_ST_BLOCKSIZE,512,[The size of a block])
AC_DEFINE(BROKEN_GETGRNAM,1,[Does getgrnam work correctly])
;;
@@ -1093,7 +1093,7 @@ if test "$enable_shared" = "yes"; then
LDSHFLAGS="-shared"
DYNEXP="-Wl,-Bdynamic"
SONAMEFLAG="-Wl,-soname,"
- PICFLAG="-fPIC"
+ PICFLAGS="-fPIC"
AC_DEFINE(STAT_ST_BLOCKSIZE,512,[The size of a block])
AC_DEFINE(BROKEN_GETGRNAM,1,[Does getgrnam work correctly])
;;
@@ -1107,9 +1107,9 @@ if test "$enable_shared" = "yes"; then
SONAMEFLAG="-soname "
SHLD="\${LD}"
if test "${GCC}" = "yes"; then
- PICFLAG="-fPIC"
+ PICFLAGS="-fPIC"
else
- PICFLAG="-KPIC"
+ PICFLAGS="-KPIC"
fi
AC_DEFINE(STAT_ST_BLOCKSIZE,512,[The size of a block])
;;
@@ -1117,7 +1117,7 @@ if test "$enable_shared" = "yes"; then
BLDSHARED="true"
LDSHFLAGS="-Wl,-bexpall,-bM:SRE,-bnoentry,-berok"
DYNEXP="-Wl,-brtl,-bexpall"
- PICFLAG="-O2"
+ PICFLAGS="-O2"
if test "${GCC}" != "yes"; then
## for funky AIX compiler using strncpy()
CFLAGS="$CFLAGS -D_LINUX_SOURCE_COMPAT -qmaxmem=32000"
@@ -1133,9 +1133,9 @@ if test "$enable_shared" = "yes"; then
SHLD="/usr/bin/ld"
LDSHFLAGS="-B symbolic -b -z"
SONAMEFLAG="+h "
- PICFLAG="+z"
+ PICFLAGS="+z"
elif test "${GCC}" = "yes"; then
- PICFLAG="-fPIC"
+ PICFLAGS="-fPIC"
fi
DYNEXP="-Wl,-E"
AC_DEFINE(STAT_ST_BLOCKSIZE,8192,[The size of a block])
@@ -1148,7 +1148,7 @@ if test "$enable_shared" = "yes"; then
BLDSHARED="true"
LDSHFLAGS="-shared"
SONAMEFLAG="-Wl,-soname,"
- PICFLAG="-fPIC"
+ PICFLAGS="-fPIC"
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
AC_DEFINE(BROKEN_GETGRNAM,1,[Does getgrnam work correctly])
;;
@@ -1159,7 +1159,7 @@ if test "$enable_shared" = "yes"; then
BLDSHARED="true"
LDSHFLAGS="-shared"
SONAMEFLAG="-Wl,-soname,"
- PICFLAG="-KPIC"
+ PICFLAGS="-KPIC"
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
;;
*next2*) AC_DEFINE(NEXT2,1,[Whether the host os is NeXT v2])
@@ -1219,17 +1219,12 @@ AC_CACHE_CHECK([whether building shared libraries actually works],
[ac_cv_shlib_works],[
ac_cv_shlib_works=no
# try building a trivial shared library
- if test "$PICSUFFIX" = "po"; then
- $CC $CPPFLAGS $CFLAGS $PICFLAG -c -o shlib.po ${srcdir-.}/tests/shlib.c &&
- $CC $CPPFLAGS $CFLAGS `eval echo $LDSHFLAGS` -o "shlib.$SHLIBEXT" shlib.po &&
- ac_cv_shlib_works=yes
- else
- $CC $CPPFLAGS $CFLAGS $PICFLAG -c -o shlib.$PICSUFFIX ${srcdir-.}/tests/shlib.c &&
- mv shlib.$PICSUFFIX shlib.po &&
- $CC $CPPFLAGS $CFLAGS `eval echo $LDSHFLAGS` -o "shlib.$SHLIBEXT" shlib.po &&
- ac_cv_shlib_works=yes
- fi
- rm -f "shlib.$SHLIBEXT" shlib.po
+ $CC $CPPFLAGS $CFLAGS $PICFLAGS -c -o \
+ shlib.$PICSUFFIX ${srcdir-.}/tests/shlib.c && \
+ $CC $CPPFLAGS $CFLAGS `eval echo $LDSHFLAGS` -o "shlib.$SHLIBEXT" \
+ shlib.$PICSUFFIX && \
+ ac_cv_shlib_works=yes
+ rm -f "shlib.$SHLIBEXT" shlib.$PICSUFFIX
])
if test $ac_cv_shlib_works = no; then
BLDSHARED=false
@@ -1396,12 +1391,22 @@ if test x"$samba_cv_HAVE_GETTIMEOFDAY_TZ" = x"yes"; then
AC_DEFINE(HAVE_GETTIMEOFDAY_TZ,1,[Whether gettimeofday() is available])
fi
-AC_CACHE_CHECK([for __va_copy],samba_cv_HAVE_VA_COPY,[
+AC_CACHE_CHECK([for va_copy],samba_cv_HAVE_VA_COPY,[
AC_TRY_LINK([#include <stdarg.h>
-va_list ap1,ap2;], [__va_copy(ap1,ap2);],
-samba_cv_HAVE_VA_COPY=yes,samba_cv_HAVE_VA_COPY=no)])
+va_list ap1,ap2;], [va_copy(ap1,ap2);],
+samba_cv_HAVE_VA_COPY=yes,
+samba_cv_HAVE_VA_COPY=no)])
if test x"$samba_cv_HAVE_VA_COPY" = x"yes"; then
- AC_DEFINE(HAVE_VA_COPY,1,[Whether __va_copy() is available])
+ AC_DEFINE(HAVE_VA_COPY,1,[Whether va_copy() is available])
+else
+ AC_CACHE_CHECK([for __va_copy],samba_cv_HAVE___VA_COPY,[
+ AC_TRY_LINK([#include <stdarg.h>
+ va_list ap1,ap2;], [__va_copy(ap1,ap2);],
+ samba_cv_HAVE___VA_COPY=yes,
+ samba_cv_HAVE___VA_COPY=no)])
+ if test x"$samba_cv_HAVE___VA_COPY" = x"yes"; then
+ AC_DEFINE(HAVE___VA_COPY,1,[Whether __va_copy() is available])
+ fi
fi
AC_CACHE_CHECK([for C99 vsnprintf],samba_cv_HAVE_C99_VSNPRINTF,[
@@ -1600,18 +1605,18 @@ for i in $LOOK_DIRS ; do
save_CPPFLAGS=$CPPFLAGS
CPPFLAGS="$CPPFLAGS -I$i/include"
dnl This is here to handle -withval stuff for --with-libiconv
- if test x"$ICONV_PATH_SPEC" = "xyes" ; then
- LDFLAGS="-L$i/lib"
- fi
+dnl Perhaps we should always add a -L
+ LDFLAGS="$LDFLAGS -L$i/lib"
LIBS=
export LDFLAGS LIBS CPPFLAGS
dnl Try to find iconv(3)
jm_ICONV($i)
if test "$ICONV_FOUND" = yes; then
+ LDFLAGS=$save_LDFLAG
LIB_ADD_DIR(LDFLAGS, "$i/lib")
CFLAGS_ADD_DIR(CPPFLAGS, "$i/include")
- LIBS="$save_LIBS $LIBS"
+ LIBS="$save_LIBS"
ICONV_LOCATION=$i
export LDFLAGS LIBS CPPFLAGS
dnl Now, check for a working iconv ... we want to do it here because
@@ -1623,6 +1628,9 @@ dnl there might be a working iconv further down the list of LOOK_DIRS
if test x"$ICONV_PATH_SPEC" = "xyes" ; then
LIBS="$LIBS -L$ICONV_LOCATION/lib"
fi
+ if test x"$jm_cv_lib_iconv" != x; then
+ LIBS="$LIBS -l$jm_cv_lib_iconv"
+ fi
dnl AC_CACHE_CHECK([for working iconv],samba_cv_HAVE_NATIVE_ICONV,[
default_dos_charset=no
default_display_charset=no
@@ -1675,9 +1683,14 @@ dnl ])
LIBS="$ic_save_LIBS"
if test x"$samba_cv_HAVE_NATIVE_ICONV" = x"yes"; then
- CPPFLAGS=$save_CPPFLAGS
- CFLAGS_ADD_DIR(CPPFLAGS, "$i/include")
- export CPPFLAGS
+ CPPFLAGS=$save_CPPFLAGS
+ LDFLAGS=$save_LDFLAGS
+ LIBS=$save_LIBS
+ if test x"$jm_cv_lib_iconv" != x; then
+ LIBS="$LIBS -l$jm_cv_lib_iconv"
+ fi
+ CFLAGS_ADD_DIR(CPPFLAGS, "$i/include")
+ export CPPFLAGS
AC_DEFINE(HAVE_NATIVE_ICONV,1,[Whether to use native iconv])
AC_DEFINE_UNQUOTED(DEFAULT_DOS_CHARSET,$default_dos_charset,[Default dos charset name])
AC_DEFINE_UNQUOTED(DEFAULT_DISPLAY_CHARSET,$default_display_charset,[Default display charset name])
@@ -2185,7 +2198,7 @@ AC_ARG_WITH(smbwrapper,
# Conditions under which smbwrapper should not be built.
- if test x$PICFLAG = x; then
+ if test x$PICFLAGS = x; then
echo No support for PIC code - disabling smbwrapper and smbsh
WRAPPROG=""
WRAP=""
@@ -2659,6 +2672,29 @@ if test x"$with_ads_support" != x"no"; then
[Whether in-memory keytabs are supported])
fi
+ AC_CACHE_CHECK([for key in krb5_keytab_entry],
+ samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEY,[
+ AC_TRY_COMPILE([#include <krb5.h>],
+ [krb5_keytab_entry entry; entry.key = NULL;],
+ samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEY=yes,
+ samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEY=no)])
+
+ if test x"$samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEY" = x"yes"; then
+ AC_DEFINE(HAVE_KRB5_KEYTAB_ENTRY_KEY,1,
+ [Whether krb5_keytab_entry has key member])
+ fi
+
+ AC_CACHE_CHECK([for keyblock in krb5_keytab_entry],
+ samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK,[
+ AC_TRY_COMPILE([#include <krb5.h>],
+ [krb5_keytab_entry entry; entry.keyblock.keytype = 0;],
+ samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK=yes,
+ samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK=no)])
+
+ if test x"$samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK" = x"yes"; then
+ AC_DEFINE(HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK,1,
+ [Whether krb5_keytab_entry has keyblock member])
+ fi
if test x"$ac_cv_lib_ext_krb5_krb5_mk_req_extended" = x"yes"; then
AC_DEFINE(HAVE_KRB5,1,[Whether to have KRB5 support])
@@ -2798,7 +2834,7 @@ AC_ARG_WITH(pam_smbpass,
# Conditions under which pam_smbpass should not be built.
- if test x$PICFLAG = x; then
+ if test x$PICFLAGS = x; then
AC_MSG_ERROR([No support for PIC code])
elif test x"$ac_cv_header_security_pam_appl_h" = x"no"; then
AC_MSG_ERROR([No security/pam_appl.h found])
diff --git a/source/include/includes.h b/source/include/includes.h
index 29bb53980fe..ebb09b6c6ce 100644
--- a/source/include/includes.h
+++ b/source/include/includes.h
@@ -333,10 +333,6 @@
#define PASSWORD_LENGTH 16
#endif /* HAVE_SYS_SECURITY_H */
-#ifdef HAVE_COMPAT_H
-#include <compat.h>
-#endif
-
#ifdef HAVE_STROPTS_H
#include <stropts.h>
#endif
@@ -1259,10 +1255,14 @@ int smb_xvasprintf(char **ptr, const char *format, va_list ap) PRINTF_ATTRIBUTE(
/* we need to use __va_copy() on some platforms */
#ifdef HAVE_VA_COPY
+#define VA_COPY(dest, src) va_copy(dest, src)
+#else
+#ifdef HAVE___VA_COPY
#define VA_COPY(dest, src) __va_copy(dest, src)
#else
#define VA_COPY(dest, src) (dest) = (src)
#endif
+#endif
#ifndef HAVE_TIMEGM
time_t timegm(struct tm *tm);
@@ -1315,4 +1315,11 @@ BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_conte
#endif
#define FALSE __ERROR__XX__DONT_USE_FALSE
+/* If we have blacklisted mmap() try to avoid using it accidentally by
+ undefining the HAVE_MMAP symbol. */
+
+#ifdef MMAP_BLACKLIST
+#undef HAVE_MMAP
+#endif
+
#endif /* _INCLUDES_H */
diff --git a/source/include/libsmbclient.h b/source/include/libsmbclient.h
index f5d653f6978..68c4a053d1b 100644
--- a/source/include/libsmbclient.h
+++ b/source/include/libsmbclient.h
@@ -5,6 +5,7 @@
Copyright (C) Richard Sharpe 2000
Copyright (C) John Terpsra 2000
Copyright (C) Tom Jansen (Ninja ISD) 2002
+ Copyright (C) Derrell Lipman 2003
This program is free software; you can redistribute it and/or modify
@@ -65,6 +66,9 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include <utime.h>
+
+#define SMBC_BASE_FD 10000 /* smallest file descriptor returned */
#define SMBC_WORKGROUP 1
#define SMBC_SERVER 2
@@ -113,6 +117,20 @@ struct smbc_dirent
char name[1];
};
+/*
+ * Flags for smbc_setxattr()
+ * Specify a bitwise OR of these, or 0 to add or replace as necessary
+ */
+#define SMBC_XATTR_FLAG_CREATE 0x1 /* fail if attr already exists */
+#define SMBC_XATTR_FLAG_REPLACE 0x2 /* fail if attr does not exist */
+
+
+#ifndef ENOATTR
+# define ENOATTR ENOENT /* No such attribute */
+#endif
+
+
+
/**@ingroup structure
* Structure that represents a print job.
@@ -358,6 +376,27 @@ struct _SMBCCTX {
off_t (*telldir) (SMBCCTX *c, SMBCFILE *dir);
int (*lseekdir)(SMBCCTX *c, SMBCFILE *dir, off_t offset);
int (*fstatdir)(SMBCCTX *c, SMBCFILE *dir, struct stat *st);
+ int (*chmod)(SMBCCTX *c, const char *fname, mode_t mode);
+ int (*utimes)(SMBCCTX *c,
+ const char *fname, struct timeval *tbuf);
+ int (*setxattr)(SMBCCTX *context,
+ const char *fname,
+ const char *name,
+ const void *value,
+ size_t size,
+ int flags);
+ int (*getxattr)(SMBCCTX *context,
+ const char *fname,
+ const char *name,
+ const void *value,
+ size_t size);
+ int (*removexattr)(SMBCCTX *context,
+ const char *fname,
+ const char *name);
+ int (*listxattr)(SMBCCTX *context,
+ const char *fname,
+ char *list,
+ size_t size);
/** callable functions for printing
*/
@@ -499,6 +538,30 @@ SMBCCTX * smbc_init_context(SMBCCTX * context);
int smbc_init(smbc_get_auth_data_fn fn, int debug);
+/**@ingroup misc
+ * Set or retrieve the compatibility library's context pointer
+ *
+ * @param context New context to use, or NULL. If a new context is provided,
+ * it must have allocated with smbc_new_context() and
+ * initialized with smbc_init_context(), followed, optionally,
+ * by some manual changes to some of the non-internal fields.
+ *
+ * @return The old context.
+ *
+ * @see smbc_new_context(), smbc_init_context(), smbc_init()
+ *
+ * @note This function may be called prior to smbc_init() to force
+ * use of the next context without any internal calls to
+ * smbc_new_context() or smbc_init_context(). It may also
+ * be called after smbc_init() has already called those two
+ * functions, to replace the existing context with a new one.
+ * Care should be taken, in this latter case, to ensure that
+ * the server cache and any data allocated by the
+ * authentication functions have been freed, if necessary.
+ */
+
+SMBCCTX * smbc_set_context(SMBCCTX * new_context);
+
/**@ingroup file
* Open a file on an SMB server.
*
@@ -1008,6 +1071,807 @@ int smbc_chown(const char *url, uid_t owner, gid_t group);
*/
int smbc_chmod(const char *url, mode_t mode);
+/**@ingroup attribute
+ * Change the last modification time on a file
+ *
+ * @param url The smb url of the file or directory to change
+ * the modification time of
+ *
+ * @param tbuf A timeval structure which contains the desired
+ * modification time. NOTE: Only the tv_sec field is
+ * used. The tv_usec (microseconds) portion is ignored.
+ *
+ * @return 0 on success, < 0 on error with errno set:
+ * - EINVAL The client library is not properly initialized
+ * - EPERM Permission was denied.
+ *
+ */
+int smbc_utimes(const char *url, struct timeval *tbuf);
+
+#ifdef HAVE_UTIME_H
+/**@ingroup attribute
+ * Change the last modification time on a file
+ *
+ * @param url The smb url of the file or directory to change
+ * the modification time of
+ *
+ * @param utbuf A utimebuf structure which contains the desired
+ * modification time. NOTE: Although the structure contains
+ * an access time as well, the access time value is ignored.
+ *
+ * @return 0 on success, < 0 on error with errno set:
+ * - EINVAL The client library is not properly initialized
+ * - ENOMEM No memory was available for internal needs
+ * - EPERM Permission was denied.
+ *
+ */
+int smbc_utime(const char *fname, struct utimbuf *utbuf);
+#endif
+
+/**@ingroup attribute
+ * Set extended attributes for a file. This is used for modifying a file's
+ * security descriptor (i.e. owner, group, and access control list)
+ *
+ * @param url The smb url of the file or directory to set extended
+ * attributes for.
+ *
+ * @param name The name of an attribute to be changed. Names are of
+ * one of the following forms:
+ *
+ * system.nt_sec_desc.<attribute name>
+ * system.nt_sec_desc.*
+ * system.nt_sec_desc.*+
+ *
+ * where <attribute name> is one of:
+ *
+ * revision
+ * owner
+ * owner+
+ * group
+ * group+
+ * acl:<name or sid>
+ * acl+:<name or sid>
+ *
+ * In the forms "system.nt_sec_desc.*" and
+ * "system.nt_sec_desc.*+", the asterisk and plus signs are
+ * literal, i.e. the string is provided exactly as shown, and
+ * the value parameter should contain a complete security
+ * descriptor with name:value pairs separated by tabs,
+ * commas, or newlines (not spaces!).
+ *
+ * The plus sign ('+') indicates that SIDs should be mapped
+ * to names. Without the plus sign, SIDs are not mapped;
+ * rather they are simply converted to a string format.
+ *
+ * @param value The value to be assigned to the specified attribute name.
+ * This buffer should contain only the attribute value if the
+ * name was of the "system.nt_sec_desc.<attribute_name>"
+ * form. If the name was of the "system.nt_sec_desc.*" form
+ * then a complete security descriptor, with name:value pairs
+ * separated by tabs, commas, or newlines (not spaces!),
+ * should be provided in this value buffer. A complete
+ * security descriptor will contain one or more entries
+ * selected from the following:
+ *
+ * REVISION:<revision number>
+ * OWNER:<sid or name>
+ * GROUP:<sid or name>
+ * ACL:<sid or name>:<type>/<flags>/<mask>
+ *
+ * The revision of the ACL specifies the internal Windows NT
+ * ACL revision for the security descriptor. If not specified
+ * it defaults to 1. Using values other than 1 may cause
+ * strange behaviour.
+ *
+ * The owner and group specify the owner and group sids for
+ * the object. If the attribute name (either '*+' with a
+ * complete security descriptor, or individual 'owner+' or
+ * 'group+' attribute names) ended with a plus sign, the
+ * specified name is resolved to a SID value, using the
+ * server on which the file or directory resides. Otherwise,
+ * the value should be provided in SID-printable format as
+ * S-1-x-y-z, and is used directly. The <sid or name>
+ * associated with the ACL: attribute should be provided
+ * similarly.
+ *
+ * @param size The number of the bytes of data in the value buffer
+ *
+ * @param flags A bit-wise OR of zero or more of the following:
+ * SMBC_XATTR_FLAG_CREATE -
+ * fail if the named attribute already exists
+ * SMBC_XATTR_FLAG_REPLACE -
+ * fail if the attribute does not already exist
+ *
+ * If neither flag is specified, the specified attributes
+ * will be added or replace existing attributes of the same
+ * name, as necessary.
+ *
+ * @return 0 on success, < 0 on error with errno set:
+ * - EINVAL The client library is not properly initialized
+ * or one of the parameters is not of a correct
+ * form
+ * - ENOMEM No memory was available for internal needs
+ * - EEXIST If the attribute already exists and the flag
+ * SMBC_XATTR_FLAG_CREAT was specified
+ * - ENOATTR If the attribute does not exist and the flag
+ * SMBC_XATTR_FLAG_REPLACE was specified
+ * - EPERM Permission was denied.
+ * - ENOTSUP The referenced file system does not support
+ * extended attributes
+ *
+ * @note Attribute names are compared in a case-insensitive
+ * fashion. All of the following are equivalent, although
+ * the all-lower-case name is the preferred format:
+ * system.nt_sec_desc.owner
+ * SYSTEM.NT_SEC_DESC.OWNER
+ * sYsTeM.nt_sEc_desc.owNER
+ *
+ */
+int smbc_setxattr(const char *url,
+ const char *name,
+ const void *value,
+ size_t size,
+ int flags);
+
+
+/**@ingroup attribute
+ * Set extended attributes for a file. This is used for modifying a file's
+ * security descriptor (i.e. owner, group, and access control list). The
+ * POSIX function which this maps to would act on a symbolic link rather than
+ * acting on what the symbolic link points to, but with no symbolic links in
+ * SMB file systems, this function is functionally identical to
+ * smbc_setxattr().
+ *
+ * @param url The smb url of the file or directory to set extended
+ * attributes for.
+ *
+ * @param name The name of an attribute to be changed. Names are of
+ * one of the following forms:
+ *
+ * system.nt_sec_desc.<attribute name>
+ * system.nt_sec_desc.*
+ * system.nt_sec_desc.*+
+ *
+ * where <attribute name> is one of:
+ *
+ * revision
+ * owner
+ * owner+
+ * group
+ * group+
+ * acl:<name or sid>
+ * acl+:<name or sid>
+ *
+ * In the forms "system.nt_sec_desc.*" and
+ * "system.nt_sec_desc.*+", the asterisk and plus signs are
+ * literal, i.e. the string is provided exactly as shown, and
+ * the value parameter should contain a complete security
+ * descriptor with name:value pairs separated by tabs,
+ * commas, or newlines (not spaces!).
+ *
+ * The plus sign ('+') indicates that SIDs should be mapped
+ * to names. Without the plus sign, SIDs are not mapped;
+ * rather they are simply converted to a string format.
+ *
+ * @param value The value to be assigned to the specified attribute name.
+ * This buffer should contain only the attribute value if the
+ * name was of the "system.nt_sec_desc.<attribute_name>"
+ * form. If the name was of the "system.nt_sec_desc.*" form
+ * then a complete security descriptor, with name:value pairs
+ * separated by tabs, commas, or newlines (not spaces!),
+ * should be provided in this value buffer. A complete
+ * security descriptor will contain one or more entries
+ * selected from the following:
+ *
+ * REVISION:<revision number>
+ * OWNER:<sid or name>
+ * GROUP:<sid or name>
+ * ACL:<sid or name>:<type>/<flags>/<mask>
+ *
+ * The revision of the ACL specifies the internal Windows NT
+ * ACL revision for the security descriptor. If not specified
+ * it defaults to 1. Using values other than 1 may cause
+ * strange behaviour.
+ *
+ * The owner and group specify the owner and group sids for
+ * the object. If the attribute name (either '*+' with a
+ * complete security descriptor, or individual 'owner+' or
+ * 'group+' attribute names) ended with a plus sign, the
+ * specified name is resolved to a SID value, using the
+ * server on which the file or directory resides. Otherwise,
+ * the value should be provided in SID-printable format as
+ * S-1-x-y-z, and is used directly. The <sid or name>
+ * associated with the ACL: attribute should be provided
+ * similarly.
+ *
+ * @param size The number of the bytes of data in the value buffer
+ *
+ * @param flags A bit-wise OR of zero or more of the following:
+ * SMBC_XATTR_FLAG_CREATE -
+ * fail if the named attribute already exists
+ * SMBC_XATTR_FLAG_REPLACE -
+ * fail if the attribute does not already exist
+ *
+ * If neither flag is specified, the specified attributes
+ * will be added or replace existing attributes of the same
+ * name, as necessary.
+ *
+ * @return 0 on success, < 0 on error with errno set:
+ * - EINVAL The client library is not properly initialized
+ * or one of the parameters is not of a correct
+ * form
+ * - ENOMEM No memory was available for internal needs
+ * - EEXIST If the attribute already exists and the flag
+ * SMBC_XATTR_FLAG_CREAT was specified
+ * - ENOATTR If the attribute does not exist and the flag
+ * SMBC_XATTR_FLAG_REPLACE was specified
+ * - EPERM Permission was denied.
+ * - ENOTSUP The referenced file system does not support
+ * extended attributes
+ *
+ * @note Attribute names are compared in a case-insensitive
+ * fashion. All of the following are equivalent, although
+ * the all-lower-case name is the preferred format:
+ * system.nt_sec_desc.owner
+ * SYSTEM.NT_SEC_DESC.OWNER
+ * sYsTeM.nt_sEc_desc.owNER
+ *
+ */
+int smbc_lsetxattr(const char *url,
+ const char *name,
+ const void *value,
+ size_t size,
+ int flags);
+
+
+/**@ingroup attribute
+ * Set extended attributes for a file. This is used for modifying a file's
+ * security descriptor (i.e. owner, group, and access control list)
+ *
+ * @param fd A file descriptor associated with an open file (as
+ * previously returned by smbc_open(), to get extended
+ * attributes for.
+ *
+ * @param name The name of an attribute to be changed. Names are of
+ * one of the following forms:
+ *
+ * system.nt_sec_desc.<attribute name>
+ * system.nt_sec_desc.*
+ * system.nt_sec_desc.*+
+ *
+ * where <attribute name> is one of:
+ *
+ * revision
+ * owner
+ * owner+
+ * group
+ * group+
+ * acl:<name or sid>
+ * acl+:<name or sid>
+ *
+ * In the forms "system.nt_sec_desc.*" and
+ * "system.nt_sec_desc.*+", the asterisk and plus signs are
+ * literal, i.e. the string is provided exactly as shown, and
+ * the value parameter should contain a complete security
+ * descriptor with name:value pairs separated by tabs,
+ * commas, or newlines (not spaces!).
+ *
+ * The plus sign ('+') indicates that SIDs should be mapped
+ * to names. Without the plus sign, SIDs are not mapped;
+ * rather they are simply converted to a string format.
+ *
+ * @param value The value to be assigned to the specified attribute name.
+ * This buffer should contain only the attribute value if the
+ * name was of the "system.nt_sec_desc.<attribute_name>"
+ * form. If the name was of the "system.nt_sec_desc.*" form
+ * then a complete security descriptor, with name:value pairs
+ * separated by tabs, commas, or newlines (not spaces!),
+ * should be provided in this value buffer. A complete
+ * security descriptor will contain one or more entries
+ * selected from the following:
+ *
+ * REVISION:<revision number>
+ * OWNER:<sid or name>
+ * GROUP:<sid or name>
+ * ACL:<sid or name>:<type>/<flags>/<mask>
+ *
+ * The revision of the ACL specifies the internal Windows NT
+ * ACL revision for the security descriptor. If not specified
+ * it defaults to 1. Using values other than 1 may cause
+ * strange behaviour.
+ *
+ * The owner and group specify the owner and group sids for
+ * the object. If the attribute name (either '*+' with a
+ * complete security descriptor, or individual 'owner+' or
+ * 'group+' attribute names) ended with a plus sign, the
+ * specified name is resolved to a SID value, using the
+ * server on which the file or directory resides. Otherwise,
+ * the value should be provided in SID-printable format as
+ * S-1-x-y-z, and is used directly. The <sid or name>
+ * associated with the ACL: attribute should be provided
+ * similarly.
+ *
+ * @param size The number of the bytes of data in the value buffer
+ *
+ * @param flags A bit-wise OR of zero or more of the following:
+ * SMBC_XATTR_FLAG_CREATE -
+ * fail if the named attribute already exists
+ * SMBC_XATTR_FLAG_REPLACE -
+ * fail if the attribute does not already exist
+ *
+ * If neither flag is specified, the specified attributes
+ * will be added or replace existing attributes of the same
+ * name, as necessary.
+ *
+ * @return 0 on success, < 0 on error with errno set:
+ * - EINVAL The client library is not properly initialized
+ * or one of the parameters is not of a correct
+ * form
+ * - ENOMEM No memory was available for internal needs
+ * - EEXIST If the attribute already exists and the flag
+ * SMBC_XATTR_FLAG_CREAT was specified
+ * - ENOATTR If the attribute does not exist and the flag
+ * SMBC_XATTR_FLAG_REPLACE was specified
+ * - EPERM Permission was denied.
+ * - ENOTSUP The referenced file system does not support
+ * extended attributes
+ *
+ * @note Attribute names are compared in a case-insensitive
+ * fashion. All of the following are equivalent, although
+ * the all-lower-case name is the preferred format:
+ * system.nt_sec_desc.owner
+ * SYSTEM.NT_SEC_DESC.OWNER
+ * sYsTeM.nt_sEc_desc.owNER
+ *
+ */
+int smbc_fsetxattr(int fd,
+ const char *name,
+ const void *value,
+ size_t size,
+ int flags);
+
+
+/**@ingroup attribute
+ * Get extended attributes for a file.
+ *
+ * @param url The smb url of the file or directory to get extended
+ * attributes for.
+ *
+ * @param name The name of an attribute to be retrieved. Names are of
+ * one of the following forms:
+ *
+ * system.nt_sec_desc.<attribute name>
+ * system.nt_sec_desc.*
+ * system.nt_sec_desc.*+
+ *
+ * where <attribute name> is one of:
+ *
+ * revision
+ * owner
+ * owner+
+ * group
+ * group+
+ * acl:<name or sid>
+ * acl+:<name or sid>
+ *
+ * In the forms "system.nt_sec_desc.*" and
+ * "system.nt_sec_desc.*+", the asterisk and plus signs are
+ * literal, i.e. the string is provided exactly as shown, and
+ * the value parameter will return a complete security
+ * descriptor with name:value pairs separated by tabs,
+ * commas, or newlines (not spaces!).
+ *
+ * The plus sign ('+') indicates that SIDs should be mapped
+ * to names. Without the plus sign, SIDs are not mapped;
+ * rather they are simply converted to a string format.
+ *
+ * @param value A pointer to a buffer in which the value of the specified
+ * attribute will be placed (unless size is zero).
+ *
+ * @param size The size of the buffer pointed to by value. This parameter
+ * may also be zero, in which case the size of the buffer
+ * required to hold the attribute value will be returned,
+ * but nothing will be placed into the value buffer.
+ *
+ * @return 0 on success, < 0 on error with errno set:
+ * - EINVAL The client library is not properly initialized
+ * or one of the parameters is not of a correct
+ * form
+ * - ENOMEM No memory was available for internal needs
+ * - EEXIST If the attribute already exists and the flag
+ * SMBC_XATTR_FLAG_CREAT was specified
+ * - ENOATTR If the attribute does not exist and the flag
+ * SMBC_XATTR_FLAG_REPLACE was specified
+ * - EPERM Permission was denied.
+ * - ENOTSUP The referenced file system does not support
+ * extended attributes
+ *
+ */
+int smbc_getxattr(const char *url,
+ const char *name,
+ const void *value,
+ size_t size);
+
+
+/**@ingroup attribute
+ * Get extended attributes for a file. The POSIX function which this maps to
+ * would act on a symbolic link rather than acting on what the symbolic link
+ * points to, but with no symbolic links in SMB file systems, this function
+ * is functionally identical to smbc_getxattr().
+ *
+ * @param url The smb url of the file or directory to get extended
+ * attributes for.
+ *
+ * @param name The name of an attribute to be retrieved. Names are of
+ * one of the following forms:
+ *
+ * system.nt_sec_desc.<attribute name>
+ * system.nt_sec_desc.*
+ * system.nt_sec_desc.*+
+ *
+ * where <attribute name> is one of:
+ *
+ * revision
+ * owner
+ * owner+
+ * group
+ * group+
+ * acl:<name or sid>
+ * acl+:<name or sid>
+ *
+ * In the forms "system.nt_sec_desc.*" and
+ * "system.nt_sec_desc.*+", the asterisk and plus signs are
+ * literal, i.e. the string is provided exactly as shown, and
+ * the value parameter will return a complete security
+ * descriptor with name:value pairs separated by tabs,
+ * commas, or newlines (not spaces!).
+ *
+ * The plus sign ('+') indicates that SIDs should be mapped
+ * to names. Without the plus sign, SIDs are not mapped;
+ * rather they are simply converted to a string format.
+ *
+ * @param value A pointer to a buffer in which the value of the specified
+ * attribute will be placed (unless size is zero).
+ *
+ * @param size The size of the buffer pointed to by value. This parameter
+ * may also be zero, in which case the size of the buffer
+ * required to hold the attribute value will be returned,
+ * but nothing will be placed into the value buffer.
+ *
+ * @return 0 on success, < 0 on error with errno set:
+ * - EINVAL The client library is not properly initialized
+ * or one of the parameters is not of a correct
+ * form
+ * - ENOMEM No memory was available for internal needs
+ * - EEXIST If the attribute already exists and the flag
+ * SMBC_XATTR_FLAG_CREAT was specified
+ * - ENOATTR If the attribute does not exist and the flag
+ * SMBC_XATTR_FLAG_REPLACE was specified
+ * - EPERM Permission was denied.
+ * - ENOTSUP The referenced file system does not support
+ * extended attributes
+ *
+ */
+int smbc_lgetxattr(const char *url,
+ const char *name,
+ const void *value,
+ size_t size);
+
+
+/**@ingroup attribute
+ * Get extended attributes for a file.
+ *
+ * @param fd A file descriptor associated with an open file (as
+ * previously returned by smbc_open(), to get extended
+ * attributes for.
+ *
+ * @param name The name of an attribute to be retrieved. Names are of
+ * one of the following forms:
+ *
+ * system.nt_sec_desc.<attribute name>
+ * system.nt_sec_desc.*
+ * system.nt_sec_desc.*+
+ *
+ * where <attribute name> is one of:
+ *
+ * revision
+ * owner
+ * owner+
+ * group
+ * group+
+ * acl:<name or sid>
+ * acl+:<name or sid>
+ *
+ * In the forms "system.nt_sec_desc.*" and
+ * "system.nt_sec_desc.*+", the asterisk and plus signs are
+ * literal, i.e. the string is provided exactly as shown, and
+ * the value parameter will return a complete security
+ * descriptor with name:value pairs separated by tabs,
+ * commas, or newlines (not spaces!).
+ *
+ * The plus sign ('+') indicates that SIDs should be mapped
+ * to names. Without the plus sign, SIDs are not mapped;
+ * rather they are simply converted to a string format.
+ *
+ * @param value A pointer to a buffer in which the value of the specified
+ * attribute will be placed (unless size is zero).
+ *
+ * @param size The size of the buffer pointed to by value. This parameter
+ * may also be zero, in which case the size of the buffer
+ * required to hold the attribute value will be returned,
+ * but nothing will be placed into the value buffer.
+ *
+ * @return 0 on success, < 0 on error with errno set:
+ * - EINVAL The client library is not properly initialized
+ * or one of the parameters is not of a correct
+ * form
+ * - ENOMEM No memory was available for internal needs
+ * - EEXIST If the attribute already exists and the flag
+ * SMBC_XATTR_FLAG_CREAT was specified
+ * - ENOATTR If the attribute does not exist and the flag
+ * SMBC_XATTR_FLAG_REPLACE was specified
+ * - EPERM Permission was denied.
+ * - ENOTSUP The referenced file system does not support
+ * extended attributes
+ *
+ */
+int smbc_fgetxattr(int fd,
+ const char *name,
+ const void *value,
+ size_t size);
+
+
+/**@ingroup attribute
+ * Remove extended attributes for a file. This is used for modifying a file's
+ * security descriptor (i.e. owner, group, and access control list)
+ *
+ * @param url The smb url of the file or directory to remove the extended
+ * attributes for.
+ *
+ * @param name The name of an attribute to be removed. Names are of
+ * one of the following forms:
+ *
+ * system.nt_sec_desc.<attribute name>
+ * system.nt_sec_desc.*
+ * system.nt_sec_desc.*+
+ *
+ * where <attribute name> is one of:
+ *
+ * revision
+ * owner
+ * owner+
+ * group
+ * group+
+ * acl:<name or sid>
+ * acl+:<name or sid>
+ *
+ * In the forms "system.nt_sec_desc.*" and
+ * "system.nt_sec_desc.*+", the asterisk and plus signs are
+ * literal, i.e. the string is provided exactly as shown, and
+ * the value parameter will return a complete security
+ * descriptor with name:value pairs separated by tabs,
+ * commas, or newlines (not spaces!).
+ *
+ * The plus sign ('+') indicates that SIDs should be mapped
+ * to names. Without the plus sign, SIDs are not mapped;
+ * rather they are simply converted to a string format.
+ *
+ * @return 0 on success, < 0 on error with errno set:
+ * - EINVAL The client library is not properly initialized
+ * - ENOMEM No memory was available for internal needs
+ * - EPERM Permission was denied.
+ * - ENOTSUP The referenced file system does not support
+ * extended attributes
+ *
+ */
+int smbc_removexattr(const char *url,
+ const char *name);
+
+
+/**@ingroup attribute
+ * Remove extended attributes for a file. This is used for modifying a file's
+ * security descriptor (i.e. owner, group, and access control list) The POSIX
+ * function which this maps to would act on a symbolic link rather than acting
+ * on what the symbolic link points to, but with no symbolic links in SMB file
+ * systems, this function is functionally identical to smbc_removexattr().
+ *
+ * @param url The smb url of the file or directory to remove the extended
+ * attributes for.
+ *
+ * @param name The name of an attribute to be removed. Names are of
+ * one of the following forms:
+ *
+ * system.nt_sec_desc.<attribute name>
+ * system.nt_sec_desc.*
+ * system.nt_sec_desc.*+
+ *
+ * where <attribute name> is one of:
+ *
+ * revision
+ * owner
+ * owner+
+ * group
+ * group+
+ * acl:<name or sid>
+ * acl+:<name or sid>
+ *
+ * In the forms "system.nt_sec_desc.*" and
+ * "system.nt_sec_desc.*+", the asterisk and plus signs are
+ * literal, i.e. the string is provided exactly as shown, and
+ * the value parameter will return a complete security
+ * descriptor with name:value pairs separated by tabs,
+ * commas, or newlines (not spaces!).
+ *
+ * The plus sign ('+') indicates that SIDs should be mapped
+ * to names. Without the plus sign, SIDs are not mapped;
+ * rather they are simply converted to a string format.
+ *
+ * @return 0 on success, < 0 on error with errno set:
+ * - EINVAL The client library is not properly initialized
+ * - ENOMEM No memory was available for internal needs
+ * - EPERM Permission was denied.
+ * - ENOTSUP The referenced file system does not support
+ * extended attributes
+ *
+ */
+int smbc_lremovexattr(const char *url,
+ const char *name);
+
+
+/**@ingroup attribute
+ * Remove extended attributes for a file. This is used for modifying a file's
+ * security descriptor (i.e. owner, group, and access control list)
+ *
+ * @param fd A file descriptor associated with an open file (as
+ * previously returned by smbc_open(), to get extended
+ * attributes for.
+ *
+ * @param name The name of an attribute to be removed. Names are of
+ * one of the following forms:
+ *
+ * system.nt_sec_desc.<attribute name>
+ * system.nt_sec_desc.*
+ * system.nt_sec_desc.*+
+ *
+ * where <attribute name> is one of:
+ *
+ * revision
+ * owner
+ * owner+
+ * group
+ * group+
+ * acl:<name or sid>
+ * acl+:<name or sid>
+ *
+ * In the forms "system.nt_sec_desc.*" and
+ * "system.nt_sec_desc.*+", the asterisk and plus signs are
+ * literal, i.e. the string is provided exactly as shown, and
+ * the value parameter will return a complete security
+ * descriptor with name:value pairs separated by tabs,
+ * commas, or newlines (not spaces!).
+ *
+ * The plus sign ('+') indicates that SIDs should be mapped
+ * to names. Without the plus sign, SIDs are not mapped;
+ * rather they are simply converted to a string format.
+ *
+ * @return 0 on success, < 0 on error with errno set:
+ * - EINVAL The client library is not properly initialized
+ * - ENOMEM No memory was available for internal needs
+ * - EPERM Permission was denied.
+ * - ENOTSUP The referenced file system does not support
+ * extended attributes
+ *
+ */
+int smbc_fremovexattr(int fd,
+ const char *name);
+
+
+/**@ingroup attribute
+ * List the supported extended attribute names associated with a file
+ *
+ * @param url The smb url of the file or directory to list the extended
+ * attributes for.
+ *
+ * @param list A pointer to a buffer in which the list of attributes for
+ * the specified file or directory will be placed (unless
+ * size is zero).
+ *
+ * @param size The size of the buffer pointed to by list. This parameter
+ * may also be zero, in which case the size of the buffer
+ * required to hold all of the attribute names will be
+ * returned, but nothing will be placed into the list buffer.
+ *
+ * @return 0 on success, < 0 on error with errno set:
+ * - EINVAL The client library is not properly initialized
+ * - ENOMEM No memory was available for internal needs
+ * - EPERM Permission was denied.
+ * - ENOTSUP The referenced file system does not support
+ * extended attributes
+ *
+ * @note This function always returns all attribute names supported
+ * by NT file systems, regardless of wether the referenced
+ * file system supports extended attributes (e.g. a Windows
+ * 2000 machine supports extended attributes if NTFS is used,
+ * but not if FAT is used, and Windows 98 doesn't support
+ * extended attributes at all. Whether this is a feature or
+ * a bug is yet to be decided.
+ */
+int smbc_listxattr(const char *url,
+ char *list,
+ size_t size);
+
+/**@ingroup attribute
+ * List the supported extended attribute names associated with a file The
+ * POSIX function which this maps to would act on a symbolic link rather than
+ * acting on what the symbolic link points to, but with no symbolic links in
+ * SMB file systems, this function is functionally identical to
+ * smbc_listxattr().
+ *
+ * @param url The smb url of the file or directory to list the extended
+ * attributes for.
+ *
+ * @param list A pointer to a buffer in which the list of attributes for
+ * the specified file or directory will be placed (unless
+ * size is zero).
+ *
+ * @param size The size of the buffer pointed to by list. This parameter
+ * may also be zero, in which case the size of the buffer
+ * required to hold all of the attribute names will be
+ * returned, but nothing will be placed into the list buffer.
+ *
+ * @return 0 on success, < 0 on error with errno set:
+ * - EINVAL The client library is not properly initialized
+ * - ENOMEM No memory was available for internal needs
+ * - EPERM Permission was denied.
+ * - ENOTSUP The referenced file system does not support
+ * extended attributes
+ *
+ * @note This function always returns all attribute names supported
+ * by NT file systems, regardless of wether the referenced
+ * file system supports extended attributes (e.g. a Windows
+ * 2000 machine supports extended attributes if NTFS is used,
+ * but not if FAT is used, and Windows 98 doesn't support
+ * extended attributes at all. Whether this is a feature or
+ * a bug is yet to be decided.
+ */
+int smbc_llistxattr(const char *url,
+ char *list,
+ size_t size);
+
+/**@ingroup attribute
+ * List the supported extended attribute names associated with a file
+ *
+ * @param fd A file descriptor associated with an open file (as
+ * previously returned by smbc_open(), to get extended
+ * attributes for.
+ *
+ * @param list A pointer to a buffer in which the list of attributes for
+ * the specified file or directory will be placed (unless
+ * size is zero).
+ *
+ * @param size The size of the buffer pointed to by list. This parameter
+ * may also be zero, in which case the size of the buffer
+ * required to hold all of the attribute names will be
+ * returned, but nothing will be placed into the list buffer.
+ *
+ * @return 0 on success, < 0 on error with errno set:
+ * - EINVAL The client library is not properly initialized
+ * - ENOMEM No memory was available for internal needs
+ * - EPERM Permission was denied.
+ * - ENOTSUP The referenced file system does not support
+ * extended attributes
+ *
+ * @note This function always returns all attribute names supported
+ * by NT file systems, regardless of wether the referenced
+ * file system supports extended attributes (e.g. a Windows
+ * 2000 machine supports extended attributes if NTFS is used,
+ * but not if FAT is used, and Windows 98 doesn't support
+ * extended attributes at all. Whether this is a feature or
+ * a bug is yet to be decided.
+ */
+int smbc_flistxattr(int fd,
+ char *list,
+ size_t size);
/**@ingroup print
* Print a file given the name in fname. It would be a URL ...
@@ -1068,5 +1932,16 @@ int smbc_list_print_jobs(const char *purl, smbc_list_print_job_fn fn);
*/
int smbc_unlink_print_job(const char *purl, int id);
+/**@ingroup callback
+ * Remove a server from the cached server list it's unused.
+ *
+ * @param context pointer to smb context
+ *
+ * @param srv pointer to server to remove
+ *
+ * @return On success, 0 is returned. 1 is returned if the server could not
+ * be removed. Also useable outside libsmbclient.
+ */
+int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv);
#endif /* SMBCLIENT_H_INCLUDED */
diff --git a/source/include/local.h b/source/include/local.h
index 4c3c58e14fc..540365047a2 100644
--- a/source/include/local.h
+++ b/source/include/local.h
@@ -227,4 +227,7 @@
/* Buffer size to use when printing backtraces */
#define BACKTRACE_STACK_SIZE 64
+/* size of listen() backlog in smbd */
+#define SMBD_LISTEN_BACKLOG 50
+
#endif
diff --git a/source/include/ntdomain.h b/source/include/ntdomain.h
index ccbc190c59d..3fe8f41d8d4 100644
--- a/source/include/ntdomain.h
+++ b/source/include/ntdomain.h
@@ -402,5 +402,6 @@ struct acct_info
#include "rpc_dfs.h"
#include "rpc_ds.h"
#include "rpc_echo.h"
+#include "rpc_shutdown.h"
#endif /* _NT_DOMAIN_H */
diff --git a/source/include/safe_string.h b/source/include/safe_string.h
index 07578b2424c..cb3f37c4841 100644
--- a/source/include/safe_string.h
+++ b/source/include/safe_string.h
@@ -47,6 +47,20 @@
#endif /* sprintf */
#define sprintf __ERROR__XX__NEVER_USE_SPRINTF__;
+/*
+ * strcasecmp/strncasecmp aren't an error, but it means you're not thinking about
+ * multibyte. Don't use them. JRA.
+ */
+#ifdef strcasecmp
+#undef strcasecmp
+#endif
+#define strcasecmp __ERROR__XX__NEVER_USE_STRCASECMP__;
+
+#ifdef strncasecmp
+#undef strncasecmp
+#endif
+#define strncasecmp __ERROR__XX__NEVER_USE_STRCASECMP__;
+
#endif /* !_SPLINT_ */
#ifdef DEVELOPER
diff --git a/source/include/smb.h b/source/include/smb.h
index 8c6f47f23fb..e41b5834f70 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -194,6 +194,7 @@ typedef smb_ucs2_t wfstring[FSTRING_LEN];
#define PIPE_SPOOLSS "\\PIPE\\spoolss"
#define PIPE_NETDFS "\\PIPE\\netdfs"
#define PIPE_ECHO "\\PIPE\\rpcecho"
+#define PIPE_SHUTDOWN "\\PIPE\\initshutdown"
#define PIPE_NETLOGON_PLAIN "\\NETLOGON"
@@ -207,7 +208,8 @@ typedef smb_ucs2_t wfstring[FSTRING_LEN];
#define PI_SPOOLSS 7
#define PI_NETDFS 8
#define PI_ECHO 9
-#define PI_MAX_PIPES 10
+#define PI_SHUTDOWN 10
+#define PI_MAX_PIPES 11
/* 64 bit time (100usec) since ????? - cifs6.txt, section 3.5, page 30 */
typedef struct nttime_info
diff --git a/source/include/smb_acls.h b/source/include/smb_acls.h
index e7edb62bde2..2bde6caeda1 100644
--- a/source/include/smb_acls.h
+++ b/source/include/smb_acls.h
@@ -195,7 +195,7 @@ typedef struct SMB_ACL_T {
/* Donated by Medha Date, mdate@austin.ibm.com, for IBM */
-#include "/usr/include/acl.h"
+#include <acl.h>
typedef uint *SMB_ACL_PERMSET_T;
diff --git a/source/intl/lang_tdb.c b/source/intl/lang_tdb.c
index af70b529ff9..b0e9e414de6 100644
--- a/source/intl/lang_tdb.c
+++ b/source/intl/lang_tdb.c
@@ -242,7 +242,7 @@ void lang_msg_free(const char *msgstr)
*/
const char *lang_msg_rotate(const char *msgid)
{
-#define NUM_LANG_BUFS 4
+#define NUM_LANG_BUFS 16
char *msgstr;
static pstring bufs[NUM_LANG_BUFS];
static int next;
diff --git a/source/lib/access.c b/source/lib/access.c
index a874c8b1e20..62414726fb0 100644
--- a/source/lib/access.c
+++ b/source/lib/access.c
@@ -71,7 +71,7 @@ static BOOL string_match(const char *tok,const char *s, char *invalid_char)
if (tok[0] == '.') { /* domain: match last fields */
if ((str_len = strlen(s)) > (tok_len = strlen(tok))
- && strcasecmp(tok, s + str_len - tok_len) == 0)
+ && strequal(tok, s + str_len - tok_len))
return (True);
} else if (tok[0] == '@') { /* netgroup: look it up */
#ifdef HAVE_NETGROUP
@@ -107,14 +107,14 @@ static BOOL string_match(const char *tok,const char *s, char *invalid_char)
DEBUG(0,("access: netgroup support is not configured\n"));
return (False);
#endif
- } else if (strcasecmp(tok, "ALL") == 0) { /* all: match any */
+ } else if (strequal(tok, "ALL")) { /* all: match any */
return (True);
- } else if (strcasecmp(tok, "FAIL") == 0) { /* fail: match any */
+ } else if (strequal(tok, "FAIL")) { /* fail: match any */
return (FAIL);
- } else if (strcasecmp(tok, "LOCAL") == 0) { /* local: no dots */
- if (strchr_m(s, '.') == 0 && strcasecmp(s, "unknown") != 0)
+ } else if (strequal(tok, "LOCAL")) { /* local: no dots */
+ if (strchr_m(s, '.') == 0 && !strequal(s, "unknown"))
return (True);
- } else if (!strcasecmp(tok, s)) { /* match host name or address */
+ } else if (!strequal(tok, s)) { /* match host name or address */
return (True);
} else if (tok[(tok_len = strlen(tok)) - 1] == '.') { /* network */
if (strncmp(tok, s, tok_len) == 0)
@@ -175,7 +175,7 @@ static BOOL list_match(const char **list,const char *item,
*/
for (; *list ; list++) {
- if (strcasecmp(*list, "EXCEPT") == 0) /* EXCEPT: give up */
+ if (strequal(*list, "EXCEPT")) /* EXCEPT: give up */
break;
if ((match = (*match_fn) (*list, item))) /* True or FAIL */
break;
@@ -183,7 +183,7 @@ static BOOL list_match(const char **list,const char *item,
/* Process exceptions to True or FAIL matches. */
if (match != False) {
- while (*list && strcasecmp(*list, "EXCEPT"))
+ while (*list && !strequal(*list, "EXCEPT"))
list++;
for (; *list; list++) {
@@ -275,8 +275,8 @@ static BOOL only_ipaddrs_in_list(const char** list)
for (; *list ; list++) {
/* factor out the special strings */
- if (!strcasecmp(*list, "ALL") || !strcasecmp(*list, "FAIL") ||
- !strcasecmp(*list, "EXCEPT")) {
+ if (strequal(*list, "ALL") || strequal(*list, "FAIL") ||
+ strequal(*list, "EXCEPT")) {
continue;
}
diff --git a/source/lib/afs.c b/source/lib/afs.c
index 882442a79f1..fc78950f398 100644
--- a/source/lib/afs.c
+++ b/source/lib/afs.c
@@ -185,13 +185,9 @@ BOOL afs_login(connection_struct *conn)
strncpy(p, cell, sizeof(ticket)-PTR_DIFF(p,ticket)-1);
p += strlen(p)+1;
- /* As long as we still only use the effective UID we need to set the
- * token for it here as well. This involves patching AFS in two
- * places. Once we start using the real uid where we have the
- * setresuid function, we can use getuid() here which would be more
- * correct. */
-
- ct.ViceId = geteuid();
+ /* This assumes that we have setresuid and set the real uid as well as
+ the effective uid in set_effective_uid(). */
+ ct.ViceId = getuid();
DEBUG(10, ("Creating Token for uid %d\n", ct.ViceId));
/* Alice's network layer address. At least Openafs-1.2.10
diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c
index dafc88fb77a..9d15c6daa02 100644
--- a/source/lib/charcnv.c
+++ b/source/lib/charcnv.c
@@ -56,7 +56,7 @@ static const char *charset_name(charset_t ch)
else if (ch == CH_UTF8) ret = "UTF8";
#if defined(HAVE_NL_LANGINFO) && defined(CODESET)
- if (ret && strcasecmp(ret, "LOCALE") == 0) {
+ if (ret && !strcmp(ret, "LOCALE")) {
const char *ln = NULL;
#ifdef HAVE_SETLOCALE
diff --git a/source/lib/getsmbpass.c b/source/lib/getsmbpass.c
index 27cd5e6dfa2..df5e0359aa2 100644
--- a/source/lib/getsmbpass.c
+++ b/source/lib/getsmbpass.c
@@ -158,14 +158,15 @@ char *getsmbpass(const char *prompt)
tcsetattr (fileno (in), TCSANOW, &t);
}
+ fprintf(out, "\n");
+ fflush(out);
+
if (in != stdin) /* We opened the terminal; now close it. */
fclose(in);
/* Catch problematic signals */
CatchSignal(SIGINT, SIGNAL_CAST SIG_DFL);
- printf("\n");
-
if (gotintr) {
printf("Interupted by signal.\n");
fflush(stdout);
diff --git a/source/lib/iconv.c b/source/lib/iconv.c
index 0326ca70611..9f6db79ee24 100644
--- a/source/lib/iconv.c
+++ b/source/lib/iconv.c
@@ -21,6 +21,12 @@
#include "includes.h"
+/*
+ * We have to use strcasecmp here as the character conversions
+ * haven't been initialised yet. JRA.
+ */
+
+#undef strcasecmp
/**
* @file
diff --git a/source/lib/privileges.c b/source/lib/privileges.c
index 1c23d9e40e5..1ed583382de 100644
--- a/source/lib/privileges.c
+++ b/source/lib/privileges.c
@@ -188,7 +188,6 @@ NTSTATUS add_all_privilege(PRIVILEGE_SET *priv_set)
result = add_privilege(priv_set, set);
NTSTATUS_CHECK(result, done, "add_all_privilege", "add_privilege");
-done:
return result;
}
diff --git a/source/lib/sendfile.c b/source/lib/sendfile.c
index bcc8cb08ca1..4aa76a0c74a 100644
--- a/source/lib/sendfile.c
+++ b/source/lib/sendfile.c
@@ -161,7 +161,7 @@ ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T of
vec[0].sfv_fd = SFV_FD_SELF;
vec[0].sfv_flag = 0;
- vec[0].sfv_off = header->data;
+ vec[0].sfv_off = (off_t)header->data;
vec[0].sfv_len = hdr_len = header->length;
vec[1].sfv_fd = fromfd;
diff --git a/source/lib/smbldap.c b/source/lib/smbldap.c
index 781e6b976c3..fe34cfb852e 100644
--- a/source/lib/smbldap.c
+++ b/source/lib/smbldap.c
@@ -258,6 +258,7 @@ BOOL fetch_ldap_pw(char **dn, char** pw)
return False;
}
+ size = MIN(size, sizeof(fstring)-1);
strncpy(old_style_pw, data, size);
old_style_pw[size] = 0;
@@ -350,7 +351,7 @@ BOOL fetch_ldap_pw(char **dn, char** pw)
}
for (i = 0; mods[i] != NULL; ++i) {
- if (mods[i]->mod_op == modop && !strcasecmp(mods[i]->mod_type, attribute))
+ if (mods[i]->mod_op == modop && strequal(mods[i]->mod_type, attribute))
break;
}
@@ -542,7 +543,7 @@ static int smbldap_open_connection (struct smbldap_state *ldap_state)
SMB_ASSERT(sizeof(protocol)>10 && sizeof(host)>254);
/* skip leading "URL:" (if any) */
- if ( strncasecmp( p, "URL:", 4 ) == 0 ) {
+ if ( strnequal( p, "URL:", 4 ) ) {
p += 4;
}
diff --git a/source/lib/snprintf.c b/source/lib/snprintf.c
index a2f9f592db3..5b0cfa1ab33 100644
--- a/source/lib/snprintf.c
+++ b/source/lib/snprintf.c
@@ -147,10 +147,14 @@
#ifndef VA_COPY
#ifdef HAVE_VA_COPY
+#define VA_COPY(dest, src) va_copy(dest, src)
+#else
+#ifdef HAVE___VA_COPY
#define VA_COPY(dest, src) __va_copy(dest, src)
#else
#define VA_COPY(dest, src) (dest) = (src)
#endif
+#endif
/*
* dopr(): poor man's version of doprintf
diff --git a/source/lib/substitute.c b/source/lib/substitute.c
index 28466e43f29..923afd989f7 100644
--- a/source/lib/substitute.c
+++ b/source/lib/substitute.c
@@ -45,10 +45,10 @@ void set_local_machine_name(const char* local_name, BOOL perm)
* arrggg!!!
*/
- if (strcasecmp(local_name, "*SMBSERVER")==0)
+ if (strequal(local_name, "*SMBSERVER"))
return;
- if (strcasecmp(local_name, "*SMBSERV")==0)
+ if (strequal(local_name, "*SMBSERV"))
return;
if (already_perm)
@@ -529,6 +529,9 @@ char *alloc_sub_basic(const char *smb_name, const char *str)
else
t = realloc_string_sub(t, "%L", global_myname());
break;
+ case 'N':
+ t = realloc_string_sub(t, "%N", automount_server(smb_name));
+ break;
case 'M' :
t = realloc_string_sub(t, "%M", client_name());
break;
diff --git a/source/lib/talloctort.c b/source/lib/talloctort.c
index ad5de38581d..0cdf693bb91 100644
--- a/source/lib/talloctort.c
+++ b/source/lib/talloctort.c
@@ -51,9 +51,9 @@ int main(void)
}
for (i = 0; i < NCTX; i++) {
- printf("talloc@%p %-40s %dkB\n", ctx[i],
+ printf("talloc@%p %-40s %ldkB\n", ctx[i],
talloc_pool_name(ctx[i]),
- talloc_pool_size(ctx[i]) >> 10);
+ (unsigned long)talloc_pool_size(ctx[i]) >> 10);
}
printf("%s", talloc_describe_all(ctx[0]));
diff --git a/source/lib/time.c b/source/lib/time.c
index 5309711a056..635ede9be22 100644
--- a/source/lib/time.c
+++ b/source/lib/time.c
@@ -318,8 +318,11 @@ time_t nt_time_to_unix(NTTIME *nt)
/* now adjust by 369 years to make the secs since 1970 */
d -= TIME_FIXUP_CONSTANT;
- if (!(l_time_min <= d && d <= l_time_max))
- return(0);
+ if (d <= l_time_min)
+ return (l_time_min);
+
+ if (d >= l_time_max)
+ return (l_time_max);
ret = (time_t)(d+0.5);
@@ -691,7 +694,7 @@ char *timestring(BOOL hires)
".%06ld",
(long)tp.tv_usec);
} else {
- strftime(TimeBuf,100,"%Y/%m/%d %H:%M:%S",tm);
+ strftime(TimeBuf,sizeof(TimeBuf)-1,"%Y/%m/%d %H:%M:%S",tm);
}
#else
if (hires) {
diff --git a/source/lib/username.c b/source/lib/username.c
index 6321d470212..40327f81687 100644
--- a/source/lib/username.c
+++ b/source/lib/username.c
@@ -293,13 +293,16 @@ struct passwd *Get_Pwnam(const char *user)
}
/****************************************************************************
- Check if a user is in a netgroup user list.
+ Check if a user is in a netgroup user list. If at first we don't succeed,
+ try lower case.
****************************************************************************/
static BOOL user_in_netgroup_list(const char *user, const char *ngname)
{
#ifdef HAVE_NETGROUP
static char *mydomain = NULL;
+ fstring lowercase_user, lowercase_ngname;
+
if (mydomain == NULL)
yp_get_default_domain(&mydomain);
@@ -315,6 +318,20 @@ static BOOL user_in_netgroup_list(const char *user, const char *ngname)
if (innetgr(ngname, NULL, user, mydomain))
return (True);
+
+ /*
+ * Ok, innetgr is case sensitive. Try once more with lowercase
+ * just in case. Attempt to fix #703. JRA.
+ */
+
+ fstrcpy(lowercase_user, user);
+ strlower_m(lowercase_user);
+ fstrcpy(lowercase_ngname, ngname);
+ strlower_m(lowercase_ngname);
+
+ if (innetgr(lowercase_ngname, NULL, lowercase_user, mydomain))
+ return (True);
+
#endif /* HAVE_NETGROUP */
return False;
}
diff --git a/source/lib/util.c b/source/lib/util.c
index 766c5041b4e..ce1389c8e9c 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -1404,7 +1404,8 @@ void smb_panic(const char *why)
backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
- DEBUG(0, ("BACKTRACE: %d stack frames:\n", backtrace_size));
+ DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
+ (unsigned long)backtrace_size));
if (backtrace_strings) {
int i;
diff --git a/source/lib/util_sec.c b/source/lib/util_sec.c
index 1980b8bfb7c..7c2576ed91e 100644
--- a/source/lib/util_sec.c
+++ b/source/lib/util_sec.c
@@ -183,11 +183,8 @@ void gain_root_group_privilege(void)
void set_effective_uid(uid_t uid)
{
#if USE_SETRESUID
- /* On Systems which have this function, would it not be more
- * appropriate to also set the real uid by doing
- * setresuid(uid,uid,-1)? This would make patching AFS
- * unnecessary. See comment in lib/afs.c. */
- setresuid(-1,uid,-1);
+ /* Set the effective as well as the real uid. */
+ setresuid(uid,uid,-1);
#endif
#if USE_SETREUID
diff --git a/source/lib/util_sock.c b/source/lib/util_sock.c
index b8b84717084..b59d7aa7ebb 100644
--- a/source/lib/util_sock.c
+++ b/source/lib/util_sock.c
@@ -184,8 +184,8 @@ ssize_t read_udp_socket(int fd,char *buf,size_t len)
lastip = sock.sin_addr;
lastport = ntohs(sock.sin_port);
- DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
- inet_ntoa(lastip), lastport, ret));
+ DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %lu\n",
+ inet_ntoa(lastip), lastport, (unsigned long)ret));
return(ret);
}
@@ -460,7 +460,7 @@ static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int
DEBUG(5,("Got keepalive packet\n"));
}
- DEBUG(10,("got smb length of %d\n",len));
+ DEBUG(10,("got smb length of %lu\n",(unsigned long)len));
return(len);
}
@@ -487,7 +487,8 @@ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
break;
}
- DEBUG(10,("read_smb_length: got smb length of %d\n",len));
+ DEBUG(10,("read_smb_length: got smb length of %lu\n",
+ (unsigned long)len));
return len;
}
@@ -497,9 +498,10 @@ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
BUFFER_SIZE+SAFETY_MARGIN.
The timeout is in milliseconds.
This function will return on receipt of a session keepalive packet.
+ Doesn't check the MAC on signed packets.
****************************************************************************/
-BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
+BOOL receive_smb_raw(int fd,char *buffer, unsigned int timeout)
{
ssize_t len,ret;
@@ -509,7 +511,7 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
len = read_smb_length_return_keepalive(fd,buffer,timeout);
if (len < 0) {
- DEBUG(10,("receive_smb: length < 0!\n"));
+ DEBUG(10,("receive_smb_raw: length < 0!\n"));
/*
* Correct fix. smb_read_error may have already been
@@ -528,7 +530,7 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
*/
if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
- DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
+ DEBUG(0,("Invalid packet length! (%lu bytes).\n",(unsigned long)len));
if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) {
/*
@@ -552,6 +554,20 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
}
}
+ return True;
+}
+
+/****************************************************************************
+ Wrapper for receive_smb_raw().
+ Checks the MAC on signed packets.
+****************************************************************************/
+
+BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
+{
+ if (!receive_smb_raw(fd, buffer, timeout)) {
+ return False;
+ }
+
/* Check the incoming SMB signature. */
if (!srv_check_sign_mac(buffer)) {
DEBUG(0, ("receive_smb: SMB Signature verification failed on incoming packet!\n"));
@@ -822,8 +838,8 @@ static BOOL matchname(char *remotehost,struct in_addr addr)
* DNS is perverted). We always check the address list, though.
*/
- if (strcasecmp(remotehost, hp->h_name)
- && strcasecmp(remotehost, "localhost")) {
+ if (!strequal(remotehost, hp->h_name)
+ && !strequal(remotehost, "localhost")) {
DEBUG(0,("host name/name mismatch: %s != %s\n",
remotehost, hp->h_name));
return False;
diff --git a/source/lib/util_str.c b/source/lib/util_str.c
index 15ac1639a9a..b6025a362d3 100644
--- a/source/lib/util_str.c
+++ b/source/lib/util_str.c
@@ -590,8 +590,9 @@ char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_
len = strnlen(src, maxlength+1);
if (len > maxlength) {
- DEBUG(0,("ERROR: string overflow by %u (%u - %u) in safe_strcpy [%.50s]\n",
- (unsigned int)(len-maxlength), len, maxlength, src));
+ DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n",
+ (unsigned long)(len-maxlength), (unsigned long)len,
+ (unsigned long)maxlength, src));
len = maxlength;
}
diff --git a/source/libads/ads_struct.c b/source/libads/ads_struct.c
index dd31439d830..9774968e121 100644
--- a/source/libads/ads_struct.c
+++ b/source/libads/ads_struct.c
@@ -95,10 +95,10 @@ ADS_STRUCT *ads_init(const char *realm,
ads->server.ldap_server = ldap_server? strdup(ldap_server) : NULL;
/* we need to know if this is a foreign realm */
- if (realm && *realm && strcasecmp(lp_realm(), realm) != 0) {
+ if (realm && *realm && !strequal(lp_realm(), realm)) {
ads->server.foreign = 1;
}
- if (workgroup && *workgroup && strcasecmp(lp_workgroup(), workgroup) != 0) {
+ if (workgroup && *workgroup && !strequal(lp_workgroup(), workgroup)) {
ads->server.foreign = 1;
}
diff --git a/source/libads/kerberos_verify.c b/source/libads/kerberos_verify.c
index 4ae89aa01f3..cdea5a2fe42 100644
--- a/source/libads/kerberos_verify.c
+++ b/source/libads/kerberos_verify.c
@@ -71,10 +71,18 @@ static krb5_error_code create_keytab(krb5_context context,
entry.principal = host_princ;
entry.vno = kvno;
- /* this will have to be detected in configure...heimdal
- calls it keyblock, MIT calls it key, but it does not
- matter we are creating keytabs with MIT */
- entry.keyblock = *key;
+
+#if !defined(HAVE_KRB5_KEYTAB_ENTRY_KEY) && !defined(HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK)
+#error krb5_keytab_entry has no key or keyblock member
+#endif
+
+#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEY /* MIT */
+ entry.key = *key;
+#endif
+
+#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK /* Heimdal */
+ entry.keyblock = *key;
+#endif
DEBUG(10,("adding keytab-entry for (%s) with encryption type (%d)\n",
host_princ_s, enctypes[i]));
diff --git a/source/libads/ldap.c b/source/libads/ldap.c
index 8c3185ea5e3..b3706cb2403 100644
--- a/source/libads/ldap.c
+++ b/source/libads/ldap.c
@@ -972,7 +972,7 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn)
**/
char *ads_ou_string(const char *org_unit)
{
- if (!org_unit || !*org_unit || strcasecmp(org_unit, "Computers") == 0) {
+ if (!org_unit || !*org_unit || strequal(org_unit, "Computers")) {
return strdup("cn=Computers");
}
@@ -1970,8 +1970,8 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **workg
prefix_length = strlen(prefix);
for (i=0;principles[i]; i++) {
- if (strncasecmp(principles[i], prefix, prefix_length) == 0 &&
- strcasecmp(ads->config.realm, principles[i]+prefix_length) != 0 &&
+ if (strnequal(principles[i], prefix, prefix_length) &&
+ !strequal(ads->config.realm, principles[i]+prefix_length) &&
!strchr(principles[i]+prefix_length, '.')) {
/* found an alternate (short) name for the domain. */
DEBUG(3,("Found alternate name '%s' for realm '%s'\n",
diff --git a/source/libsmb/clidgram.c b/source/libsmb/clidgram.c
index 5ab6bef87b6..c4675f1938a 100644
--- a/source/libsmb/clidgram.c
+++ b/source/libsmb/clidgram.c
@@ -75,7 +75,7 @@ int cli_send_mailslot(int dgram_sock, BOOL unique, const char *mailslot,
SSVAL(ptr,smb_vwv15,1);
SSVAL(ptr,smb_vwv16,2);
p2 = smb_buf(ptr);
- pstrcpy(p2,mailslot);
+ fstrcpy(p2,mailslot);
p2 = skip_string(p2,1);
memcpy(p2,buf,len);
@@ -135,7 +135,7 @@ static char cli_backup_list[1024];
int cli_get_backup_list(const char *myname, const char *send_to_name)
{
- char outbuf[15];
+ pstring outbuf;
char *p;
struct in_addr sendto_ip, my_ip;
int dgram_sock;
@@ -262,6 +262,3 @@ int cli_get_backup_server(char *my_name, char *target, char *servername, int nam
return True;
}
-
-
-
diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c
index 0a134f715dc..9b54acf7756 100644
--- a/source/libsmb/clientgen.c
+++ b/source/libsmb/clientgen.c
@@ -59,7 +59,7 @@ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout)
BOOL ret;
for(;;) {
- ret = receive_smb(fd, buffer, timeout);
+ ret = receive_smb_raw(fd, buffer, timeout);
if (!ret) {
DEBUG(10,("client_receive_smb failed\n"));
diff --git a/source/libsmb/clilist.c b/source/libsmb/clilist.c
index 7822987ada8..2c1831ae990 100644
--- a/source/libsmb/clilist.c
+++ b/source/libsmb/clilist.c
@@ -82,7 +82,7 @@ static int interpret_long_filename(struct cli_state *cli,
case 260: /* NT uses this, but also accepts 2 */
{
- int namelen, slen;
+ size_t namelen, slen;
p += 4; /* next entry offset */
p += 4; /* fileindex */
diff --git a/source/libsmb/clisecdesc.c b/source/libsmb/clisecdesc.c
index 548cd6ec187..2989966f4de 100644
--- a/source/libsmb/clisecdesc.c
+++ b/source/libsmb/clisecdesc.c
@@ -33,7 +33,7 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum,
SEC_DESC *psd = NULL;
SIVAL(param, 0, fnum);
- SSVAL(param, 4, 0x7);
+ SIVAL(param, 4, 0x7);
if (!cli_send_nt_trans(cli,
NT_TRANSACT_QUERY_SECURITY_DESC,
diff --git a/source/libsmb/clitrans.c b/source/libsmb/clitrans.c
index e6771ac6885..92c1cc99eeb 100644
--- a/source/libsmb/clitrans.c
+++ b/source/libsmb/clitrans.c
@@ -488,6 +488,17 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
}
}
+ /*
+ * Likewise for NT_STATUS_BUFFER_TOO_SMALL
+ */
+ if (cli_is_nt_error(cli)) {
+ if (!NT_STATUS_EQUAL(cli_nt_error(cli),
+ NT_STATUS_BUFFER_TOO_SMALL)) {
+ cli_signing_trans_stop(cli);
+ return(False);
+ }
+ }
+
/* parse out the lengths */
total_data = SVAL(cli->inbuf,smb_ntr_TotalDataCount);
total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount);
diff --git a/source/libsmb/errormap.c b/source/libsmb/errormap.c
index 4d9a717e1c0..116d2cefe15 100644
--- a/source/libsmb/errormap.c
+++ b/source/libsmb/errormap.c
@@ -98,6 +98,10 @@ static const struct {
*/
{ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED},
{ERRDOS, 111, NT_STATUS_BUFFER_TOO_SMALL},
+/*
+ * Not an official error, as only bit 0x80000000, not bits 0xC0000000 are set.
+ */
+ {ERRDOS, ERRmoredata, STATUS_BUFFER_OVERFLOW},
{ERRDOS, ERRbadfid, NT_STATUS_OBJECT_TYPE_MISMATCH},
{ERRHRD, ERRgeneral, NT_STATUS_NONCONTINUABLE_EXCEPTION},
{ERRHRD, ERRgeneral, NT_STATUS_INVALID_DISPOSITION},
diff --git a/source/libsmb/libsmb_compat.c b/source/libsmb/libsmb_compat.c
index 27b274953ab..cc23835ae3d 100644
--- a/source/libsmb/libsmb_compat.c
+++ b/source/libsmb/libsmb_compat.c
@@ -5,6 +5,7 @@
Copyright (C) Richard Sharpe 2000
Copyright (C) John Terpstra 2000
Copyright (C) Tom Jansen (Ninja ISD) 2002
+ Copyright (C) Derrell Lipman 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
@@ -34,14 +35,14 @@ struct smbc_compat_fdlist {
static SMBCCTX * statcont = NULL;
static int smbc_compat_initialized = 0;
-static int smbc_currentfd = 10000;
-static struct smbc_compat_fdlist * smbc_compat_fdlist = NULL;
-
+static int smbc_compat_nextfd = 0;
+static struct smbc_compat_fdlist * smbc_compat_fd_in_use = NULL;
+static struct smbc_compat_fdlist * smbc_compat_fd_avail = NULL;
/* Find an fd and return the SMBCFILE * or NULL on failure */
static SMBCFILE * find_fd(int fd)
{
- struct smbc_compat_fdlist * f = smbc_compat_fdlist;
+ struct smbc_compat_fdlist * f = smbc_compat_fd_in_use;
while (f) {
if (f->fd == fd)
return f->file;
@@ -53,16 +54,36 @@ static SMBCFILE * find_fd(int fd)
/* Add an fd, returns 0 on success, -1 on error with errno set */
static int add_fd(SMBCFILE * file)
{
- struct smbc_compat_fdlist * f = malloc(sizeof(struct smbc_compat_fdlist));
- if (!f) {
- errno = ENOMEM;
- return -1;
- }
+ struct smbc_compat_fdlist * f = smbc_compat_fd_avail;
+
+ if (f) {
+ /* We found one that's available */
+ DLIST_REMOVE(smbc_compat_fd_avail, f);
+
+ } else {
+ /*
+ * None were available, so allocate one. Keep the number of
+ * file descriptors determinate. This allows the application
+ * to allocate bitmaps or mapping of file descriptors based on
+ * a known maximum number of file descriptors that will ever
+ * be returned.
+ */
+ if (smbc_compat_nextfd >= FD_SETSIZE) {
+ errno = EMFILE;
+ return -1;
+ }
+
+ f = malloc(sizeof(struct smbc_compat_fdlist));
+ if (!f) {
+ errno = ENOMEM;
+ return -1;
+ }
- f->fd = smbc_currentfd++;
+ f->fd = SMBC_BASE_FD + smbc_compat_nextfd++;
+ }
+
f->file = file;
-
- DLIST_ADD(smbc_compat_fdlist, f);
+ DLIST_ADD(smbc_compat_fd_in_use, f);
return f->fd;
}
@@ -72,16 +93,19 @@ static int add_fd(SMBCFILE * file)
/* Delete an fd, returns 0 on success */
static int del_fd(int fd)
{
- struct smbc_compat_fdlist * f = smbc_compat_fdlist;
+ struct smbc_compat_fdlist * f = smbc_compat_fd_in_use;
+
while (f) {
if (f->fd == fd)
break;
f = f->next;
}
+
if (f) {
/* found */
- DLIST_REMOVE(smbc_compat_fdlist, f);
- SAFE_FREE(f);
+ DLIST_REMOVE(smbc_compat_fd_in_use, f);
+ f->file = NULL;
+ DLIST_ADD(smbc_compat_fd_avail, f);
return 0;
}
return 1;
@@ -112,6 +136,22 @@ int smbc_init(smbc_get_auth_data_fn fn, int debug)
}
+SMBCCTX *smbc_set_context(SMBCCTX * context)
+{
+ SMBCCTX *old_context = statcont;
+
+ if (context) {
+ /* Save provided context. It must have been initialized! */
+ statcont = context;
+
+ /* You'd better know what you're doing. We won't help you. */
+ smbc_compat_initialized = 1;
+ }
+
+ return old_context;
+}
+
+
int smbc_open(const char *furl, int flags, mode_t mode)
{
SMBCFILE * file;
@@ -252,8 +292,121 @@ int smbc_fstat(int fd, struct stat *st)
int smbc_chmod(const char *url, mode_t mode)
{
- /* NOT IMPLEMENTED IN LIBSMBCLIENT YET */
- return -1;
+ return statcont->chmod(statcont, url, mode);
+}
+
+int smbc_utimes(const char *fname, struct timeval *tbuf)
+{
+ return statcont->utimes(statcont, fname, tbuf);
+}
+
+#ifdef HAVE_UTIME_H
+int smbc_utime(const char *fname, struct utimbuf *utbuf)
+{
+ struct timeval tv;
+
+ if (utbuf == NULL)
+ return statcont->utimes(statcont, fname, NULL);
+
+ tv.tv_sec = utbuf->modtime;
+ tv.tv_usec = 0;
+ return statcont->utimes(statcont, fname, &tv);
+}
+#endif
+
+int smbc_setxattr(const char *fname,
+ const char *name,
+ const void *value,
+ size_t size,
+ int flags)
+{
+ return statcont->setxattr(statcont, fname, name, value, size, flags);
+}
+
+int smbc_lsetxattr(const char *fname,
+ const char *name,
+ const void *value,
+ size_t size,
+ int flags)
+{
+ return statcont->setxattr(statcont, fname, name, value, size, flags);
+}
+
+int smbc_fsetxattr(int fd,
+ const char *name,
+ const void *value,
+ size_t size,
+ int flags)
+{
+ SMBCFILE * file = find_fd(fd);
+ return statcont->setxattr(statcont, file->fname,
+ name, value, size, flags);
+}
+
+int smbc_getxattr(const char *fname,
+ const char *name,
+ const void *value,
+ size_t size)
+{
+ return statcont->getxattr(statcont, fname, name, value, size);
+}
+
+int smbc_lgetxattr(const char *fname,
+ const char *name,
+ const void *value,
+ size_t size)
+{
+ return statcont->getxattr(statcont, fname, name, value, size);
+}
+
+int smbc_fgetxattr(int fd,
+ const char *name,
+ const void *value,
+ size_t size)
+{
+ SMBCFILE * file = find_fd(fd);
+ return statcont->getxattr(statcont, file->fname, name, value, size);
+}
+
+int smbc_removexattr(const char *fname,
+ const char *name)
+{
+ return statcont->removexattr(statcont, fname, name);
+}
+
+int smbc_lremovexattr(const char *fname,
+ const char *name)
+{
+ return statcont->removexattr(statcont, fname, name);
+}
+
+int smbc_fremovexattr(int fd,
+ const char *name)
+{
+ SMBCFILE * file = find_fd(fd);
+ return statcont->removexattr(statcont, file->fname, name);
+}
+
+int smbc_listxattr(const char *fname,
+ char *list,
+ size_t size)
+{
+ return statcont->listxattr(statcont, fname, list, size);
+}
+
+int smbc_llistxattr(const char *fname,
+ char *list,
+ size_t size)
+{
+ return statcont->listxattr(statcont, fname, list, size);
+}
+
+int smbc_flistxattr(int fd,
+ char *list,
+ size_t size)
+{
+ SMBCFILE * file = find_fd(fd);
+ return statcont->listxattr(statcont, file->fname, list, size);
}
int smbc_print_file(const char *fname, const char *printq)
diff --git a/source/libsmb/libsmbclient.c b/source/libsmb/libsmbclient.c
index 69c4d8f7a77..21273ec4319 100644
--- a/source/libsmb/libsmbclient.c
+++ b/source/libsmb/libsmbclient.c
@@ -5,6 +5,7 @@
Copyright (C) Richard Sharpe 2000, 2002
Copyright (C) John Terpstra 2000
Copyright (C) Tom Jansen (Ninja ISD) 2002
+ Copyright (C) Derrell Lipman 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,25 @@
#include "../include/libsmb_internal.h"
/*
+ * Internal flags for extended attributes
+ */
+
+/* internal mode values */
+#define SMBC_XATTR_MODE_ADD 1
+#define SMBC_XATTR_MODE_REMOVE 2
+#define SMBC_XATTR_MODE_REMOVE_ALL 3
+#define SMBC_XATTR_MODE_SET 4
+#define SMBC_XATTR_MODE_CHOWN 5
+#define SMBC_XATTR_MODE_CHGRP 6
+
+#define CREATE_ACCESS_READ READ_CONTROL_ACCESS
+
+/*We should test for this in configure ... */
+#ifndef ENOTSUP
+#define ENOTSUP EOPNOTSUPP
+#endif
+
+/*
* Functions exported by libsmb_cache.c that we need here
*/
int smbc_default_cache_functions(SMBCCTX *context);
@@ -162,8 +182,9 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share,
/* see if it has the right prefix */
len = strlen(smbc_prefix);
- if (strncmp(s,smbc_prefix,len) ||
- (s[len] != '/' && s[len] != 0)) return -1; /* What about no smb: ? */
+ if (strncmp(s,smbc_prefix,len) || (s[len] != '/' && s[len] != 0)) {
+ return -1; /* What about no smb: ? */
+ }
p = s + len;
@@ -343,6 +364,67 @@ int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv)
return 0;
}
+SMBCSRV *find_server(SMBCCTX *context,
+ const char *server,
+ const char *share,
+ fstring workgroup,
+ fstring username,
+ fstring password)
+{
+ SMBCSRV *srv;
+ int auth_called = 0;
+
+ check_server_cache:
+
+ srv = context->callbacks.get_cached_srv_fn(context, server, share,
+ workgroup, username);
+
+ if (!auth_called && !srv && (!username[0] || !password[0])) {
+ context->callbacks.auth_fn(server, share,
+ workgroup, sizeof(fstring),
+ username, sizeof(fstring),
+ password, sizeof(fstring));
+ /*
+ * However, smbc_auth_fn may have picked up info relating to
+ * an existing connection, so try for an existing connection
+ * again ...
+ */
+ auth_called = 1;
+ goto check_server_cache;
+
+ }
+
+ if (srv) {
+ if (context->callbacks.check_server_fn(context, srv)) {
+ /*
+ * This server is no good anymore
+ * Try to remove it and check for more possible
+ * servers in the cache
+ */
+ if (context->callbacks.remove_unused_server_fn(context,
+ srv)) {
+ /*
+ * We could not remove the server completely,
+ * remove it from the cache so we will not get
+ * it again. It will be removed when the last
+ * file/dir is closed.
+ */
+ context->callbacks.remove_cached_srv_fn(context,
+ srv);
+ }
+
+ /*
+ * Maybe there are more cached connections to this
+ * server
+ */
+ goto check_server_cache;
+ }
+ return srv;
+ }
+
+ return NULL;
+}
+
/*
* Connect to a server, possibly on an existing connection
*
@@ -360,7 +442,6 @@ SMBCSRV *smbc_server(SMBCCTX *context,
fstring password)
{
SMBCSRV *srv=NULL;
- int auth_called = 0;
struct cli_state c;
struct nmb_name called, calling;
char *p;
@@ -378,45 +459,10 @@ SMBCSRV *smbc_server(SMBCCTX *context,
return NULL;
}
- check_server_cache:
-
- srv = context->callbacks.get_cached_srv_fn(context, server, share,
- workgroup, username);
-
- if (!auth_called && !srv && (!username[0] || !password[0])) {
- context->callbacks.auth_fn(server, share, workgroup, sizeof(fstring),
- username, sizeof(fstring), password, sizeof(fstring));
- /*
- * However, smbc_auth_fn may have picked up info relating to an
- * existing connection, so try for an existing connection again ...
- */
- auth_called = 1;
- goto check_server_cache;
-
- }
-
- if (srv) {
- if (context->callbacks.check_server_fn(context, srv)) {
- /*
- * This server is no good anymore
- * Try to remove it and check for more possible servers in the cache
- */
- if (context->callbacks.remove_unused_server_fn(context, srv)) {
- /*
- * We could not remove the server completely, remove it from the cache
- * so we will not get it again. It will be removed when the last file/dir
- * is closed.
- */
- context->callbacks.remove_cached_srv_fn(context, srv);
- }
-
- /*
- * Maybe there are more cached connections to this server
- */
- goto check_server_cache;
- }
- return srv;
- }
+ srv = find_server(context, server, share,
+ workgroup, username, password);
+ if (srv)
+ return srv;
make_nmb_name(&calling, context->netbios_name, 0x0);
make_nmb_name(&called , server, 0x20);
@@ -441,16 +487,26 @@ SMBCSRV *smbc_server(SMBCCTX *context,
/* have to open a new connection */
if (!cli_initialise(&c)) {
- errno = ENOENT;
+ errno = ENOMEM;
return NULL;
}
c.timeout = context->timeout;
+ /* Force use of port 139 for first try, so browse lists can work */
+ c.port = 139;
+
if (!cli_connect(&c, server_n, &ip)) {
- cli_shutdown(&c);
- errno = ENOENT;
- return NULL;
+ /*
+ * Port 139 connection failed. Try port 445 to handle
+ * connections to newer (e.g. XP) hosts with NetBIOS disabled.
+ */
+ c.port = 445;
+ if (!cli_connect(&c, server_n, &ip)) {
+ cli_shutdown(&c);
+ errno = ENETUNREACH;
+ return NULL;
+ }
}
if (!cli_session_request(&c, &calling, &called)) {
@@ -553,6 +609,101 @@ SMBCSRV *smbc_server(SMBCCTX *context,
}
/*
+ * Connect to a server for getting/setting attributes, possibly on an existing
+ * connection. This works similarly to smbc_server().
+ */
+SMBCSRV *smbc_attr_server(SMBCCTX *context,
+ const char *server, const char *share,
+ fstring workgroup,
+ fstring username, fstring password,
+ POLICY_HND *pol)
+{
+ struct in_addr ip;
+ struct cli_state *ipc_cli;
+ NTSTATUS nt_status;
+ SMBCSRV *ipc_srv=NULL;
+
+ /*
+ * See if we've already created this special connection. Reference
+ * our "special" share name 'IPC$$'.
+ */
+ ipc_srv = find_server(context, server, "IPC$$",
+ workgroup, username, password);
+ if (!ipc_srv) {
+
+ /* We didn't find a cached connection. Get the password */
+ if (*password == '\0') {
+ /* ... then retrieve it now. */
+ context->callbacks.auth_fn(server, share,
+ workgroup, sizeof(fstring),
+ username, sizeof(fstring),
+ password, sizeof(fstring));
+ }
+
+ zero_ip(&ip);
+ nt_status = cli_full_connection(&ipc_cli,
+ global_myname(), server,
+ &ip, 0, "IPC$", "?????",
+ username, workgroup,
+ password, 0,
+ Undefined, NULL);
+ if (! NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(0,("cli_full_connection failed! (%s)\n",
+ nt_errstr(nt_status)));
+ errno = ENOTSUP;
+ return NULL;
+ }
+
+ if (!cli_nt_session_open(ipc_cli, PI_LSARPC)) {
+ DEBUG(0, ("cli_nt_session_open fail! (%s)\n",
+ nt_errstr(nt_status)));
+ errno = ENOTSUP;
+ free(ipc_cli);
+ return NULL;
+ }
+
+ /* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED,
+ but NT sends 0x2000000 so we might as well do it too. */
+
+ nt_status = cli_lsa_open_policy(ipc_cli,
+ ipc_cli->mem_ctx,
+ True,
+ GENERIC_EXECUTE_ACCESS,
+ pol);
+
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ errno = smbc_errno(context, ipc_cli);
+ free(ipc_cli);
+ return NULL;
+ }
+
+ ipc_srv = (SMBCSRV *)malloc(sizeof(*ipc_srv));
+ if (!ipc_srv) {
+ errno = ENOMEM;
+ free(ipc_cli);
+ return NULL;
+ }
+
+ ZERO_STRUCTP(ipc_srv);
+ ipc_srv->cli = *ipc_cli;
+
+ free(ipc_cli);
+
+ /* now add it to the cache (internal or external) */
+ if (context->callbacks.add_cached_srv_fn(context, ipc_srv,
+ server,
+ "IPC$$",
+ workgroup,
+ username)) {
+ DEBUG(3, (" Failed to add server to cache\n"));
+ return NULL;
+ }
+ }
+
+ return ipc_srv;
+}
+
+/*
* Routine to open() a file ...
*/
@@ -850,7 +1001,10 @@ static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path,
size, mode, ino)) return True;
/* if this is NT then don't bother with the getatr */
- if (srv->cli.capabilities & CAP_NT_SMBS) return False;
+ if (srv->cli.capabilities & CAP_NT_SMBS) {
+ errno = EPERM;
+ return False;
+ }
if (cli_getatr(&srv->cli, path, mode, size, m_time)) {
a_time = c_time = m_time;
@@ -858,6 +1012,7 @@ static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path,
return True;
}
+ errno = EPERM;
return False;
}
@@ -1139,8 +1294,12 @@ int smbc_setup_stat(SMBCCTX *context, struct stat *st, char *fname, size_t size,
if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR;
st->st_size = size;
+#ifdef HAVE_STAT_ST_BLKSIZE
st->st_blksize = 512;
+#endif
+#ifdef HAVE_STAT_ST_BLOCKS
st->st_blocks = (size+511)/512;
+#endif
st->st_uid = getuid();
st->st_gid = getgid();
@@ -1198,9 +1357,7 @@ static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st)
srv = smbc_server(context, server, share, workgroup, user, password);
if (!srv) {
-
return -1; /* errno set by smbc_server */
-
}
/* if (strncmp(srv->cli.dev, "IPC", 3) == 0) {
@@ -1580,18 +1737,17 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
/*
* Get a connection to IPC$ on the server if we do not already have one
*/
-
+
srv = smbc_server(context, server, "IPC$", workgroup, user, password);
-
- if (!srv) {
-
- if (dir) {
- SAFE_FREE(dir->fname);
- SAFE_FREE(dir);
- }
- return NULL;
- }
-
+ if (!srv) {
+
+ if (dir) {
+ SAFE_FREE(dir->fname);
+ SAFE_FREE(dir);
+ }
+ return NULL;
+ }
+
dir->srv = srv;
dir->dir_type = SMBC_WORKGROUP;
@@ -2286,188 +2442,905 @@ static int smbc_fstatdir_ctx(SMBCCTX *context, SMBCFILE *dir, struct stat *st)
}
-/*
- * Open a print file to be written to by other calls
- */
-
-static SMBCFILE *smbc_open_print_job_ctx(SMBCCTX *context, const char *fname)
+int smbc_chmod_ctx(SMBCCTX *context, const char *fname, mode_t newmode)
{
- fstring server, share, user, password;
+ SMBCSRV *srv;
+ fstring server, share, user, password, workgroup;
pstring path;
-
+ uint16 mode;
+
if (!context || !context->internal ||
!context->internal->_initialized) {
- errno = EINVAL;
- return NULL;
+ errno = EINVAL; /* Best I can think of ... */
+ return -1;
}
if (!fname) {
errno = EINVAL;
- return NULL;
+ return -1;
}
- DEBUG(4, ("smbc_open_print_job_ctx(%s)\n", fname));
+ DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, newmode));
smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/
- /* What if the path is empty, or the file exists? */
+ if (user[0] == (char)0) fstrcpy(user, context->user);
- return context->open(context, fname, O_WRONLY, 666);
+ fstrcpy(workgroup, context->workgroup);
-}
+ srv = smbc_server(context, server, share, workgroup, user, password);
-/*
- * Routine to print a file on a remote server ...
- *
- * We open the file, which we assume to be on a remote server, and then
- * copy it to a print file on the share specified by printq.
- */
+ if (!srv) {
+ return -1; /* errno set by smbc_server */
+ }
-static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_print, const char *printq)
-{
- SMBCFILE *fid1, *fid2;
- int bytes, saverr, tot_bytes = 0;
- char buf[4096];
+ mode = 0;
- if (!c_file || !c_file->internal->_initialized || !c_print ||
- !c_print->internal->_initialized) {
+ if (!(newmode & (S_IWUSR | S_IWGRP | S_IWOTH))) mode |= aRONLY;
+ if ((newmode & S_IXUSR) && lp_map_archive(-1)) mode |= aARCH;
+ if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM;
+ if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN;
- errno = EINVAL;
+ if (!cli_setatr(&srv->cli, path, mode, 0)) {
+ errno = smbc_errno(context, &srv->cli);
return -1;
+ }
+
+ return 0;
+}
+
+int smbc_utimes_ctx(SMBCCTX *context, const char *fname, struct timeval *tbuf)
+{
+ SMBCSRV *srv;
+ fstring server, share, user, password, workgroup;
+ pstring path;
+ uint16 mode;
+ time_t t = (tbuf == NULL ? time(NULL) : tbuf->tv_sec);
+
+ if (!context || !context->internal ||
+ !context->internal->_initialized) {
+ errno = EINVAL; /* Best I can think of ... */
+ return -1;
+
}
- if (!fname && !printq) {
+ if (!fname) {
errno = EINVAL;
return -1;
}
+
+ DEBUG(4, ("smbc_utimes(%s, [%s])\n", fname, ctime(&t)));
- /* Try to open the file for reading ... */
+ smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/
- if ((int)(fid1 = c_file->open(c_file, fname, O_RDONLY, 0666)) < 0) {
-
- DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno));
- return -1; /* smbc_open sets errno */
-
+ if (user[0] == (char)0) fstrcpy(user, context->user);
+
+ fstrcpy(workgroup, context->workgroup);
+
+ srv = smbc_server(context, server, share, workgroup, user, password);
+
+ if (!srv) {
+ return -1; /* errno set by smbc_server */
+ }
+
+ if (!smbc_getatr(context, srv, path,
+ &mode, NULL,
+ NULL, NULL, NULL,
+ NULL)) {
+ return -1;
+ }
+
+ if (!cli_setatr(&srv->cli, path, mode, t)) {
+ /* some servers always refuse directory changes */
+ if (!(mode & aDIR)) {
+ errno = smbc_errno(context, &srv->cli);
+ return -1;
+ }
}
- /* Now, try to open the printer file for writing */
+ return 0;
+}
- if ((int)(fid2 = c_print->open_print_job(c_print, printq)) < 0) {
- saverr = errno; /* Save errno */
- c_file->close(c_file, fid1);
- errno = saverr;
- return -1;
+/* The MSDN is contradictory over the ordering of ACE entries in an ACL.
+ However NT4 gives a "The information may have been modified by a
+ computer running Windows NT 5.0" if denied ACEs do not appear before
+ allowed ACEs. */
+
+static int ace_compare(SEC_ACE *ace1, SEC_ACE *ace2)
+{
+ if (sec_ace_equal(ace1, ace2))
+ return 0;
+
+ if (ace1->type != ace2->type)
+ return ace2->type - ace1->type;
+
+ if (sid_compare(&ace1->trustee, &ace2->trustee))
+ return sid_compare(&ace1->trustee, &ace2->trustee);
+
+ if (ace1->flags != ace2->flags)
+ return ace1->flags - ace2->flags;
+
+ if (ace1->info.mask != ace2->info.mask)
+ return ace1->info.mask - ace2->info.mask;
+
+ if (ace1->size != ace2->size)
+ return ace1->size - ace2->size;
+
+ return memcmp(ace1, ace2, sizeof(SEC_ACE));
+}
+
+static void sort_acl(SEC_ACL *the_acl)
+{
+ uint32 i;
+ if (!the_acl) return;
+
+ qsort(the_acl->ace, the_acl->num_aces, sizeof(the_acl->ace[0]), QSORT_CAST ace_compare);
+
+ for (i=1;i<the_acl->num_aces;) {
+ if (sec_ace_equal(&the_acl->ace[i-1], &the_acl->ace[i])) {
+ int j;
+ for (j=i; j<the_acl->num_aces-1; j++) {
+ the_acl->ace[j] = the_acl->ace[j+1];
+ }
+ the_acl->num_aces--;
+ } else {
+ i++;
+ }
+ }
+}
+
+/* convert a SID to a string, either numeric or username/group */
+static void convert_sid_to_string(struct cli_state *ipc_cli,
+ POLICY_HND *pol,
+ fstring str,
+ BOOL numeric,
+ DOM_SID *sid)
+{
+ char **domains = NULL;
+ char **names = NULL;
+ uint32 *types = NULL;
+
+ sid_to_string(str, sid);
+
+ if (numeric) return; /* no lookup desired */
+
+ /* Ask LSA to convert the sid to a name */
+
+ if (!NT_STATUS_IS_OK(cli_lsa_lookup_sids(ipc_cli, ipc_cli->mem_ctx,
+ pol, 1, sid, &domains,
+ &names, &types)) ||
+ !domains || !domains[0] || !names || !names[0]) {
+ return;
+ }
+
+ /* Converted OK */
+
+ slprintf(str, sizeof(fstring) - 1, "%s%s%s",
+ domains[0], lp_winbind_separator(),
+ names[0]);
+}
+
+/* convert a string to a SID, either numeric or username/group */
+static BOOL convert_string_to_sid(struct cli_state *ipc_cli,
+ POLICY_HND *pol,
+ BOOL numeric,
+ DOM_SID *sid,
+ const char *str)
+{
+ uint32 *types = NULL;
+ DOM_SID *sids = NULL;
+ BOOL result = True;
+
+ if (numeric) {
+ if (strncmp(str, "S-", 2) == 0) {
+ return string_to_sid(sid, str);
+ }
+
+ result = False;
+ goto done;
+ }
+
+ if (!NT_STATUS_IS_OK(cli_lsa_lookup_names(ipc_cli, ipc_cli->mem_ctx,
+ pol, 1, &str, &sids,
+ &types))) {
+ result = False;
+ goto done;
}
- while ((bytes = c_file->read(c_file, fid1, buf, sizeof(buf))) > 0) {
+ sid_copy(sid, &sids[0]);
+ done:
+
+ return result;
+}
- tot_bytes += bytes;
- if ((c_print->write(c_print, fid2, buf, bytes)) < 0) {
+/* parse an ACE in the same format as print_ace() */
+static BOOL parse_ace(struct cli_state *ipc_cli,
+ POLICY_HND *pol,
+ SEC_ACE *ace,
+ BOOL numeric,
+ char *str)
+{
+ char *p;
+ const char *cp;
+ fstring tok;
+ unsigned atype, aflags, amask;
+ DOM_SID sid;
+ SEC_ACCESS mask;
+ const struct perm_value *v;
+ struct perm_value {
+ const char *perm;
+ uint32 mask;
+ };
+
+ /* These values discovered by inspection */
+ static const struct perm_value special_values[] = {
+ { "R", 0x00120089 },
+ { "W", 0x00120116 },
+ { "X", 0x001200a0 },
+ { "D", 0x00010000 },
+ { "P", 0x00040000 },
+ { "O", 0x00080000 },
+ { NULL, 0 },
+ };
+
+ static const struct perm_value standard_values[] = {
+ { "READ", 0x001200a9 },
+ { "CHANGE", 0x001301bf },
+ { "FULL", 0x001f01ff },
+ { NULL, 0 },
+ };
+
+
+ ZERO_STRUCTP(ace);
+ p = strchr_m(str,':');
+ if (!p) return False;
+ *p = '\0';
+ p++;
+ /* Try to parse numeric form */
+
+ if (sscanf(p, "%i/%i/%i", &atype, &aflags, &amask) == 3 &&
+ convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) {
+ goto done;
+ }
+
+ /* Try to parse text form */
+
+ if (!convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) {
+ return False;
+ }
+
+ cp = p;
+ if (!next_token(&cp, tok, "/", sizeof(fstring))) {
+ return False;
+ }
+
+ if (StrnCaseCmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) {
+ atype = SEC_ACE_TYPE_ACCESS_ALLOWED;
+ } else if (StrnCaseCmp(tok, "DENIED", strlen("DENIED")) == 0) {
+ atype = SEC_ACE_TYPE_ACCESS_DENIED;
+ } else {
+ return False;
+ }
- saverr = errno;
- c_file->close(c_file, fid1);
- c_print->close(c_print, fid2);
- errno = saverr;
+ /* Only numeric form accepted for flags at present */
+ if (!(next_token(&cp, tok, "/", sizeof(fstring)) &&
+ sscanf(tok, "%i", &aflags))) {
+ return False;
+ }
+
+ if (!next_token(&cp, tok, "/", sizeof(fstring))) {
+ return False;
+ }
+
+ if (strncmp(tok, "0x", 2) == 0) {
+ if (sscanf(tok, "%i", &amask) != 1) {
+ return False;
}
+ goto done;
+ }
+ for (v = standard_values; v->perm; v++) {
+ if (strcmp(tok, v->perm) == 0) {
+ amask = v->mask;
+ goto done;
+ }
}
- saverr = errno;
+ p = tok;
- c_file->close(c_file, fid1); /* We have to close these anyway */
- c_print->close(c_print, fid2);
+ while(*p) {
+ BOOL found = False;
- if (bytes < 0) {
+ for (v = special_values; v->perm; v++) {
+ if (v->perm[0] == *p) {
+ amask |= v->mask;
+ found = True;
+ }
+ }
- errno = saverr;
- return -1;
+ if (!found) return False;
+ p++;
+ }
+ if (*p) {
+ return False;
}
- return tot_bytes;
+ done:
+ mask.mask = amask;
+ init_sec_ace(ace, &sid, atype, mask, aflags);
+ return True;
+}
+
+/* add an ACE to a list of ACEs in a SEC_ACL */
+static BOOL add_ace(SEC_ACL **the_acl, SEC_ACE *ace, TALLOC_CTX *ctx)
+{
+ SEC_ACL *new;
+ SEC_ACE *aces;
+ if (! *the_acl) {
+ (*the_acl) = make_sec_acl(ctx, 3, 1, ace);
+ return True;
+ }
+ aces = calloc(1+(*the_acl)->num_aces,sizeof(SEC_ACE));
+ memcpy(aces, (*the_acl)->ace, (*the_acl)->num_aces * sizeof(SEC_ACE));
+ memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE));
+ new = make_sec_acl(ctx,(*the_acl)->revision,1+(*the_acl)->num_aces, aces);
+ SAFE_FREE(aces);
+ (*the_acl) = new;
+ return True;
}
-/*
- * Routine to list print jobs on a printer share ...
- */
-static int smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, smbc_list_print_job_fn fn)
+/* parse a ascii version of a security descriptor */
+static SEC_DESC *sec_desc_parse(TALLOC_CTX *ctx,
+ struct cli_state *ipc_cli,
+ POLICY_HND *pol,
+ BOOL numeric,
+ char *str)
{
- SMBCSRV *srv;
- fstring server, share, user, password, workgroup;
- pstring path;
+ const char *p = str;
+ fstring tok;
+ SEC_DESC *ret;
+ size_t sd_size;
+ DOM_SID *grp_sid=NULL, *owner_sid=NULL;
+ SEC_ACL *dacl=NULL;
+ int revision=1;
+
+ while (next_token(&p, tok, "\t,\r\n", sizeof(tok))) {
+
+ if (StrnCaseCmp(tok,"REVISION:", 9) == 0) {
+ revision = strtol(tok+9, NULL, 16);
+ continue;
+ }
- if (!context || !context->internal ||
- !context->internal->_initialized) {
+ if (StrnCaseCmp(tok,"OWNER:", 6) == 0) {
+ owner_sid = (DOM_SID *)calloc(1, sizeof(DOM_SID));
+ if (!owner_sid ||
+ !convert_string_to_sid(ipc_cli, pol,
+ numeric,
+ owner_sid, tok+6)) {
+ DEBUG(5, ("Failed to parse owner sid\n"));
+ return NULL;
+ }
+ continue;
+ }
- errno = EINVAL;
+ if (StrnCaseCmp(tok,"OWNER+:", 7) == 0) {
+ owner_sid = (DOM_SID *)calloc(1, sizeof(DOM_SID));
+ if (!owner_sid ||
+ !convert_string_to_sid(ipc_cli, pol,
+ False,
+ owner_sid, tok+7)) {
+ DEBUG(5, ("Failed to parse owner sid\n"));
+ return NULL;
+ }
+ continue;
+ }
+
+ if (StrnCaseCmp(tok,"GROUP:", 6) == 0) {
+ grp_sid = (DOM_SID *)calloc(1, sizeof(DOM_SID));
+ if (!grp_sid ||
+ !convert_string_to_sid(ipc_cli, pol,
+ numeric,
+ grp_sid, tok+6)) {
+ DEBUG(5, ("Failed to parse group sid\n"));
+ return NULL;
+ }
+ continue;
+ }
+
+ if (StrnCaseCmp(tok,"GROUP+:", 7) == 0) {
+ grp_sid = (DOM_SID *)calloc(1, sizeof(DOM_SID));
+ if (!grp_sid ||
+ !convert_string_to_sid(ipc_cli, pol,
+ False,
+ grp_sid, tok+6)) {
+ DEBUG(5, ("Failed to parse group sid\n"));
+ return NULL;
+ }
+ continue;
+ }
+
+ if (StrnCaseCmp(tok,"ACL:", 4) == 0) {
+ SEC_ACE ace;
+ if (!parse_ace(ipc_cli, pol, &ace, numeric, tok+4)) {
+ DEBUG(5, ("Failed to parse ACL %s\n", tok));
+ return NULL;
+ }
+ if(!add_ace(&dacl, &ace, ctx)) {
+ DEBUG(5, ("Failed to add ACL %s\n", tok));
+ return NULL;
+ }
+ continue;
+ }
+
+ if (StrnCaseCmp(tok,"ACL+:", 5) == 0) {
+ SEC_ACE ace;
+ if (!parse_ace(ipc_cli, pol, &ace, False, tok+5)) {
+ DEBUG(5, ("Failed to parse ACL %s\n", tok));
+ return NULL;
+ }
+ if(!add_ace(&dacl, &ace, ctx)) {
+ DEBUG(5, ("Failed to add ACL %s\n", tok));
+ return NULL;
+ }
+ continue;
+ }
+
+ DEBUG(5, ("Failed to parse security descriptor\n"));
+ return NULL;
+ }
+
+ ret = make_sec_desc(ctx, revision, SEC_DESC_SELF_RELATIVE,
+ owner_sid, grp_sid, NULL, dacl, &sd_size);
+
+ SAFE_FREE(grp_sid);
+ SAFE_FREE(owner_sid);
+
+ return ret;
+}
+
+
+/*****************************************************
+retrieve the acls for a file
+*******************************************************/
+static int cacl_get(TALLOC_CTX *ctx, struct cli_state *cli,
+ struct cli_state *ipc_cli, POLICY_HND *pol,
+ char *filename, char *name, char *buf, int bufsize)
+{
+ uint32 i;
+ int n = 0;
+ int n_used;
+ BOOL all;
+ BOOL numeric = True;
+ BOOL determine_size = (bufsize == 0);
+ int fnum = -1;
+ SEC_DESC *sd;
+ fstring sidstr;
+ char *p;
+
+ fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ);
+
+ if (fnum == -1) {
+ DEBUG(5, ("cacl_get failed to open %s: %s\n",
+ filename, cli_errstr(cli)));
+ errno = 0;
return -1;
+ }
+ sd = cli_query_secdesc(cli, fnum, ctx);
+
+ if (!sd) {
+ DEBUG(5, ("cacl_get Failed to query old descriptor\n"));
+ errno = 0;
+ return -1;
}
- if (!fname) {
-
- errno = EINVAL;
+ cli_close(cli, fnum);
+
+ all = (*name == '*');
+ numeric = (* (name + strlen(name) - 1) != '+');
+
+ n_used = 0;
+
+ if (all) {
+ if (determine_size) {
+ p = talloc_asprintf(ctx,
+ "REVISION:%d", sd->revision);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize,
+ "REVISION:%d", sd->revision);
+ }
+ } else if (StrCaseCmp(name, "revision") == 0) {
+ if (determine_size) {
+ p = talloc_asprintf(ctx, "%d", sd->revision);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize, "%d", sd->revision);
+ }
+ }
+
+ if (!determine_size && n > bufsize) {
+ errno = ERANGE;
+ return -1;
+ }
+ buf += n;
+ n_used += n;
+ bufsize -= n;
+
+ /* Get owner and group sid */
+
+ if (sd->owner_sid) {
+ convert_sid_to_string(ipc_cli, pol,
+ sidstr, numeric, sd->owner_sid);
+ } else {
+ fstrcpy(sidstr, "");
+ }
+
+ if (all) {
+ if (determine_size) {
+ p = talloc_asprintf(ctx, ",OWNER:%s", sidstr);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize, ",OWNER:%s", sidstr);
+ }
+ } else if (StrnCaseCmp(name, "owner", 5) == 0) {
+ if (determine_size) {
+ p = talloc_asprintf(ctx, "%s", sidstr);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize, "%s", sidstr);
+ }
+ }
+
+ if (!determine_size && n > bufsize) {
+ errno = ERANGE;
+ return -1;
+ }
+ buf += n;
+ n_used += n;
+ bufsize -= n;
+
+ if (sd->grp_sid) {
+ convert_sid_to_string(ipc_cli, pol,
+ sidstr, numeric, sd->grp_sid);
+ } else {
+ fstrcpy(sidstr, "");
+ }
+
+ if (all) {
+ if (determine_size) {
+ p = talloc_asprintf(ctx, ",GROUP:%s", sidstr);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize, ",GROUP:%s", sidstr);
+ }
+ } else if (StrnCaseCmp(name, "group", 5) == 0) {
+ if (determine_size) {
+ p = talloc_asprintf(ctx, "%s", sidstr);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize, "%s", sidstr);
+ }
+ }
+
+ if (!determine_size && n > bufsize) {
+ errno = ERANGE;
+ return -1;
+ }
+ buf += n;
+ n_used += n;
+ bufsize -= n;
+
+ /* Add aces to value buffer */
+ for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
+
+ SEC_ACE *ace = &sd->dacl->ace[i];
+ convert_sid_to_string(ipc_cli, pol,
+ sidstr, numeric, &ace->trustee);
+
+ if (all) {
+ if (determine_size) {
+ p = talloc_asprintf(ctx,
+ ",ACL:%s:%d/%d/0x%08x",
+ sidstr,
+ ace->type,
+ ace->flags,
+ ace->info.mask);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize,
+ ",ACL:%s:%d/%d/0x%08x",
+ sidstr,
+ ace->type,
+ ace->flags,
+ ace->info.mask);
+ }
+ } else if ((StrnCaseCmp(name, "acl", 3) == 0 &&
+ StrCaseCmp(name + 3, sidstr) == 0) ||
+ (StrnCaseCmp(name, "acl+", 4) == 0 &&
+ StrCaseCmp(name + 4, sidstr) == 0)) {
+ if (determine_size) {
+ p = talloc_asprintf(ctx,
+ "%d/%d/0x%08x",
+ ace->type,
+ ace->flags,
+ ace->info.mask);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize,
+ "%d/%d/0x%08x",
+ ace->type, ace->flags, ace->info.mask);
+ }
+ }
+ if (n > bufsize) {
+ errno = ERANGE;
+ return -1;
+ }
+ buf += n;
+ n_used += n;
+ bufsize -= n;
+ }
+
+ if (n_used == 0) {
+ errno = ENOATTR;
+ return -1;
+ }
+ return n_used;
+}
+
+
+/*****************************************************
+set the ACLs on a file given an ascii description
+*******************************************************/
+static int cacl_set(TALLOC_CTX *ctx, struct cli_state *cli,
+ struct cli_state *ipc_cli, POLICY_HND *pol,
+ const char *filename, const char *the_acl,
+ int mode, int flags)
+{
+ int fnum;
+ int err = 0;
+ SEC_DESC *sd = NULL, *old;
+ SEC_ACL *dacl = NULL;
+ DOM_SID *owner_sid = NULL;
+ DOM_SID *grp_sid = NULL;
+ uint32 i, j;
+ size_t sd_size;
+ int ret = 0;
+ char *p;
+ BOOL numeric = True;
+
+ /* the_acl will be null for REMOVE_ALL operations */
+ if (the_acl) {
+ numeric = ((p = strchr(the_acl, ':')) != NULL &&
+ p > the_acl &&
+ p[-1] != '+');
+
+ /* if this is to set the entire ACL... */
+ if (*the_acl == '*') {
+ /* ... then increment past the first colon */
+ the_acl = p + 1;
+ }
+
+ sd = sec_desc_parse(ctx, ipc_cli, pol,
+ numeric, (char *) the_acl);
+
+ if (!sd) {
+ errno = EINVAL;
+ return -1;
+ }
+ }
+
+ /* The desired access below is the only one I could find that works
+ with NT4, W2KP and Samba */
+
+ fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ);
+
+ if (fnum == -1) {
+ DEBUG(5, ("cacl_set failed to open %s: %s\n",
+ filename, cli_errstr(cli)));
+ errno = 0;
return -1;
+ }
+
+ old = cli_query_secdesc(cli, fnum, ctx);
+ if (!old) {
+ DEBUG(5, ("cacl_set Failed to query old descriptor\n"));
+ errno = 0;
+ return -1;
}
-
- DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname));
- smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/
+ cli_close(cli, fnum);
- if (user[0] == (char)0) fstrcpy(user, context->user);
-
- fstrcpy(workgroup, context->workgroup);
+ switch (mode) {
+ case SMBC_XATTR_MODE_REMOVE_ALL:
+ old->dacl->num_aces = 0;
+ SAFE_FREE(old->dacl->ace);
+ SAFE_FREE(old->dacl);
+ old->off_dacl = 0;
+ dacl = old->dacl;
+ break;
- srv = smbc_server(context, server, share, workgroup, user, password);
+ case SMBC_XATTR_MODE_REMOVE:
+ for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) {
+ BOOL found = False;
- if (!srv) {
+ for (j=0;old->dacl && j<old->dacl->num_aces;j++) {
+ if (sec_ace_equal(&sd->dacl->ace[i],
+ &old->dacl->ace[j])) {
+ uint32 k;
+ for (k=j; k<old->dacl->num_aces-1;k++) {
+ old->dacl->ace[k] = old->dacl->ace[k+1];
+ }
+ old->dacl->num_aces--;
+ if (old->dacl->num_aces == 0) {
+ SAFE_FREE(old->dacl->ace);
+ SAFE_FREE(old->dacl);
+ old->off_dacl = 0;
+ }
+ found = True;
+ dacl = old->dacl;
+ break;
+ }
+ }
- return -1; /* errno set by smbc_server */
+ if (!found) {
+ err = ENOATTR;
+ ret = -1;
+ goto failed;
+ }
+ }
+ break;
+
+ case SMBC_XATTR_MODE_ADD:
+ for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) {
+ BOOL found = False;
+
+ for (j=0;old->dacl && j<old->dacl->num_aces;j++) {
+ if (sid_equal(&sd->dacl->ace[i].trustee,
+ &old->dacl->ace[j].trustee)) {
+ if (!(flags & SMBC_XATTR_FLAG_CREATE)) {
+ err = EEXIST;
+ ret = -1;
+ goto failed;
+ }
+ old->dacl->ace[j] = sd->dacl->ace[i];
+ ret = -1;
+ found = True;
+ }
+ }
+
+ if (!found && (flags & SMBC_XATTR_FLAG_REPLACE)) {
+ err = ENOATTR;
+ ret = -1;
+ goto failed;
+ }
+
+ for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) {
+ add_ace(&old->dacl, &sd->dacl->ace[i], ctx);
+ }
+ }
+ dacl = old->dacl;
+ break;
+
+ case SMBC_XATTR_MODE_SET:
+ old = sd;
+ owner_sid = old->owner_sid;
+ grp_sid = old->grp_sid;
+ dacl = old->dacl;
+ break;
+ case SMBC_XATTR_MODE_CHOWN:
+ owner_sid = sd->owner_sid;
+ break;
+
+ case SMBC_XATTR_MODE_CHGRP:
+ grp_sid = sd->grp_sid;
+ break;
}
- if (cli_print_queue(&srv->cli, (void (*)(struct print_job_info *))fn) < 0) {
+ /* Denied ACE entries must come before allowed ones */
+ sort_acl(old->dacl);
- errno = smbc_errno(context, &srv->cli);
+ /* Create new security descriptor and set it */
+ sd = make_sec_desc(ctx, old->revision, SEC_DESC_SELF_RELATIVE,
+ owner_sid, grp_sid, NULL, dacl, &sd_size);
+
+ fnum = cli_nt_create(cli, filename,
+ WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS);
+
+ if (fnum == -1) {
+ DEBUG(5, ("cacl_set failed to open %s: %s\n",
+ filename, cli_errstr(cli)));
+ errno = 0;
return -1;
+ }
+ if (!cli_set_secdesc(cli, fnum, sd)) {
+ DEBUG(5, ("ERROR: secdesc set failed: %s\n", cli_errstr(cli)));
+ ret = -1;
}
-
- return 0;
+ /* Clean up */
+
+ failed:
+ cli_close(cli, fnum);
+
+ if (err != 0) {
+ errno = err;
+ }
+
+ return ret;
}
-/*
- * Delete a print job from a remote printer share
- */
-static int smbc_unlink_print_job_ctx(SMBCCTX *context, const char *fname, int id)
+int smbc_setxattr_ctx(SMBCCTX *context,
+ const char *fname,
+ const char *name,
+ const void *value,
+ size_t size,
+ int flags)
{
- SMBCSRV *srv;
+ int ret;
+ SMBCSRV *srv;
+ SMBCSRV *ipc_srv;
fstring server, share, user, password, workgroup;
pstring path;
- int err;
+ TALLOC_CTX *ctx;
+ POLICY_HND pol;
if (!context || !context->internal ||
!context->internal->_initialized) {
- errno = EINVAL;
+ errno = EINVAL; /* Best I can think of ... */
return -1;
-
+
}
if (!fname) {
@@ -2477,7 +3350,8 @@ static int smbc_unlink_print_job_ctx(SMBCCTX *context, const char *fname, int id
}
- DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname));
+ DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n",
+ fname, name, (int) size, (char *) value));
smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/
@@ -2486,24 +3360,538 @@ static int smbc_unlink_print_job_ctx(SMBCCTX *context, const char *fname, int id
fstrcpy(workgroup, context->workgroup);
srv = smbc_server(context, server, share, workgroup, user, password);
-
if (!srv) {
-
return -1; /* errno set by smbc_server */
-
}
- if ((err = cli_printjob_del(&srv->cli, id)) != 0) {
+ ipc_srv = smbc_attr_server(context, server, share,
+ workgroup, user, password,
+ &pol);
+ if (!ipc_srv) {
+ return -1;
+ }
+
+ ctx = talloc_init("smbc_setxattr");
+ if (!ctx) {
+ errno = ENOMEM;
+ return -1;
+ }
- if (err < 0)
- errno = smbc_errno(context, &srv->cli);
- else if (err == ERRnosuchprintjob)
- errno = EINVAL;
- return -1;
+ /*
+ * Are they asking to set an access control element or to set
+ * the entire access control list?
+ */
+ if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 ||
+ StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 ||
+ StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 ||
+ StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 ||
+ StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) {
+
+ /* Yup. */
+ char *namevalue =
+ talloc_asprintf(ctx, "%s:%s", name+19, (char *) value);
+ if (! namevalue) {
+ errno = ENOMEM;
+ ret = -1;
+ } else {
+ ret = cacl_set(ctx, &srv->cli,
+ &ipc_srv->cli, &pol, path,
+ namevalue,
+ (*namevalue == '*'
+ ? SMBC_XATTR_MODE_SET
+ : SMBC_XATTR_MODE_ADD),
+ flags);
+ }
+ talloc_destroy(ctx);
+ return ret;
+ }
- }
+ /*
+ * Are they asking to set the owner?
+ */
+ if (StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 ||
+ StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0) {
+
+ /* Yup. */
+ char *namevalue =
+ talloc_asprintf(ctx, "%s:%s", name+19, (char *) value);
+ if (! namevalue) {
+ errno = ENOMEM;
+ ret = -1;
+ } else {
+ ret = cacl_set(ctx, &srv->cli,
+ &ipc_srv->cli, &pol, path,
+ namevalue, SMBC_XATTR_MODE_CHOWN, 0);
+ }
+ talloc_destroy(ctx);
+ return ret;
+ }
- return 0;
+ /*
+ * Are they asking to set the group?
+ */
+ if (StrCaseCmp(name, "system.nt_sec_desc.group") == 0 ||
+ StrCaseCmp(name, "system.nt_sec_desc.group+") == 0) {
+
+ /* Yup. */
+ char *namevalue =
+ talloc_asprintf(ctx, "%s:%s", name+19, (char *) value);
+ if (! namevalue) {
+ errno = ENOMEM;
+ ret = -1;
+ } else {
+ ret = cacl_set(ctx, &srv->cli,
+ &ipc_srv->cli, &pol, path,
+ namevalue, SMBC_XATTR_MODE_CHOWN, 0);
+ }
+ talloc_destroy(ctx);
+ return ret;
+ }
+
+ /* Unsupported attribute name */
+ talloc_destroy(ctx);
+ errno = EINVAL;
+ return -1;
+}
+
+int smbc_getxattr_ctx(SMBCCTX *context,
+ const char *fname,
+ const char *name,
+ const void *value,
+ size_t size)
+{
+ int ret;
+ SMBCSRV *srv;
+ SMBCSRV *ipc_srv;
+ fstring server, share, user, password, workgroup;
+ pstring path;
+ TALLOC_CTX *ctx;
+ POLICY_HND pol;
+
+ if (!context || !context->internal ||
+ !context->internal->_initialized) {
+
+ errno = EINVAL; /* Best I can think of ... */
+ return -1;
+
+ }
+
+ if (!fname) {
+
+ errno = EINVAL;
+ return -1;
+
+ }
+
+ DEBUG(4, ("smbc_getxattr(%s, %s)\n", fname, name));
+
+ smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/
+
+ if (user[0] == (char)0) fstrcpy(user, context->user);
+
+ fstrcpy(workgroup, context->workgroup);
+
+ srv = smbc_server(context, server, share, workgroup, user, password);
+ if (!srv) {
+ return -1; /* errno set by smbc_server */
+ }
+
+ ipc_srv = smbc_attr_server(context, server, share,
+ workgroup, user, password,
+ &pol);
+ if (!ipc_srv) {
+ return -1;
+ }
+
+ ctx = talloc_init("smbc:getxattr");
+ if (!ctx) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ /* Are they requesting a supported attribute? */
+ if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 ||
+ StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 ||
+ StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 ||
+ StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 ||
+ StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0 ||
+ StrCaseCmp(name, "system.nt_sec_desc.group") == 0 ||
+ StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 ||
+ StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 ||
+ StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) {
+
+ /* Yup. */
+ ret = cacl_get(ctx, &srv->cli,
+ &ipc_srv->cli, &pol,
+ (char *) path, (char *) name + 19,
+ (char *) value, size);
+ if (ret < 0 && errno == 0) {
+ errno = smbc_errno(context, &srv->cli);
+ }
+ talloc_destroy(ctx);
+ return ret;
+ }
+
+ /* Unsupported attribute name */
+ talloc_destroy(ctx);
+ errno = EINVAL;
+ return -1;
+}
+
+
+int smbc_removexattr_ctx(SMBCCTX *context,
+ const char *fname,
+ const char *name)
+{
+ int ret;
+ SMBCSRV *srv;
+ SMBCSRV *ipc_srv;
+ fstring server, share, user, password, workgroup;
+ pstring path;
+ TALLOC_CTX *ctx;
+ POLICY_HND pol;
+
+ if (!context || !context->internal ||
+ !context->internal->_initialized) {
+
+ errno = EINVAL; /* Best I can think of ... */
+ return -1;
+
+ }
+
+ if (!fname) {
+
+ errno = EINVAL;
+ return -1;
+
+ }
+
+ DEBUG(4, ("smbc_removexattr(%s, %s)\n", fname, name));
+
+ smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/
+
+ if (user[0] == (char)0) fstrcpy(user, context->user);
+
+ fstrcpy(workgroup, context->workgroup);
+
+ srv = smbc_server(context, server, share, workgroup, user, password);
+ if (!srv) {
+ return -1; /* errno set by smbc_server */
+ }
+
+ ipc_srv = smbc_attr_server(context, server, share,
+ workgroup, user, password,
+ &pol);
+ if (!ipc_srv) {
+ return -1;
+ }
+
+ ipc_srv = smbc_attr_server(context, server, share,
+ workgroup, user, password,
+ &pol);
+ if (!ipc_srv) {
+ return -1;
+ }
+
+ ctx = talloc_init("smbc_removexattr");
+ if (!ctx) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ /* Are they asking to set the entire ACL? */
+ if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 ||
+ StrCaseCmp(name, "system.nt_sec_desc.*+") == 0) {
+
+ /* Yup. */
+ ret = cacl_set(ctx, &srv->cli,
+ &ipc_srv->cli, &pol, path,
+ NULL, SMBC_XATTR_MODE_REMOVE_ALL, 0);
+ talloc_destroy(ctx);
+ return ret;
+ }
+
+ /*
+ * Are they asking to remove one or more spceific security descriptor
+ * attributes?
+ */
+ if (StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 ||
+ StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 ||
+ StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0 ||
+ StrCaseCmp(name, "system.nt_sec_desc.group") == 0 ||
+ StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 ||
+ StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 ||
+ StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) {
+
+ /* Yup. */
+ ret = cacl_set(ctx, &srv->cli,
+ &ipc_srv->cli, &pol, path,
+ name + 19, SMBC_XATTR_MODE_REMOVE, 0);
+ talloc_destroy(ctx);
+ return ret;
+ }
+
+ /* Unsupported attribute name */
+ talloc_destroy(ctx);
+ errno = EINVAL;
+ return -1;
+}
+
+int smbc_listxattr_ctx(SMBCCTX *context,
+ const char *fname,
+ char *list,
+ size_t size)
+{
+ /*
+ * This isn't quite what listxattr() is supposed to do. This returns
+ * the complete set of attributes, always, rather than only those
+ * attribute names which actually exist for a file. Hmmm...
+ */
+ const char supported[] =
+ "system.nt_sec_desc.revision\0"
+ "system.nt_sec_desc.owner\0"
+ "system.nt_sec_desc.owner+\0"
+ "system.nt_sec_desc.group\0"
+ "system.nt_sec_desc.group+\0"
+ "system.nt_sec_desc.acl\0"
+ "system.nt_sec_desc.acl+\0"
+ "system.nt_sec_desc.*\0"
+ "system.nt_sec_desc.*+\0"
+ ;
+
+ if (size == 0) {
+ return sizeof(supported);
+ }
+
+ if (sizeof(supported) > size) {
+ errno = ERANGE;
+ return -1;
+ }
+
+ /* this can't be strcpy() because there are embedded null characters */
+ memcpy(list, supported, sizeof(supported));
+ return sizeof(supported);
+}
+
+
+/*
+ * Open a print file to be written to by other calls
+ */
+
+static SMBCFILE *smbc_open_print_job_ctx(SMBCCTX *context, const char *fname)
+{
+ fstring server, share, user, password;
+ pstring path;
+
+ if (!context || !context->internal ||
+ !context->internal->_initialized) {
+
+ errno = EINVAL;
+ return NULL;
+
+ }
+
+ if (!fname) {
+
+ errno = EINVAL;
+ return NULL;
+
+ }
+
+ DEBUG(4, ("smbc_open_print_job_ctx(%s)\n", fname));
+
+ smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/
+
+ /* What if the path is empty, or the file exists? */
+
+ return context->open(context, fname, O_WRONLY, 666);
+
+}
+
+/*
+ * Routine to print a file on a remote server ...
+ *
+ * We open the file, which we assume to be on a remote server, and then
+ * copy it to a print file on the share specified by printq.
+ */
+
+static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_print, const char *printq)
+{
+ SMBCFILE *fid1, *fid2;
+ int bytes, saverr, tot_bytes = 0;
+ char buf[4096];
+
+ if (!c_file || !c_file->internal->_initialized || !c_print ||
+ !c_print->internal->_initialized) {
+
+ errno = EINVAL;
+ return -1;
+
+ }
+
+ if (!fname && !printq) {
+
+ errno = EINVAL;
+ return -1;
+
+ }
+
+ /* Try to open the file for reading ... */
+
+ if ((int)(fid1 = c_file->open(c_file, fname, O_RDONLY, 0666)) < 0) {
+
+ DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno));
+ return -1; /* smbc_open sets errno */
+
+ }
+
+ /* Now, try to open the printer file for writing */
+
+ if ((int)(fid2 = c_print->open_print_job(c_print, printq)) < 0) {
+
+ saverr = errno; /* Save errno */
+ c_file->close(c_file, fid1);
+ errno = saverr;
+ return -1;
+
+ }
+
+ while ((bytes = c_file->read(c_file, fid1, buf, sizeof(buf))) > 0) {
+
+ tot_bytes += bytes;
+
+ if ((c_print->write(c_print, fid2, buf, bytes)) < 0) {
+
+ saverr = errno;
+ c_file->close(c_file, fid1);
+ c_print->close(c_print, fid2);
+ errno = saverr;
+
+ }
+
+ }
+
+ saverr = errno;
+
+ c_file->close(c_file, fid1); /* We have to close these anyway */
+ c_print->close(c_print, fid2);
+
+ if (bytes < 0) {
+
+ errno = saverr;
+ return -1;
+
+ }
+
+ return tot_bytes;
+
+}
+
+/*
+ * Routine to list print jobs on a printer share ...
+ */
+
+static int smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, smbc_list_print_job_fn fn)
+{
+ SMBCSRV *srv;
+ fstring server, share, user, password, workgroup;
+ pstring path;
+
+ if (!context || !context->internal ||
+ !context->internal->_initialized) {
+
+ errno = EINVAL;
+ return -1;
+
+ }
+
+ if (!fname) {
+
+ errno = EINVAL;
+ return -1;
+
+ }
+
+ DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname));
+
+ smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/
+
+ if (user[0] == (char)0) fstrcpy(user, context->user);
+
+ fstrcpy(workgroup, context->workgroup);
+
+ srv = smbc_server(context, server, share, workgroup, user, password);
+
+ if (!srv) {
+
+ return -1; /* errno set by smbc_server */
+
+ }
+
+ if (cli_print_queue(&srv->cli, (void (*)(struct print_job_info *))fn) < 0) {
+
+ errno = smbc_errno(context, &srv->cli);
+ return -1;
+
+ }
+
+ return 0;
+
+}
+
+/*
+ * Delete a print job from a remote printer share
+ */
+
+static int smbc_unlink_print_job_ctx(SMBCCTX *context, const char *fname, int id)
+{
+ SMBCSRV *srv;
+ fstring server, share, user, password, workgroup;
+ pstring path;
+ int err;
+
+ if (!context || !context->internal ||
+ !context->internal->_initialized) {
+
+ errno = EINVAL;
+ return -1;
+
+ }
+
+ if (!fname) {
+
+ errno = EINVAL;
+ return -1;
+
+ }
+
+ DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname));
+
+ smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/
+
+ if (user[0] == (char)0) fstrcpy(user, context->user);
+
+ fstrcpy(workgroup, context->workgroup);
+
+ srv = smbc_server(context, server, share, workgroup, user, password);
+
+ if (!srv) {
+
+ return -1; /* errno set by smbc_server */
+
+ }
+
+ if ((err = cli_printjob_del(&srv->cli, id)) != 0) {
+
+ if (err < 0)
+ errno = smbc_errno(context, &srv->cli);
+ else if (err == ERRnosuchprintjob)
+ errno = EINVAL;
+ return -1;
+
+ }
+
+ return 0;
}
@@ -2512,59 +3900,65 @@ static int smbc_unlink_print_job_ctx(SMBCCTX *context, const char *fname, int id
*/
SMBCCTX * smbc_new_context(void)
{
- SMBCCTX * context;
-
- context = malloc(sizeof(SMBCCTX));
- if (!context) {
- errno = ENOMEM;
- return NULL;
- }
+ SMBCCTX * context;
- ZERO_STRUCTP(context);
+ context = malloc(sizeof(SMBCCTX));
+ if (!context) {
+ errno = ENOMEM;
+ return NULL;
+ }
- context->internal = malloc(sizeof(struct smbc_internal_data));
- if (!context->internal) {
- errno = ENOMEM;
- return NULL;
- }
+ ZERO_STRUCTP(context);
- ZERO_STRUCTP(context->internal);
+ context->internal = malloc(sizeof(struct smbc_internal_data));
+ if (!context->internal) {
+ errno = ENOMEM;
+ return NULL;
+ }
-
- /* ADD REASONABLE DEFAULTS */
- context->debug = 0;
- context->timeout = 20000; /* 20 seconds */
-
- context->open = smbc_open_ctx;
- context->creat = smbc_creat_ctx;
- context->read = smbc_read_ctx;
- context->write = smbc_write_ctx;
- context->close = smbc_close_ctx;
- context->unlink = smbc_unlink_ctx;
- context->rename = smbc_rename_ctx;
- context->lseek = smbc_lseek_ctx;
- context->stat = smbc_stat_ctx;
- context->fstat = smbc_fstat_ctx;
- context->opendir = smbc_opendir_ctx;
- context->closedir = smbc_closedir_ctx;
- context->readdir = smbc_readdir_ctx;
- context->getdents = smbc_getdents_ctx;
- context->mkdir = smbc_mkdir_ctx;
- context->rmdir = smbc_rmdir_ctx;
- context->telldir = smbc_telldir_ctx;
- context->lseekdir = smbc_lseekdir_ctx;
- context->fstatdir = smbc_fstatdir_ctx;
- context->open_print_job = smbc_open_print_job_ctx;
- context->print_file = smbc_print_file_ctx;
- context->list_print_jobs = smbc_list_print_jobs_ctx;
- context->unlink_print_job = smbc_unlink_print_job_ctx;
-
- context->callbacks.check_server_fn = smbc_check_server;
- context->callbacks.remove_unused_server_fn = smbc_remove_unused_server;
-
- smbc_default_cache_functions(context);
-
- return context;
+ ZERO_STRUCTP(context->internal);
+
+
+ /* ADD REASONABLE DEFAULTS */
+ context->debug = 0;
+ context->timeout = 20000; /* 20 seconds */
+
+ context->open = smbc_open_ctx;
+ context->creat = smbc_creat_ctx;
+ context->read = smbc_read_ctx;
+ context->write = smbc_write_ctx;
+ context->close = smbc_close_ctx;
+ context->unlink = smbc_unlink_ctx;
+ context->rename = smbc_rename_ctx;
+ context->lseek = smbc_lseek_ctx;
+ context->stat = smbc_stat_ctx;
+ context->fstat = smbc_fstat_ctx;
+ context->opendir = smbc_opendir_ctx;
+ context->closedir = smbc_closedir_ctx;
+ context->readdir = smbc_readdir_ctx;
+ context->getdents = smbc_getdents_ctx;
+ context->mkdir = smbc_mkdir_ctx;
+ context->rmdir = smbc_rmdir_ctx;
+ context->telldir = smbc_telldir_ctx;
+ context->lseekdir = smbc_lseekdir_ctx;
+ context->fstatdir = smbc_fstatdir_ctx;
+ context->chmod = smbc_chmod_ctx;
+ context->utimes = smbc_utimes_ctx;
+ context->setxattr = smbc_setxattr_ctx;
+ context->getxattr = smbc_getxattr_ctx;
+ context->removexattr = smbc_removexattr_ctx;
+ context->listxattr = smbc_listxattr_ctx;
+ context->open_print_job = smbc_open_print_job_ctx;
+ context->print_file = smbc_print_file_ctx;
+ context->list_print_jobs = smbc_list_print_jobs_ctx;
+ context->unlink_print_job = smbc_unlink_print_job_ctx;
+
+ context->callbacks.check_server_fn = smbc_check_server;
+ context->callbacks.remove_unused_server_fn = smbc_remove_unused_server;
+
+ smbc_default_cache_functions(context);
+
+ return context;
}
/*
@@ -2576,64 +3970,64 @@ SMBCCTX * smbc_new_context(void)
*/
int smbc_free_context(SMBCCTX * context, int shutdown_ctx)
{
- if (!context) {
- errno = EBADF;
- return 1;
- }
-
- if (shutdown_ctx) {
- SMBCFILE * f;
- DEBUG(1,("Performing aggressive shutdown.\n"));
-
- f = context->internal->_files;
- while (f) {
- context->close(context, f);
- f = f->next;
- }
- context->internal->_files = NULL;
-
- /* First try to remove the servers the nice way. */
- if (context->callbacks.purge_cached_fn(context)) {
- SMBCSRV * s;
- DEBUG(1, ("Could not purge all servers, Nice way shutdown failed.\n"));
- s = context->internal->_servers;
- while (s) {
- cli_shutdown(&s->cli);
- context->callbacks.remove_cached_srv_fn(context, s);
- SAFE_FREE(s);
- s = s->next;
- }
- context->internal->_servers = NULL;
- }
- }
- else {
- /* This is the polite way */
- if (context->callbacks.purge_cached_fn(context)) {
- DEBUG(1, ("Could not purge all servers, free_context failed.\n"));
- errno = EBUSY;
- return 1;
- }
- if (context->internal->_servers) {
- DEBUG(1, ("Active servers in context, free_context failed.\n"));
- errno = EBUSY;
- return 1;
- }
- if (context->internal->_files) {
- DEBUG(1, ("Active files in context, free_context failed.\n"));
- errno = EBUSY;
- return 1;
- }
- }
+ if (!context) {
+ errno = EBADF;
+ return 1;
+ }
+
+ if (shutdown_ctx) {
+ SMBCFILE * f;
+ DEBUG(1,("Performing aggressive shutdown.\n"));
+
+ f = context->internal->_files;
+ while (f) {
+ context->close(context, f);
+ f = f->next;
+ }
+ context->internal->_files = NULL;
+
+ /* First try to remove the servers the nice way. */
+ if (context->callbacks.purge_cached_fn(context)) {
+ SMBCSRV * s;
+ DEBUG(1, ("Could not purge all servers, Nice way shutdown failed.\n"));
+ s = context->internal->_servers;
+ while (s) {
+ cli_shutdown(&s->cli);
+ context->callbacks.remove_cached_srv_fn(context, s);
+ SAFE_FREE(s);
+ s = s->next;
+ }
+ context->internal->_servers = NULL;
+ }
+ }
+ else {
+ /* This is the polite way */
+ if (context->callbacks.purge_cached_fn(context)) {
+ DEBUG(1, ("Could not purge all servers, free_context failed.\n"));
+ errno = EBUSY;
+ return 1;
+ }
+ if (context->internal->_servers) {
+ DEBUG(1, ("Active servers in context, free_context failed.\n"));
+ errno = EBUSY;
+ return 1;
+ }
+ if (context->internal->_files) {
+ DEBUG(1, ("Active files in context, free_context failed.\n"));
+ errno = EBUSY;
+ return 1;
+ }
+ }
- /* Things we have to clean up */
- SAFE_FREE(context->workgroup);
- SAFE_FREE(context->netbios_name);
- SAFE_FREE(context->user);
-
- DEBUG(3, ("Context %p succesfully freed\n", context));
- SAFE_FREE(context->internal);
- SAFE_FREE(context);
- return 0;
+ /* Things we have to clean up */
+ SAFE_FREE(context->workgroup);
+ SAFE_FREE(context->netbios_name);
+ SAFE_FREE(context->user);
+
+ DEBUG(3, ("Context %p succesfully freed\n", context));
+ SAFE_FREE(context->internal);
+ SAFE_FREE(context);
+ return 0;
}
@@ -2646,128 +4040,128 @@ int smbc_free_context(SMBCCTX * context, int shutdown_ctx)
*/
SMBCCTX * smbc_init_context(SMBCCTX * context)
{
- pstring conf;
- int pid;
- char *user = NULL, *home = NULL;
+ pstring conf;
+ int pid;
+ char *user = NULL, *home = NULL;
- if (!context || !context->internal) {
- errno = EBADF;
- return NULL;
- }
-
- /* Do not initialise the same client twice */
- if (context->internal->_initialized) {
- return 0;
- }
-
- if (!context->callbacks.auth_fn || context->debug < 0 || context->debug > 100) {
-
- errno = EINVAL;
- return NULL;
+ if (!context || !context->internal) {
+ errno = EBADF;
+ return NULL;
+ }
- }
+ /* Do not initialise the same client twice */
+ if (context->internal->_initialized) {
+ return 0;
+ }
- if (!smbc_initialized) {
- /* Do some library wide intialisations the first time we get called */
+ if (!context->callbacks.auth_fn || context->debug < 0 || context->debug > 100) {
- /* Set this to what the user wants */
- DEBUGLEVEL = context->debug;
-
- setup_logging( "libsmbclient", True);
+ errno = EINVAL;
+ return NULL;
- /* Here we would open the smb.conf file if needed ... */
-
- home = getenv("HOME");
+ }
- slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home);
-
- load_interfaces(); /* Load the list of interfaces ... */
-
- in_client = True; /* FIXME, make a param */
+ if (!smbc_initialized) {
+ /* Do some library wide intialisations the first time we get called */
- if (!lp_load(conf, True, False, False)) {
+ /* Set this to what the user wants */
+ DEBUGLEVEL = context->debug;
+
+ setup_logging( "libsmbclient", True);
- /*
- * Well, if that failed, try the dyn_CONFIGFILE
- * Which points to the standard locn, and if that
- * fails, silently ignore it and use the internal
- * defaults ...
- */
-
- if (!lp_load(dyn_CONFIGFILE, True, False, False)) {
- DEBUG(5, ("Could not load either config file: %s or %s\n",
- conf, dyn_CONFIGFILE));
- }
- }
+ /* Here we would open the smb.conf file if needed ... */
+
+ home = getenv("HOME");
- reopen_logs(); /* Get logging working ... */
-
- /*
- * Block SIGPIPE (from lib/util_sock.c: write())
- * It is not needed and should not stop execution
- */
- BlockSignals(True, SIGPIPE);
-
- /* Done with one-time initialisation */
- smbc_initialized = 1;
+ slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home);
+
+ load_interfaces(); /* Load the list of interfaces ... */
+
+ in_client = True; /* FIXME, make a param */
+
+ if (!lp_load(conf, True, False, False)) {
+
+ /*
+ * Well, if that failed, try the dyn_CONFIGFILE
+ * Which points to the standard locn, and if that
+ * fails, silently ignore it and use the internal
+ * defaults ...
+ */
+
+ if (!lp_load(dyn_CONFIGFILE, True, False, False)) {
+ DEBUG(5, ("Could not load either config file: %s or %s\n",
+ conf, dyn_CONFIGFILE));
+ }
+ }
+
+ reopen_logs(); /* Get logging working ... */
+
+ /*
+ * Block SIGPIPE (from lib/util_sock.c: write())
+ * It is not needed and should not stop execution
+ */
+ BlockSignals(True, SIGPIPE);
+
+ /* Done with one-time initialisation */
+ smbc_initialized = 1;
- }
-
- if (!context->user) {
- /*
- * FIXME: Is this the best way to get the user info?
- */
- user = getenv("USER");
- /* walk around as "guest" if no username can be found */
- if (!user) context->user = strdup("guest");
- else context->user = strdup(user);
- }
+ }
+
+ if (!context->user) {
+ /*
+ * FIXME: Is this the best way to get the user info?
+ */
+ user = getenv("USER");
+ /* walk around as "guest" if no username can be found */
+ if (!user) context->user = strdup("guest");
+ else context->user = strdup(user);
+ }
- if (!context->netbios_name) {
- /*
- * We try to get our netbios name from the config. If that fails we fall
- * back on constructing our netbios name from our hostname etc
- */
- if (global_myname()) {
- context->netbios_name = strdup(global_myname());
- }
- else {
- /*
- * Hmmm, I want to get hostname as well, but I am too lazy for the moment
- */
- pid = sys_getpid();
- context->netbios_name = malloc(17);
- if (!context->netbios_name) {
- errno = ENOMEM;
- return NULL;
- }
- slprintf(context->netbios_name, 16, "smbc%s%d", context->user, pid);
- }
- }
+ if (!context->netbios_name) {
+ /*
+ * We try to get our netbios name from the config. If that fails we fall
+ * back on constructing our netbios name from our hostname etc
+ */
+ if (global_myname()) {
+ context->netbios_name = strdup(global_myname());
+ }
+ else {
+ /*
+ * Hmmm, I want to get hostname as well, but I am too lazy for the moment
+ */
+ pid = sys_getpid();
+ context->netbios_name = malloc(17);
+ if (!context->netbios_name) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ slprintf(context->netbios_name, 16, "smbc%s%d", context->user, pid);
+ }
+ }
- DEBUG(1, ("Using netbios name %s.\n", context->netbios_name));
+ DEBUG(1, ("Using netbios name %s.\n", context->netbios_name));
- if (!context->workgroup) {
- if (lp_workgroup()) {
- context->workgroup = strdup(lp_workgroup());
- }
- else {
- /* TODO: Think about a decent default workgroup */
- context->workgroup = strdup("samba");
- }
- }
+ if (!context->workgroup) {
+ if (lp_workgroup()) {
+ context->workgroup = strdup(lp_workgroup());
+ }
+ else {
+ /* TODO: Think about a decent default workgroup */
+ context->workgroup = strdup("samba");
+ }
+ }
- DEBUG(1, ("Using workgroup %s.\n", context->workgroup));
-
- /* shortest timeout is 1 second */
- if (context->timeout > 0 && context->timeout < 1000)
- context->timeout = 1000;
+ DEBUG(1, ("Using workgroup %s.\n", context->workgroup));
+
+ /* shortest timeout is 1 second */
+ if (context->timeout > 0 && context->timeout < 1000)
+ context->timeout = 1000;
- /*
- * FIXME: Should we check the function pointers here?
- */
+ /*
+ * FIXME: Should we check the function pointers here?
+ */
- context->internal->_initialized = 1;
-
- return context;
+ context->internal->_initialized = 1;
+
+ return context;
}
diff --git a/source/libsmb/namequery_dc.c b/source/libsmb/namequery_dc.c
index a596f00ddb9..df7f856cd7b 100644
--- a/source/libsmb/namequery_dc.c
+++ b/source/libsmb/namequery_dc.c
@@ -34,7 +34,7 @@ static BOOL ads_dc_name(const char *domain, struct in_addr *dc_ip, fstring srv_n
ADS_STRUCT *ads;
const char *realm = domain;
- if (strcasecmp(realm, lp_workgroup()) == 0)
+ if (strequal(realm, lp_workgroup()))
realm = lp_realm();
ads = ads_init(realm, domain, NULL);
diff --git a/source/libsmb/ntlmssp_parse.c b/source/libsmb/ntlmssp_parse.c
index 60cb4ab04ae..b136dacf5a2 100644
--- a/source/libsmb/ntlmssp_parse.c
+++ b/source/libsmb/ntlmssp_parse.c
@@ -226,7 +226,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob,
*ps = smb_xstrdup("");
} else {
/* make sure its in the right format - be strict */
- if (len1 != len2 || ptr + len1 > blob->length) {
+ if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) {
return False;
}
if (len1 & 1) {
@@ -255,7 +255,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob,
if (len1 == 0 && len2 == 0) {
*ps = smb_xstrdup("");
} else {
- if (len1 != len2 || ptr + len1 > blob->length) {
+ if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) {
return False;
}
@@ -280,7 +280,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob,
*b = data_blob(NULL, 0);
} else {
/* make sure its in the right format - be strict */
- if (len1 != len2 || ptr + len1 > blob->length) {
+ if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) {
return False;
}
*b = data_blob(blob->data + ptr, len1);
@@ -314,4 +314,3 @@ BOOL msrpc_parse(const DATA_BLOB *blob,
return True;
}
-
diff --git a/source/libsmb/ntlmssp_sign.c b/source/libsmb/ntlmssp_sign.c
index ff2f97c2e88..153c234d1f8 100644
--- a/source/libsmb/ntlmssp_sign.c
+++ b/source/libsmb/ntlmssp_sign.c
@@ -169,8 +169,8 @@ NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state,
NTSTATUS nt_status;
if (sig->length < 8) {
- DEBUG(0, ("NTLMSSP packet check failed due to short signature (%u bytes)!\n",
- sig->length));
+ DEBUG(0, ("NTLMSSP packet check failed due to short signature (%lu bytes)!\n",
+ (unsigned long)sig->length));
}
nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data,
diff --git a/source/libsmb/smb_signing.c b/source/libsmb/smb_signing.c
index 08ff655a3f8..91509f0fb81 100644
--- a/source/libsmb/smb_signing.c
+++ b/source/libsmb/smb_signing.c
@@ -25,7 +25,6 @@
struct outstanding_packet_lookup {
uint16 mid;
uint32 reply_seq_num;
- BOOL deferred_packet;
struct outstanding_packet_lookup *prev, *next;
};
@@ -44,7 +43,7 @@ struct smb_basic_signing_context {
};
static void store_sequence_for_reply(struct outstanding_packet_lookup **list,
- uint16 mid, uint32 reply_seq_num, BOOL deferred_pkt)
+ uint16 mid, uint32 reply_seq_num)
{
struct outstanding_packet_lookup *t;
struct outstanding_packet_lookup *tmp;
@@ -55,25 +54,20 @@ static void store_sequence_for_reply(struct outstanding_packet_lookup **list,
DLIST_ADD_END(*list, t, tmp);
t->mid = mid;
t->reply_seq_num = reply_seq_num;
- t->deferred_packet = deferred_pkt;
- DEBUG(10,("store_sequence_for_reply: stored %sseq = %u mid = %u\n",
- deferred_pkt ? "deferred " : "",
+ DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n",
(unsigned int)reply_seq_num, (unsigned int)mid ));
}
static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list,
- uint16 mid, uint32 *reply_seq_num, BOOL *def)
+ uint16 mid, uint32 *reply_seq_num)
{
struct outstanding_packet_lookup *t;
for (t = *list; t; t = t->next) {
if (t->mid == mid) {
*reply_seq_num = t->reply_seq_num;
- if (def)
- *def = t->deferred_packet;
- DEBUG(10,("get_sequence_for_reply: found %sseq = %u mid = %u\n",
- (t->deferred_packet) ? "deferred " : "",
+ DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n",
(unsigned int)t->reply_seq_num, (unsigned int)t->mid ));
DLIST_REMOVE(*list, t);
SAFE_FREE(t);
@@ -84,22 +78,6 @@ static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list,
}
/***********************************************************
- A reply is pending if there is a non-deferred packet on the queue.
-************************************************************/
-
-static BOOL is_reply_pending(struct outstanding_packet_lookup *list)
-{
- for (; list; list = list->next) {
- if (!list->deferred_packet) {
- DEBUG(10,("is_reply_pending: True.\n"));
- return True;
- }
- }
- DEBUG(10,("is_reply_pending: False.\n"));
- return False;
-}
-
-/***********************************************************
SMB signing - Common code before we set a new signing implementation
************************************************************/
@@ -329,8 +307,7 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
data->send_seq_num++;
store_sequence_for_reply(&data->outstanding_packet_list,
- SVAL(outbuf,smb_mid),
- data->send_seq_num, False);
+ SVAL(outbuf,smb_mid), data->send_seq_num);
data->send_seq_num++;
}
@@ -359,8 +336,7 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si)
if (data->trans_info) {
reply_seq_number = data->trans_info->reply_seq_num;
} else if (!get_sequence_for_reply(&data->outstanding_packet_list,
- SVAL(inbuf, smb_mid),
- &reply_seq_number, NULL)) {
+ SVAL(inbuf, smb_mid), &reply_seq_number)) {
DEBUG(1, ("client_check_incoming_message: failed to get sequence number %u for reply.\n",
(unsigned int) SVAL(inbuf, smb_mid) ));
return False;
@@ -385,8 +361,8 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si)
for (i = 0; i < 10; i++, reply_seq_number++) {
simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac);
if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) {
- DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches.\n",
- reply_seq_number ));
+ DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches. \
+We were expecting seq %u\n", reply_seq_number, saved_seq ));
break;
}
}
@@ -639,7 +615,7 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
mid = SVAL(outbuf, smb_mid);
/* See if this is a reply for a deferred packet. */
- get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number, &was_deferred_packet);
+ was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number);
if (data->trans_info && (data->trans_info->mid == mid)) {
/* This is a reply in a trans stream. Use the sequence
@@ -655,18 +631,21 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8);
/* cli->outbuf[smb_ss_field+2]=0;
- Uncomment this to test if the remote server actually verifies signatures...*/
+ Uncomment this to test if the remote client actually verifies signatures...*/
- if (!was_deferred_packet) {
- if (!data->trans_info) {
- /* Always increment if not in a trans stream. */
- data->send_seq_num++;
- } else if ((data->trans_info->send_seq_num == data->send_seq_num) || (data->trans_info->mid != mid)) {
- /* Increment if this is the first reply in a trans stream or a
- * packet that doesn't belong to this stream (different mid). */
- data->send_seq_num++;
- }
- }
+ /* Don't mess with the sequence number for a deferred packet. */
+ if (was_deferred_packet) {
+ return;
+ }
+
+ if (!data->trans_info) {
+ /* Always increment if not in a trans stream. */
+ data->send_seq_num++;
+ } else if ((data->trans_info->send_seq_num == data->send_seq_num) || (data->trans_info->mid != mid)) {
+ /* Increment if this is the first reply in a trans stream or a
+ * packet that doesn't belong to this stream (different mid). */
+ data->send_seq_num++;
+ }
}
/***********************************************************
@@ -721,8 +700,10 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si)
* isn't a reply pending we need to re-sync the sequence
* number.
*/
- if (is_oplock_break(inbuf) && !is_reply_pending(data->outstanding_packet_list))
+ if (is_oplock_break(inbuf)) {
+ DEBUG(10,("srv_check_incoming_message: oplock break at seq num %u\n", data->send_seq_num));
data->send_seq_num++;
+ }
}
saved_seq = reply_seq_number;
@@ -748,8 +729,8 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si)
for (i = 0; i < 10; i++, reply_seq_number++) {
simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac);
if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) {
- DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches.\n",
- reply_seq_number ));
+ DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches. \
+We were expecting seq %u\n", reply_seq_number, saved_seq ));
break;
}
}
@@ -820,7 +801,7 @@ void srv_calculate_sign_mac(char *outbuf)
Called by server to defer an outgoing packet.
************************************************************/
-void srv_defer_sign_response(uint16 mid, BOOL deferred_packet)
+void srv_defer_sign_response(uint16 mid)
{
struct smb_basic_signing_context *data;
@@ -833,7 +814,7 @@ void srv_defer_sign_response(uint16 mid, BOOL deferred_packet)
return;
store_sequence_for_reply(&data->outstanding_packet_list,
- mid, data->send_seq_num, deferred_packet);
+ mid, data->send_seq_num);
data->send_seq_num++;
}
@@ -857,7 +838,7 @@ void srv_cancel_sign_response(uint16 mid)
DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid ));
- while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq,NULL))
+ while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq))
;
}
diff --git a/source/msdfs/msdfs.c b/source/msdfs/msdfs.c
index f8a97effee4..ce29c506bbc 100644
--- a/source/msdfs/msdfs.c
+++ b/source/msdfs/msdfs.c
@@ -78,6 +78,7 @@ static BOOL parse_dfs_path(char* pathname, struct dfs_path* pdp)
/********************************************************
Fake up a connection struct for the VFS layer.
+ Note this CHANGES CWD !!!! JRA.
*********************************************************/
static BOOL create_conn_struct( connection_struct *conn, int snum, char *path)
@@ -99,6 +100,12 @@ static BOOL create_conn_struct( connection_struct *conn, int snum, char *path)
talloc_destroy( conn->mem_ctx );
return False;
}
+ if (vfs_ChDir(conn,conn->connectpath) != 0) {
+ DEBUG(3,("create_conn_struct: Can't ChDir to new conn path %s. Error was %s\n",
+ conn->connectpath, strerror(errno) ));
+ talloc_destroy( conn->mem_ctx );
+ return False;
+ }
return True;
}
@@ -161,7 +168,8 @@ static BOOL parse_symlink(char* buf,struct referral** preflist,
/**********************************************************************
Returns true if the unix path is a valid msdfs symlink
**********************************************************************/
-BOOL is_msdfs_link(connection_struct* conn, char* path,
+
+BOOL is_msdfs_link(connection_struct* conn, char * path,
struct referral** reflistp, int* refcnt,
SMB_STRUCT_STAT *sbufp)
{
@@ -172,8 +180,6 @@ BOOL is_msdfs_link(connection_struct* conn, char* path,
if (!path || !conn)
return False;
- strlower_m(path);
-
if (sbufp == NULL)
sbufp = &st;
@@ -212,17 +218,21 @@ they request referrals for dfs roots on a server.
consumedcntp: how much of the dfs path is being redirected. the client
should try the remaining path on the redirected server.
+
*****************************************************************/
-static BOOL resolve_dfs_path(char* dfspath, struct dfs_path* dp,
+
+static BOOL resolve_dfs_path(pstring dfspath, struct dfs_path* dp,
connection_struct* conn,
BOOL findfirst_flag,
struct referral** reflistpp, int* refcntp,
BOOL* self_referralp, int* consumedcntp)
{
- fstring localpath;
+ pstring localpath;
int consumed_level = 1;
char *p;
- fstring reqpath;
+ BOOL bad_path = False;
+ SMB_STRUCT_STAT sbuf;
+ pstring reqpath;
if (!dp || !conn) {
DEBUG(1,("resolve_dfs_path: NULL dfs_path* or NULL connection_struct*!\n"));
@@ -237,10 +247,13 @@ static BOOL resolve_dfs_path(char* dfspath, struct dfs_path* dp,
return False;
}
+ DEBUG(10,("resolve_dfs_path: Conn path = %s req_path = %s\n", conn->connectpath, dp->reqpath));
+
+ unix_convert(dp->reqpath,conn,0,&bad_path,&sbuf);
+ /* JRA... should we strlower the last component here.... ? */
+ pstrcpy(localpath, dp->reqpath);
+
/* check if need to redirect */
- fstrcpy(localpath, conn->connectpath);
- fstrcat(localpath, "/");
- fstrcat(localpath, dp->reqpath);
if (is_msdfs_link(conn, localpath, reflistpp, refcntp, NULL)) {
if (findfirst_flag) {
DEBUG(6,("resolve_dfs_path (FindFirst) No redirection "
@@ -256,13 +269,11 @@ static BOOL resolve_dfs_path(char* dfspath, struct dfs_path* dp,
}
/* redirect if any component in the path is a link */
- fstrcpy(reqpath, dp->reqpath);
+ pstrcpy(reqpath, dp->reqpath);
p = strrchr(reqpath, '/');
while (p) {
*p = '\0';
- fstrcpy(localpath, conn->connectpath);
- fstrcat(localpath, "/");
- fstrcat(localpath, reqpath);
+ pstrcpy(localpath, reqpath);
if (is_msdfs_link(conn, localpath, reflistpp, refcntp, NULL)) {
DEBUG(4, ("resolve_dfs_path: Redirecting %s because parent %s is dfs link\n", dfspath, localpath));
@@ -278,7 +289,8 @@ static BOOL resolve_dfs_path(char* dfspath, struct dfs_path* dp,
trim_char(buf, '\0', '\\');
for (; consumed_level; consumed_level--) {
q = strrchr(buf, '\\');
- if (q) *q = 0;
+ if (q)
+ *q = 0;
}
*consumedcntp = strlen(buf);
DEBUG(10, ("resolve_dfs_path: Path consumed: %s (%d)\n", buf, *consumedcntp));
@@ -297,7 +309,8 @@ static BOOL resolve_dfs_path(char* dfspath, struct dfs_path* dp,
Decides if a dfs pathname should be redirected or not.
If not, the pathname is converted to a tcon-relative local unix path
*****************************************************************/
-BOOL dfs_redirect(char* pathname, connection_struct* conn,
+
+BOOL dfs_redirect(pstring pathname, connection_struct* conn,
BOOL findfirst_flag)
{
struct dfs_path dp;
@@ -310,11 +323,11 @@ BOOL dfs_redirect(char* pathname, connection_struct* conn,
/* if dfs pathname for a non-dfs share, convert to tcon-relative
path and return false */
if (!lp_msdfs_root(SNUM(conn))) {
- fstrcpy(pathname, dp.reqpath);
+ pstrcpy(pathname, dp.reqpath);
return False;
}
- if (strcasecmp(dp.servicename, lp_servicename(SNUM(conn)) ) != 0)
+ if (!strequal(dp.servicename, lp_servicename(SNUM(conn)) ))
return False;
if (resolve_dfs_path(pathname, &dp, conn, findfirst_flag,
@@ -325,7 +338,7 @@ BOOL dfs_redirect(char* pathname, connection_struct* conn,
DEBUG(3,("dfs_redirect: Not redirecting %s.\n", pathname));
/* Form non-dfs tcon-relative path */
- fstrcpy(pathname, dp.reqpath);
+ pstrcpy(pathname, dp.reqpath);
DEBUG(3,("dfs_redirect: Path converted to non-dfs path %s\n",
pathname));
return False;
@@ -338,6 +351,7 @@ BOOL dfs_redirect(char* pathname, connection_struct* conn,
Gets valid referrals for a dfs path and fills up the
junction_map structure
**********************************************************************/
+
BOOL get_referred_path(char *pathname, struct junction_map* jn,
int* consumedcntp, BOOL* self_referralp)
{
@@ -362,15 +376,13 @@ BOOL get_referred_path(char *pathname, struct junction_map* jn,
parse_dfs_path(pathname, &dp);
/* Verify hostname in path */
- if (local_machine && (strcasecmp(local_machine, dp.hostname) != 0)) {
-
- /* Hostname mismatch, check if one of our IP addresses */
- if (!ismyip(*interpret_addr2(dp.hostname))) {
-
- DEBUG(3, ("get_referred_path: Invalid hostname %s in path %s\n",
- dp.hostname, pathname));
- return False;
- }
+ if (local_machine && (!strequal(local_machine, dp.hostname))) {
+ /* Hostname mismatch, check if one of our IP addresses */
+ if (!ismyip(*interpret_addr2(dp.hostname))) {
+ DEBUG(3, ("get_referred_path: Invalid hostname %s in path %s\n",
+ dp.hostname, pathname));
+ return False;
+ }
}
pstrcpy(jn->service_name, dp.servicename);
@@ -386,7 +398,7 @@ BOOL get_referred_path(char *pathname, struct junction_map* jn,
pstrcpy(conn_path, lp_pathname(snum));
if (!create_conn_struct(conn, snum, conn_path))
return False;
-
+
if (!lp_msdfs_root(SNUM(conn))) {
DEBUG(3,("get_referred_path: .%s. in dfs path %s is not a dfs root.\n",
dp.servicename, pathname));
@@ -626,7 +638,7 @@ static int setup_ver3_dfs_referral(char* pathname, char** ppdata,
* Set up the Dfs referral for the dfs pathname
******************************************************************/
-int setup_dfs_referral(char* pathname, int max_referral_level, char** ppdata)
+int setup_dfs_referral(connection_struct *orig_conn, char *pathname, int max_referral_level, char** ppdata)
{
struct junction_map junction;
int consumedcnt;
@@ -648,12 +660,14 @@ int setup_dfs_referral(char* pathname, int max_referral_level, char** ppdata)
pathnamep++;
pstrcpy(buf, pathnamep);
- if (!get_referred_path(buf, &junction, &consumedcnt,
- &self_referral))
+ /* The following call can change cwd. */
+ if (!get_referred_path(buf, &junction, &consumedcnt, &self_referral)) {
+ vfs_ChDir(orig_conn,orig_conn->connectpath);
return -1;
+ }
+ vfs_ChDir(orig_conn,orig_conn->connectpath);
- if (!self_referral)
- {
+ if (!self_referral) {
pathnamep[consumedcnt] = '\0';
if( DEBUGLVL( 3 ) ) {
@@ -672,24 +686,18 @@ int setup_dfs_referral(char* pathname, int max_referral_level, char** ppdata)
switch(max_referral_level) {
case 2:
- {
reply_size = setup_ver2_dfs_referral(pathnamep, ppdata, &junction,
consumedcnt, self_referral);
SAFE_FREE(junction.referral_list);
break;
- }
case 3:
- {
reply_size = setup_ver3_dfs_referral(pathnamep, ppdata, &junction,
consumedcnt, self_referral);
SAFE_FREE(junction.referral_list);
break;
- }
default:
- {
DEBUG(0,("setup_dfs_referral: Invalid dfs referral version: %d\n", max_referral_level));
return -1;
- }
}
DEBUG(10,("DFS Referral pdata:\n"));
@@ -711,7 +719,7 @@ BOOL create_junction(char* pathname, struct junction_map* jn)
parse_dfs_path(pathname,&dp);
/* check if path is dfs : validate first token */
- if (local_machine && (strcasecmp(local_machine,dp.hostname)!=0)) {
+ if (local_machine && (!strequal(local_machine,dp.hostname))) {
/* Hostname mismatch, check if one of our IP addresses */
if (!ismyip(*interpret_addr2(dp.hostname))) {
@@ -752,7 +760,6 @@ static BOOL junction_to_local_path(struct junction_map* jn, char* path,
safe_strcpy(path, lp_pathname(snum), max_pathlen-1);
safe_strcat(path, "/", max_pathlen-1);
- strlower_m(jn->volume_name);
safe_strcat(path, jn->volume_name, max_pathlen-1);
pstrcpy(conn_path, lp_pathname(snum));
@@ -885,18 +892,12 @@ static BOOL form_junctions(int snum, struct junction_map* jn, int* jn_count)
cnt++;
/* Now enumerate all dfs links */
- dirp = SMB_VFS_OPENDIR(conn, connect_path);
+ dirp = SMB_VFS_OPENDIR(conn, ".");
if(!dirp)
goto out;
while((dname = vfs_readdirname(conn, dirp)) != NULL) {
- pstring pathreal;
-
- pstrcpy(pathreal, connect_path);
- pstrcat(pathreal, "/");
- pstrcat(pathreal, dname);
-
- if (is_msdfs_link(conn, pathreal, &(jn[cnt].referral_list),
+ if (is_msdfs_link(conn, dname, &(jn[cnt].referral_list),
&(jn[cnt].referral_count), NULL)) {
pstrcpy(jn[cnt].service_name, service_name);
pstrcpy(jn[cnt].volume_name, dname);
@@ -925,4 +926,3 @@ int enum_msdfs_links(struct junction_map* jn)
}
return jn_count;
}
-
diff --git a/source/nmbd/nmbd.c b/source/nmbd/nmbd.c
index 25ba07c8a7a..36aa2e24856 100644
--- a/source/nmbd/nmbd.c
+++ b/source/nmbd/nmbd.c
@@ -570,8 +570,8 @@ static BOOL open_sockets(BOOL isdaemon, int port)
if ( isdaemon )
ClientNMB = open_socket_in(SOCK_DGRAM, port,
- interpret_addr(lp_socket_address()),
- 0,True);
+ 0, interpret_addr(lp_socket_address()),
+ True);
else
ClientNMB = 0;
diff --git a/source/nmbd/nmbd_elections.c b/source/nmbd/nmbd_elections.c
index fabc0eddca2..19b00f1f4d2 100644
--- a/source/nmbd/nmbd_elections.c
+++ b/source/nmbd/nmbd_elections.c
@@ -247,7 +247,7 @@ static BOOL win_election(struct work_record *work, int version,
if (timeup < mytimeup)
return(True);
- if (strcasecmp(global_myname(), server_name) > 0)
+ if (StrCaseCmp(global_myname(), server_name) > 0)
return(False);
return(True);
diff --git a/source/nmbd/nmbd_packets.c b/source/nmbd/nmbd_packets.c
index 72eb1b50199..c318689fd19 100644
--- a/source/nmbd/nmbd_packets.c
+++ b/source/nmbd/nmbd_packets.c
@@ -1835,7 +1835,7 @@ BOOL send_mailslot(BOOL unique, const char *mailslot,char *buf, size_t len,
/* Setup the smb part. */
ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
memcpy(tmp,ptr,4);
- set_message(ptr,17,23 + len,True);
+ set_message(ptr,17,strlen(mailslot) + 1 + len,True);
memcpy(ptr,tmp,4);
SCVAL(ptr,smb_com,SMBtrans);
diff --git a/source/nmbd/nmbd_processlogon.c b/source/nmbd/nmbd_processlogon.c
index 2a6a6b66d1f..3b021978056 100644
--- a/source/nmbd/nmbd_processlogon.c
+++ b/source/nmbd/nmbd_processlogon.c
@@ -255,7 +255,7 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
q = ALIGN4(q, buf);
}
- DEBUG(3,("process_logon_packet: len = %d PTR_DIFF(q, buf) = %d\n", len, PTR_DIFF(q, buf) ));
+ DEBUG(3,("process_logon_packet: len = %d PTR_DIFF(q, buf) = %ld\n", len, (unsigned long)PTR_DIFF(q, buf) ));
if (len - PTR_DIFF(q, buf) > 8) {
/* with NT5 clients we can sometimes
@@ -491,6 +491,8 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
/* Domain SID */
+#if 0
+ /* We must range check this. */
q += IVAL(q, 0) + 4; /* 4 byte length plus data */
q += 2; /* Alignment? */
@@ -500,6 +502,7 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
q += 4; /* NT version (0x1) */
q += 2; /* LMNT token (0xff) */
q += 2; /* LM20 token (0xff) */
+#endif
SAFE_FREE(db_info); /* Not sure whether we need to do anything useful with these */
diff --git a/source/nsswitch/wb_common.c b/source/nsswitch/wb_common.c
index 79553e9e4fa..40221b69feb 100644
--- a/source/nsswitch/wb_common.c
+++ b/source/nsswitch/wb_common.c
@@ -81,7 +81,7 @@ static int make_nonstd_fd_internals(int fd, int limit /* Recursion limiter */)
if ((new_fd = fcntl(fd, F_DUPFD, 3)) == -1) {
return -1;
}
- /* Parinoia */
+ /* Paranoia */
if (new_fd < 3) {
close(new_fd);
return -1;
@@ -472,17 +472,23 @@ NSS_STATUS winbindd_request(int req_type,
}
/*************************************************************************
- A couple of simple jfunctions to disable winbindd lookups and re-
+ A couple of simple functions to disable winbindd lookups and re-
enable them
************************************************************************/
+/* Use putenv() instead of setenv() in these functions as not all
+ environments have the latter. */
+
BOOL winbind_off( void )
{
- return (setenv( WINBINDD_DONT_ENV, "1", 1 ) != -1);
+ static char *s = WINBINDD_DONT_ENV "=1";
+
+ return putenv(s) != -1;
}
BOOL winbind_on( void )
{
- return (setenv( WINBINDD_DONT_ENV, "0", 1 ) != -1);
-}
+ static char *s = WINBINDD_DONT_ENV "=0";
+ return putenv(s) != -1;
+}
diff --git a/source/nsswitch/wbinfo.c b/source/nsswitch/wbinfo.c
index 0018e99f60f..04233bb85cb 100644
--- a/source/nsswitch/wbinfo.c
+++ b/source/nsswitch/wbinfo.c
@@ -789,8 +789,13 @@ static BOOL wbinfo_set_auth_user(char *username)
if (password) {
*password = 0;
password++;
- } else
- password = "";
+ } else {
+ char *thepass = getpass("Password: ");
+ if (thepass) {
+ password = thepass;
+ } else
+ password = "";
+ }
/* Store or remove DOMAIN\username%password in secrets.tdb */
diff --git a/source/nsswitch/winbind_nss_aix.c b/source/nsswitch/winbind_nss_aix.c
index 8b5bc7a50ca..3d2f01b93c6 100644
--- a/source/nsswitch/winbind_nss_aix.c
+++ b/source/nsswitch/winbind_nss_aix.c
@@ -6,6 +6,7 @@
Copyright (C) Tim Potter 2003
Copyright (C) Steve Roylance 2003
+ Copyright (C) Andrew Tridgell 2003
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -23,182 +24,188 @@
Boston, MA 02111-1307, USA.
*/
+/*
+ see
+ http://publib16.boulder.ibm.com/doc_link/en_US/a_doc_lib/aixprggd/kernextc/sec_load_mod.htm
+ for information in the interface that this module implements
+*/
+
#include <stdlib.h>
#include <string.h>
#include <usersec.h>
#include <errno.h>
+#include <stdarg.h>
#include "winbind_client.h"
-#define MAX_GETPWENT_USERS 250
-#define MAX_GETGRENT_USERS 250
-
-static struct passwd *fill_pwent(struct winbindd_pw *pw)
-{
- struct passwd *result;
-
- if (!(result = malloc(sizeof(struct passwd))))
- goto out;
-
- ZERO_STRUCTP(result);
-
- /* User name */
+/*
+ the documentation doesn't say so, but experimentation shows that all
+ of the functions need to return static data, and the area can be
+ freed only when the same function is called again, or the close
+ method is called on the module. Note that this matches the standard
+ behaviour of functions like getpwnam().
+
+ The most puzzling thing about this AIX interface is that it seems to
+ offer no way of providing a user or group enumeration method. You
+ can find out any amount of detail about a user or group once you
+ know the name, but you can't obtain a list of those names. If anyone
+ does find out how to do this then please let me know (yes, I should
+ be able to find out as I work for IBM, and this is an IBM interface,
+ but finding the right person to ask is a mammoth task!)
+
+ tridge@samba.org October 2003
+*/
- if ((result->pw_name = malloc(strlen(pw->pw_name) + 1)) == NULL)
- goto out;
-
- strcpy(result->pw_name, pw->pw_name);
- /* Password */
+/*
+ each function uses one of the following lists of memory, declared
+ static in each backend method. This allows the function to destroy
+ the memory when that backend is called next time
+*/
+struct mem_list {
+ struct mem_list *next, *prev;
+ void *p;
+};
- if ((result->pw_passwd = malloc(strlen(pw->pw_passwd) + 1)) == NULL)
- goto out;
-
- strcpy(result->pw_passwd, pw->pw_passwd);
-
- /* [ug]id */
- result->pw_uid = pw->pw_uid;
- result->pw_gid = pw->pw_gid;
+/* allocate some memory on a mem_list */
+static void *list_alloc(struct mem_list **list, size_t size)
+{
+ struct mem_list *m;
+ m = malloc(sizeof(*m));
+ if (!m) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ m->p = malloc(size);
+ if (!m->p) {
+ errno = ENOMEM;
+ free(m);
+ return NULL;
+ }
+ m->next = *list;
+ m->prev = NULL;
+ if (*list) {
+ (*list)->prev = m;
+ }
+ (*list) = m;
+ return m->p;
+}
- /* GECOS */
+/* duplicate a string using list_alloc() */
+static char *list_strdup(struct mem_list **list, const char *s)
+{
+ char *ret = list_alloc(list, strlen(s)+1);
+ if (!ret) return NULL;
+ strcpy(ret, s);
+ return ret;
+}
- if ((result->pw_gecos = malloc(strlen(pw->pw_gecos) + 1)) == NULL)
- goto out;
+/* destroy a mem_list */
+static void list_destory(struct mem_list **list)
+{
+ struct mem_list *m, *next;
+ for (m=*list; m; m=next) {
+ next = m->next;
+ free(m->p);
+ free(m);
+ }
+ (*list) = NULL;
+}
- strcpy(result->pw_gecos, pw->pw_gecos);
-
- /* Home directory */
-
- if ((result->pw_dir = malloc(strlen(pw->pw_dir) + 1)) == NULL)
- goto out;
- strcpy(result->pw_dir, pw->pw_dir);
+#define HANDLE_ERRORS(ret) do { \
+ if ((ret) == NSS_STATUS_NOTFOUND) { \
+ errno = ENOENT; \
+ return NULL; \
+ } else if ((ret) != NSS_STATUS_SUCCESS) { \
+ errno = EIO; \
+ return NULL; \
+ } \
+} while (0)
- /* Logon shell */
-
- if ((result->pw_shell = malloc(strlen(pw->pw_shell) + 1)) == NULL)
- goto out;
-
- strcpy(result->pw_shell, pw->pw_shell);
-
- return result;
-
- /* A memory allocation failed, undo succesfull allocations and
- return NULL */
-
-out:
- errno = ENOMEM;
- SAFE_FREE(result->pw_dir);
- SAFE_FREE(result->pw_gecos);
- SAFE_FREE(result->pw_passwd);
- SAFE_FREE(result->pw_name);
- SAFE_FREE(result);
-
- return NULL;
-}
-
-static BOOL next_token(char **ptr,char *buff,char *sep, size_t bufsize)
+/*
+ fill a struct passwd from a winbindd_pw struct, using memory from a mem_list
+*/
+static struct passwd *fill_pwent(struct mem_list **list, struct winbindd_pw *pw)
{
- char *s;
- BOOL quoted;
- size_t len=1;
+ struct passwd *result;
- if (!ptr) return(False);
+ if (!(result = list_alloc(list, sizeof(struct passwd)))) {
+ return NULL;
+ }
- s = *ptr;
+ ZERO_STRUCTP(result);
- /* default to simple separators */
- if (!sep) sep = " \t\n\r";
+ result->pw_uid = pw->pw_uid;
+ result->pw_gid = pw->pw_gid;
- /* find the first non sep char */
- while (*s && strchr(sep,*s)) s++;
-
- /* nothing left? */
- if (! *s) return(False);
-
- /* copy over the token */
- for (quoted = False; len < bufsize && *s && (quoted || !strchr(sep,*s)); s++) {
- if (*s == '\"') {
- quoted = !quoted;
- } else {
- len++;
- *buff++ = *s;
- }
+ /* strings */
+ if ((result->pw_name = list_strdup(list, pw->pw_name)) == NULL ||
+ (result->pw_passwd = list_strdup(list, pw->pw_passwd)) == NULL ||
+ (result->pw_gecos = list_strdup(list, pw->pw_gecos)) == NULL ||
+ (result->pw_dir = list_strdup(list, pw->pw_dir)) == NULL ||
+ (result->pw_shell = list_strdup(list, pw->pw_shell)) == NULL) {
+ return NULL;
}
- *ptr = (*s) ? s+1 : s;
- *buff = 0;
-
- return(True);
+ return result;
}
-static struct group *fill_grent(struct winbindd_gr *gr, char *gr_mem)
+
+/*
+ fill a struct group from a winbindd_pw struct, using memory from a mem_list
+*/
+static struct group *fill_grent(struct mem_list **list, struct winbindd_gr *gr, char *gr_mem)
{
- fstring name;
int i;
char *tst;
struct group *result;
-
- if (!(result = malloc(sizeof(struct group))))
- goto out;
+ char *name, *p;
- ZERO_STRUCTP(result);
-
- /* Group name */
-
- if ((result->gr_name = malloc(strlen(gr->gr_name) + 1)) == NULL)
- goto out;
-
- strcpy(result->gr_name, gr->gr_name);
-
- /* Password */
-
- if ((result->gr_passwd = malloc(strlen(gr->gr_passwd) + 1)) == NULL)
- goto out;
-
- strcpy(result->gr_passwd, gr->gr_passwd);
+ if (!(result = list_alloc(list, sizeof(struct group)))) {
+ return NULL;
+ }
- /* gid */
+ ZERO_STRUCTP(result);
result->gr_gid = gr->gr_gid;
- /* Group membership */
+ /* Group name */
+ if ((result->gr_name = list_strdup(list, gr->gr_name)) == NULL ||
+ (result->gr_passwd = list_strdup(list, gr->gr_passwd)) == NULL) {
+ return NULL;
+ }
+ /* Group membership */
if ((gr->num_gr_mem < 0) || !gr_mem) {
gr->num_gr_mem = 0;
}
if (gr->num_gr_mem == 0) {
-
- /* Group is empty */
-
- *(result->gr_mem) = NULL;
+ /* Group is empty */
return result;
}
- if ((tst = malloc(((gr->num_gr_mem + 1) * sizeof(char *)))) == NULL)
- goto out;
+ tst = list_alloc(list, (gr->num_gr_mem + 1) * sizeof(char *));
+ if (!tst) {
+ return NULL;
+ }
result->gr_mem = (char **)tst;
/* Start looking at extra data */
-
- i = 0;
-
- while(next_token((char **)&gr_mem, name, ",", sizeof(fstring))) {
-
- /* Allocate space for member */
-
- if (((result->gr_mem)[i] =
- malloc(strlen(name) + 1)) == NULL) {
- for ( i -= 1; i >= 0; i--)
- SAFE_FREE((result->gr_mem)[i]);
- goto out;
-
- }
-
- strcpy((result->gr_mem)[i], name);
+ i=0;
+ for (name = strtok_r(gr_mem, ",", &p);
+ name;
+ name = strtok_r(NULL, ",", &p)) {
+ if (i >= gr->num_gr_mem) {
+ return NULL;
+ }
+ (result->gr_mem)[i] = list_strdup(list, name);
+ if ((result->gr_mem)[i] == NULL) {
+ return NULL;
+ }
i++;
}
@@ -206,140 +213,123 @@ static struct group *fill_grent(struct winbindd_gr *gr, char *gr_mem)
(result->gr_mem)[i] = NULL;
return result;
-
- /* A memory allocation failed, undo succesfull allocations and
- return NULL */
-
-out:
- errno = ENOMEM;
- SAFE_FREE(tst);
- SAFE_FREE(result->gr_passwd);
- SAFE_FREE(result->gr_name);
- SAFE_FREE(result);
-
- return NULL;
}
-static struct group *
-wb_aix_getgrgid (gid_t gid)
+/* take a group id and return a filled struct group */
+static struct group *wb_aix_getgrgid(gid_t gid)
{
-/* take a group id and return a filled struct group */
-
+ static struct mem_list *list;
struct winbindd_response response;
struct winbindd_request request;
+ struct group *grp;
NSS_STATUS ret;
+ list_destory(&list);
+
ZERO_STRUCT(response);
ZERO_STRUCT(request);
request.data.gid = gid;
ret = winbindd_request(WINBINDD_GETGRGID, &request, &response);
-
- if (ret == NSS_STATUS_SUCCESS) {
- return fill_grent(&response.data.gr, response.extra_data);
- } else if (ret == NSS_STATUS_NOTFOUND) {
- errno = ENOENT;
- } else {
- errno = EIO;
- }
-
- return NULL;
+
+ HANDLE_ERRORS(ret);
+
+ grp = fill_grent(&list, &response.data.gr, response.extra_data);
+
+ free_response(&response);
+
+ return grp;
}
-static struct group *
-wb_aix_getgrnam (const char *name)
-{
/* take a group name and return a filled struct group */
-
+static struct group *wb_aix_getgrnam(const char *name)
+{
+ static struct mem_list *list;
struct winbindd_response response;
struct winbindd_request request;
NSS_STATUS ret;
-
+ struct group *grp;
+
+ list_destory(&list);
+
ZERO_STRUCT(response);
ZERO_STRUCT(request);
- strncpy(request.data.groupname, name,
- sizeof(request.data.groupname));
- request.data.groupname
- [sizeof(request.data.groupname) - 1] = '\0';
+ if (strlen(name)+1 > sizeof(request.data.groupname)) {
+ errno = EINVAL;
+ return NULL;
+ }
+ strcpy(request.data.groupname, name);
ret = winbindd_request(WINBINDD_GETGRNAM, &request, &response);
- if (ret == NSS_STATUS_SUCCESS) {
- return fill_grent(&response.data.gr, response.extra_data);
- } else if (ret == NSS_STATUS_NOTFOUND) {
- errno = ENOENT;
- } else {
- errno = EIO;
- }
-
- return NULL;
+ HANDLE_ERRORS(ret);
+
+ grp = fill_grent(&list, &response.data.gr, response.extra_data);
+
+ free_response(&response);
+
+ return grp;
}
-static char *
-wb_aix_getgrset (const char *user)
+
+/* take a username and return a string containing a comma-separated
+ list of group id numbers to which the user belongs */
+static char *wb_aix_getgrset(char *user)
{
-/* take a username and return a string containing a comma-separated list of
- group id numbers to which the user belongs */
-
+ static struct mem_list *list;
struct winbindd_response response;
struct winbindd_request request;
NSS_STATUS ret;
+ int i, idx;
+ char *tmpbuf;
+ int num_gids;
+ gid_t *gid_list;
- strncpy(request.data.username, user,
- sizeof(request.data.username) - 1);
- request.data.username
- [sizeof(request.data.username) - 1] = '\0';
+ list_destory(&list);
+
+ if (strlen(user)+1 > sizeof(request.data.username)) {
+ errno = EINVAL;
+ return NULL;
+ }
+ strcpy(request.data.username, user);
ret = winbindd_request(WINBINDD_GETGROUPS, &request, &response);
- if (ret == NSS_STATUS_SUCCESS ) {
- int i, idx = 0;
- char *tmpbuf, *result;
-
- int num_gids = response.data.num_entries;
- gid_t *gid_list = (gid_t *)response.extra_data;
+ HANDLE_ERRORS(ret);
+
+ num_gids = response.data.num_entries;
+ gid_list = (gid_t *)response.extra_data;
- /* allocate a space large enough to contruct the string */
- if (!(tmpbuf = malloc(num_gids*12))) {
- errno = ENOMEM;
- return NULL;
- }
- idx += sprintf(tmpbuf, "%d", gid_list[0]);
- for (i = 1; i < num_gids; i++) {
- tmpbuf[idx++] = ',';
- idx += sprintf(tmpbuf+idx, "%d", gid_list[i]);
- }
- tmpbuf[idx] = '\0';
- if (!(result = malloc(idx+1))) {
- /* allocate a string the right size to return, but
- if that fails may as well return our working buffer
- because it contains the same thing */
- return tmpbuf;
- }
- strcpy(result, tmpbuf);
- SAFE_FREE(tmpbuf);
- return result;
- } else if (ret == NSS_STATUS_NOTFOUND) {
- errno = ENOENT;
- } else {
- errno = EIO;
+ /* allocate a space large enough to contruct the string */
+ tmpbuf = list_alloc(&list, num_gids*12);
+ if (!tmpbuf) {
+ return NULL;
}
-
- return NULL;
+
+ for (idx=i=0; i < num_gids-1; i++) {
+ idx += sprintf(tmpbuf+idx, "%u,", gid_list[i]);
+ }
+ idx += sprintf(tmpbuf+idx, "%u", gid_list[i]);
+
+ free_response(&response);
+
+ return tmpbuf;
}
-static struct passwd *
-wb_aix_getpwuid (uid_t uid)
+
+/* take a uid and return a filled struct passwd */
+static struct passwd *wb_aix_getpwuid(uid_t uid)
{
-/* take a uid and return a filled struct passwd */
-
+ static struct mem_list *list;
struct winbindd_response response;
struct winbindd_request request;
NSS_STATUS ret;
+
+ list_destory(&list);
ZERO_STRUCT(response);
ZERO_STRUCT(request);
@@ -347,55 +337,46 @@ wb_aix_getpwuid (uid_t uid)
request.data.uid = uid;
ret = winbindd_request(WINBINDD_GETPWUID, &request, &response);
-
- if (ret == NSS_STATUS_SUCCESS) {
- return fill_pwent(&response.data.pw);
- } else if (ret == NSS_STATUS_NOTFOUND ) {
- errno = ENOENT;
- } else {
- errno = EIO;
- }
-
- return NULL;
+
+ HANDLE_ERRORS(ret);
+
+ return fill_pwent(&list, &response.data.pw);
}
-static struct passwd *
-wb_aix_getpwnam (const char *name)
-{
-/* take a username and return a filled struct passwd */
+/* take a username and return a filled struct passwd */
+static struct passwd *wb_aix_getpwnam(const char *name)
+{
+ static struct mem_list *list;
struct winbindd_response response;
struct winbindd_request request;
NSS_STATUS ret;
+
+ list_destory(&list);
ZERO_STRUCT(response);
ZERO_STRUCT(request);
- strncpy(request.data.username, name,
- sizeof(request.data.username) - 1);
- request.data.username
- [sizeof(request.data.username) - 1] = '\0';
+ if (strlen(name)+1 > sizeof(request.data.username)) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ strcpy(request.data.username, name);
ret = winbindd_request(WINBINDD_GETPWNAM, &request, &response);
+
+ HANDLE_ERRORS(ret);
- if (ret == NSS_STATUS_SUCCESS ) {
- return fill_pwent(&response.data.pw);
- } else if (ret == NSS_STATUS_NOTFOUND) {
- errno = ENOENT;
- } else {
- errno = EIO;
- }
-
- return NULL;
+ return fill_pwent(&list, &response.data.pw);
}
-int
-wb_aix_init (struct secmethod_table *methods)
+int wb_aix_init(struct secmethod_table *methods)
{
- memset(methods, 0, sizeof(*methods));
+ ZERO_STRUCTP(methods);
/* identification methods, this is the minimum requried for a
- working module */
+ working module */
methods->method_getgrgid = wb_aix_getgrgid;
methods->method_getgrnam = wb_aix_getgrnam;
@@ -405,3 +386,4 @@ wb_aix_init (struct secmethod_table *methods)
return AUTH_SUCCESS;
}
+
diff --git a/source/nsswitch/winbind_nss_hpux.h b/source/nsswitch/winbind_nss_hpux.h
index 1f2bade9721..d2a5057bf51 100644
--- a/source/nsswitch/winbind_nss_hpux.h
+++ b/source/nsswitch/winbind_nss_hpux.h
@@ -25,10 +25,6 @@
#include <nsswitch.h>
-#ifndef _HAVE_TYPEDEF_NSS_STATUS
-#define _HAVE_TYPEDEF_NSS_STATUS
-typedef nss_status_t NSS_STATUS;
-
#define NSS_STATUS_SUCCESS NSS_SUCCESS
#define NSS_STATUS_NOTFOUND NSS_NOTFOUND
#define NSS_STATUS_UNAVAIL NSS_UNAVAIL
@@ -48,6 +44,8 @@ typedef enum {
NSS_TRYAGAIN
} nss_status_t;
+typedef nss_status_t NSS_STATUS;
+
struct nss_backend;
typedef nss_status_t (*nss_backend_op_t)(struct nss_backend *, void *args);
diff --git a/source/nsswitch/winbindd.c b/source/nsswitch/winbindd.c
index 6a0056f917e..4b47ac13a2f 100644
--- a/source/nsswitch/winbindd.c
+++ b/source/nsswitch/winbindd.c
@@ -452,7 +452,7 @@ void winbind_client_read(struct winbindd_cli_state *state)
(char *)&state->request,
sizeof(state->request) - state->read_buf_len);
- DEBUG(10,("client_read: read %d bytes. Need %d more for a full request.\n", n, sizeof(state->request) - n - state->read_buf_len ));
+ DEBUG(10,("client_read: read %d bytes. Need %ld more for a full request.\n", n, (unsigned long)(sizeof(state->request) - n - state->read_buf_len) ));
/* Read failed, kill client */
@@ -479,6 +479,13 @@ static void client_write(struct winbindd_cli_state *state)
int num_written;
/* Write some data */
+ /*
+ * The fancy calculation of data below allows us to handle the
+ * case where write (sys_write) does not write all the data we
+ * gave it. In that case, we will come back through here again
+ * because of the loop above us, and we want to pick up where
+ * we left off.
+ */
if (!state->write_extra_data) {
@@ -712,8 +719,8 @@ static void process_loop(void)
if (state->read_buf_len >= sizeof(uint32)
&& *(uint32 *) &state->request != sizeof(state->request)) {
- DEBUG(0,("process_loop: Invalid request size from pid %lu: %d bytes sent, should be %d\n",
- (unsigned long)state->request.pid, *(uint32 *) &state->request, sizeof(state->request)));
+ DEBUG(0,("process_loop: Invalid request size from pid %lu: %d bytes sent, should be %ld\n",
+ (unsigned long)state->request.pid, *(uint32 *) &state->request, (unsigned long)sizeof(state->request)));
remove_client(state);
break;
diff --git a/source/nsswitch/winbindd_ads.c b/source/nsswitch/winbindd_ads.c
index ef3f0f8fc20..5d0f924d8f8 100644
--- a/source/nsswitch/winbindd_ads.c
+++ b/source/nsswitch/winbindd_ads.c
@@ -364,7 +364,7 @@ static BOOL dn_lookup(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
return False;
}
- asprintf(&ldap_exp, "(distinguishedName=%s)", dn);
+ asprintf(&ldap_exp, "(distinguishedName=%s)", escaped_dn);
rc = ads_search_retry(ads, &res, ldap_exp, attrs);
SAFE_FREE(ldap_exp);
SAFE_FREE(escaped_dn);
diff --git a/source/nsswitch/winbindd_rpc.c b/source/nsswitch/winbindd_rpc.c
index 8bd2c665113..ba14a51d240 100644
--- a/source/nsswitch/winbindd_rpc.c
+++ b/source/nsswitch/winbindd_rpc.c
@@ -336,7 +336,7 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain,
DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
/* Paranoia */
- if (strcasecmp(domain->name, domains[0]) != 0) {
+ if (!strequal(domain->name, domains[0])) {
DEBUG(1, ("domain name from domain param and PDC lookup return differ! (%s vs %s)\n", domain->name, domains[0]));
return NT_STATUS_UNSUCCESSFUL;
}
diff --git a/source/nsswitch/winbindd_sid.c b/source/nsswitch/winbindd_sid.c
index ac1ee115554..3b30c3e2ebc 100644
--- a/source/nsswitch/winbindd_sid.c
+++ b/source/nsswitch/winbindd_sid.c
@@ -130,16 +130,75 @@ enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state)
DEBUG(3, ("[%5lu]: sid to uid %s\n", (unsigned long)state->pid,
state->request.data.sid));
- /* Split sid into domain sid and user rid */
if (!string_to_sid(&sid, state->request.data.sid)) {
DEBUG(1, ("Could not get convert sid %s from string\n", state->request.data.sid));
return WINBINDD_ERROR;
}
+ /* This gets a little tricky. If we assume that usernames are syncd between
+ /etc/passwd and the windows domain (such as a member of a Samba domain),
+ the we need to get the uid from the OS and not alocate one ourselves */
+
+ if ( lp_winbind_trusted_domains_only() ) {
+ struct winbindd_domain *domain = NULL;
+ DOM_SID sid2;
+ uint32 rid;
+
+ domain = find_domain_from_name( lp_workgroup() );
+ if ( !domain ) {
+ DEBUG(0,("winbindd_sid_to_uid: can't find my own domain!\n"));
+ return WINBINDD_ERROR;
+ }
+
+ sid_copy( &sid2, &sid );
+ sid_split_rid( &sid2, &rid );
+
+ if ( sid_equal( &sid2, &domain->sid ) ) {
+
+ fstring domain_name;
+ fstring user;
+ enum SID_NAME_USE type;
+ struct passwd *pw = NULL;
+ unid_t id;
+
+ /* ok...here's we know that we are dealing with our
+ own domain (the one to which we are joined). And
+ we know that there must be a UNIX account for this user.
+ So we lookup the sid and the call getpwnam().*/
+
+
+ /* But first check and see if we don't already have a mapping */
+
+ flags = ID_QUERY_ONLY;
+ if ( NT_STATUS_IS_OK(idmap_sid_to_uid(&sid, &(state->response.data.uid), flags)) )
+ return WINBINDD_OK;
+
+ /* now fall back to the hard way */
+
+ if ( !winbindd_lookup_name_by_sid(&sid, domain_name, user, &type) )
+ return WINBINDD_ERROR;
+
+ if ( !(pw = getpwnam(user)) ) {
+ DEBUG(0,("winbindd_sid_to_uid: 'winbind trusted domains only' is "
+ "set but this user [%s] doesn't exist!\n", user));
+ return WINBINDD_ERROR;
+ }
+
+ state->response.data.uid = pw->pw_uid;
+
+ id.uid = pw->pw_uid;
+ idmap_set_mapping( &sid, id, ID_USERID );
+
+ return WINBINDD_OK;
+ }
+
+ }
+
if ( state->request.flags & WBFLAG_QUERY_ONLY )
flags = ID_QUERY_ONLY;
/* Find uid for this sid and return it */
+
if ( !NT_STATUS_IS_OK(idmap_sid_to_uid(&sid, &(state->response.data.uid), flags)) ) {
DEBUG(1, ("Could not get uid for sid %s\n", state->request.data.sid));
return WINBINDD_ERROR;
@@ -167,6 +226,64 @@ enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state)
return WINBINDD_ERROR;
}
+ /* This gets a little tricky. If we assume that usernames are syncd between
+ /etc/passwd and the windows domain (such as a member of a Samba domain),
+ the we need to get the uid from the OS and not alocate one ourselves */
+
+ if ( lp_winbind_trusted_domains_only() ) {
+ struct winbindd_domain *domain = NULL;
+ DOM_SID sid2;
+ uint32 rid;
+ unid_t id;
+
+ domain = find_domain_from_name( lp_workgroup() );
+ if ( !domain ) {
+ DEBUG(0,("winbindd_sid_to_uid: can't find my own domain!\n"));
+ return WINBINDD_ERROR;
+ }
+
+ sid_copy( &sid2, &sid );
+ sid_split_rid( &sid2, &rid );
+
+ if ( sid_equal( &sid2, &domain->sid ) ) {
+
+ fstring domain_name;
+ fstring group;
+ enum SID_NAME_USE type;
+ struct group *grp = NULL;
+
+ /* ok...here's we know that we are dealing with our
+ own domain (the one to which we are joined). And
+ we know that there must be a UNIX account for this group.
+ So we lookup the sid and the call getpwnam().*/
+
+ /* But first check and see if we don't already have a mapping */
+
+ flags = ID_QUERY_ONLY;
+ if ( NT_STATUS_IS_OK(idmap_sid_to_gid(&sid, &(state->response.data.gid), flags)) )
+ return WINBINDD_OK;
+
+ /* now fall back to the hard way */
+
+ if ( !winbindd_lookup_name_by_sid(&sid, domain_name, group, &type) )
+ return WINBINDD_ERROR;
+
+ if ( !(grp = getgrnam(group)) ) {
+ DEBUG(0,("winbindd_sid_to_uid: 'winbind trusted domains only' is "
+ "set but this group [%s] doesn't exist!\n", group));
+ return WINBINDD_ERROR;
+ }
+
+ state->response.data.gid = grp->gr_gid;
+
+ id.gid = grp->gr_gid;
+ idmap_set_mapping( &sid, id, ID_GROUPID );
+
+ return WINBINDD_OK;
+ }
+
+ }
+
if ( state->request.flags & WBFLAG_QUERY_ONLY )
flags = ID_QUERY_ONLY;
@@ -185,28 +302,65 @@ enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state)
{
DOM_SID sid;
-#if 0 /* JERRY */
- /* we cannot do this check this anymore since a domain member of
- a Samba domain may share unix accounts via NIS or LDAP. In this
- case the uid/gid will be out of winbindd's range but still might
- be resolved to a SID via an ldap idmap backend */
-
- if ((state->request.data.uid < server_state.uid_low ) ||
- (state->request.data.uid > server_state.uid_high)) {
- return WINBINDD_ERROR;
- }
-#endif
-
DEBUG(3, ("[%5lu]: uid to sid %lu\n", (unsigned long)state->pid,
(unsigned long)state->request.data.uid));
+ if ( (state->request.data.uid < server_state.uid_low )
+ || (state->request.data.uid > server_state.uid_high) )
+ {
+ struct passwd *pw = NULL;
+ enum SID_NAME_USE type;
+ unid_t id;
+ struct winbindd_domain *domain;
+
+ /* SPECIAL CASE FOR MEMBERS OF SAMBA DOMAINS */
+
+ /* if we don't trust /etc/password then when can't know
+ anything about this uid */
+
+ if ( !lp_winbind_trusted_domains_only() )
+ return WINBINDD_ERROR;
+
+
+ /* look for an idmap entry first */
+
+ if ( NT_STATUS_IS_OK(idmap_uid_to_sid(&sid, state->request.data.uid)) )
+ goto done;
+
+ /* if users exist in /etc/passwd, we should try to
+ use that uid. Get the username and the lookup the SID */
+
+ if ( !(pw = getpwuid(state->request.data.uid)) )
+ return WINBINDD_ERROR;
+
+ if ( !(domain = find_domain_from_name(lp_workgroup())) ) {
+ DEBUG(0,("winbindd_uid_to_sid: can't find my own domain!\n"));
+ return WINBINDD_ERROR;
+ }
+
+ if ( !winbindd_lookup_sid_by_name(domain, pw->pw_name, &sid, &type) )
+ return WINBINDD_ERROR;
+
+ if ( type != SID_NAME_USER )
+ return WINBINDD_ERROR;
+
+ /* don't fail if we can't store it */
+
+ id.uid = pw->pw_uid;
+ idmap_set_mapping( &sid, id, ID_USERID );
+
+ goto done;
+ }
+
/* Lookup rid for this uid */
+
if (!NT_STATUS_IS_OK(idmap_uid_to_sid(&sid, state->request.data.uid))) {
DEBUG(1, ("Could not convert uid %lu to rid\n",
(unsigned long)state->request.data.uid));
return WINBINDD_ERROR;
}
+done:
sid_to_string(state->response.data.sid.sid, &sid);
state->response.data.sid.type = SID_NAME_USER;
@@ -219,28 +373,64 @@ enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state)
{
DOM_SID sid;
-#if 0 /* JERRY */
- /* we cannot do this check this anymore since a domain member of
- a Samba domain may share unix accounts via NIS or LDAP. In this
- case the uid/gid will be out of winbindd's range but still might
- be resolved to a SID via an ldap idmap backend */
-
- if ((state->request.data.gid < server_state.gid_low) ||
- (state->request.data.gid > server_state.gid_high)) {
- return WINBINDD_ERROR;
- }
-#endif
-
DEBUG(3, ("[%5lu]: gid to sid %lu\n", (unsigned long)state->pid,
(unsigned long)state->request.data.gid));
+
+ if ( (state->request.data.gid < server_state.gid_low)
+ || (state->request.data.gid > server_state.gid_high) )
+ {
+ struct group *grp = NULL;
+ enum SID_NAME_USE type;
+ unid_t id;
+ struct winbindd_domain *domain;
+
+ /* SPECIAL CASE FOR MEMBERS OF SAMBA DOMAINS */
+
+ /* if we don't trust /etc/group then when can't know
+ anything about this gid */
+
+ if ( !lp_winbind_trusted_domains_only() )
+ return WINBINDD_ERROR;
+
+ /* look for an idmap entry first */
+
+ if ( NT_STATUS_IS_OK(idmap_gid_to_sid(&sid, state->request.data.gid)) )
+ goto done;
+
+ /* if users exist in /etc/group, we should try to
+ use that gid. Get the username and the lookup the SID */
+
+ if ( !(grp = getgrgid(state->request.data.gid)) )
+ return WINBINDD_ERROR;
+
+ if ( !(domain = find_domain_from_name(lp_workgroup())) ) {
+ DEBUG(0,("winbindd_uid_to_sid: can't find my own domain!\n"));
+ return WINBINDD_ERROR;
+ }
+
+ if ( !winbindd_lookup_sid_by_name(domain, grp->gr_name, &sid, &type) )
+ return WINBINDD_ERROR;
+
+ if ( type!=SID_NAME_DOM_GRP || type!=SID_NAME_ALIAS )
+ return WINBINDD_ERROR;
+
+ /* don't fail if we can't store it */
+
+ id.gid = grp->gr_gid;
+ idmap_set_mapping( &sid, id, ID_GROUPID );
+
+ goto done;
+ }
/* Lookup sid for this uid */
+
if (!NT_STATUS_IS_OK(idmap_gid_to_sid(&sid, state->request.data.gid))) {
DEBUG(1, ("Could not convert gid %lu to sid\n",
(unsigned long)state->request.data.gid));
return WINBINDD_ERROR;
}
+done:
/* Construct sid and return it */
sid_to_string(state->response.data.sid.sid, &sid);
state->response.data.sid.type = SID_NAME_DOM_GRP;
diff --git a/source/nsswitch/winbindd_util.c b/source/nsswitch/winbindd_util.c
index 850a0b1a2d5..6d1675752f4 100644
--- a/source/nsswitch/winbindd_util.c
+++ b/source/nsswitch/winbindd_util.c
@@ -92,13 +92,13 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
/* We can't call domain_list() as this function is called from
init_domain_list() and we'll get stuck in a loop. */
for (domain = _domain_list; domain; domain = domain->next) {
- if (strcasecmp(domain_name, domain->name) == 0 ||
- strcasecmp(domain_name, domain->alt_name) == 0) {
+ if (strequal(domain_name, domain->name) ||
+ strequal(domain_name, domain->alt_name)) {
return domain;
}
if (alternative_name && *alternative_name) {
- if (strcasecmp(alternative_name, domain->name) == 0 ||
- strcasecmp(alternative_name, domain->alt_name) == 0) {
+ if (strequal(alternative_name, domain->name) ||
+ strequal(alternative_name, domain->alt_name)) {
return domain;
}
}
diff --git a/source/param/loadparm.c b/source/param/loadparm.c
index 5a5ac4a2cc1..e1308da3aa6 100644
--- a/source/param/loadparm.c
+++ b/source/param/loadparm.c
@@ -2025,7 +2025,7 @@ static int lp_enum(const char *s,const struct enum_list *_enum)
}
for (i=0; _enum[i].name; i++) {
- if (strcasecmp(_enum[i].name,s)==0)
+ if (strequal(_enum[i].name,s))
return _enum[i].value;
}
@@ -4240,9 +4240,9 @@ int lp_minor_announce_version(void)
Set the global name resolution order (used in smbclient).
************************************************************/
-void lp_set_name_resolve_order(char *new_order)
+void lp_set_name_resolve_order(const char *new_order)
{
- Globals.szNameResolveOrder = new_order;
+ string_set(&Globals.szNameResolveOrder, new_order);
}
const char *lp_printername(int snum)
diff --git a/source/passdb/lookup_sid.c b/source/passdb/lookup_sid.c
index f84ff28db91..ecf7f226298 100644
--- a/source/passdb/lookup_sid.c
+++ b/source/passdb/lookup_sid.c
@@ -299,7 +299,6 @@ static void store_gid_sid_cache(const DOM_SID *psid, gid_t gid)
NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid)
{
- uid_t low, high;
fstring sid;
ZERO_STRUCTP(psid);
@@ -307,16 +306,14 @@ NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid)
if (fetch_sid_from_uid_cache(psid, uid))
return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
- if (lp_idmap_uid(&low, &high) && uid >= low && uid <= high) {
- if (winbind_uid_to_sid(psid, uid)) {
+ if (winbind_uid_to_sid(psid, uid)) {
- DEBUG(10,("uid_to_sid: winbindd %u -> %s\n",
- (unsigned int)uid, sid_to_string(sid, psid)));
+ DEBUG(10,("uid_to_sid: winbindd %u -> %s\n",
+ (unsigned int)uid, sid_to_string(sid, psid)));
- if (psid)
- store_uid_sid_cache(psid, uid);
- return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
- }
+ if (psid)
+ store_uid_sid_cache(psid, uid);
+ return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
}
if (!local_uid_to_sid(psid, uid)) {
@@ -336,7 +333,6 @@ NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid)
NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid)
{
- gid_t low, high;
fstring sid;
ZERO_STRUCTP(psid);
@@ -344,16 +340,14 @@ NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid)
if (fetch_sid_from_gid_cache(psid, gid))
return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
- if (lp_idmap_gid(&low, &high) && gid >= low && gid <= high) {
- if (winbind_gid_to_sid(psid, gid)) {
+ if (winbind_gid_to_sid(psid, gid)) {
- DEBUG(10,("gid_to_sid: winbindd %u -> %s\n",
- (unsigned int)gid, sid_to_string(sid, psid)));
+ DEBUG(10,("gid_to_sid: winbindd %u -> %s\n",
+ (unsigned int)gid, sid_to_string(sid, psid)));
- if (psid)
- store_gid_sid_cache(psid, gid);
- return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
- }
+ if (psid)
+ store_gid_sid_cache(psid, gid);
+ return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
}
if (!local_gid_to_sid(psid, gid)) {
diff --git a/source/passdb/pdb_guest.c b/source/passdb/pdb_guest.c
index fa29657edcc..3b9e17075ed 100644
--- a/source/passdb/pdb_guest.c
+++ b/source/passdb/pdb_guest.c
@@ -60,7 +60,7 @@ static NTSTATUS guestsam_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *
if (!pdb_set_acct_ctrl(sam_account, ACB_NORMAL, PDB_DEFAULT))
return NT_STATUS_UNSUCCESSFUL;
- if (!pdb_set_user_sid_from_rid(sam_account, DOMAIN_USER_RID_GUEST, PDB_DEFAULT))
+ if (!pdb_set_user_sid_from_rid(sam_account, DOMAIN_USER_RID_GUEST, PDB_SET))
return NT_STATUS_UNSUCCESSFUL;
if (!pdb_set_group_sid_from_rid(sam_account, DOMAIN_GROUP_RID_GUESTS, PDB_DEFAULT))
@@ -110,7 +110,15 @@ static NTSTATUS guestsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT
static NTSTATUS guestsam_update_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd)
{
+#if 0 /* JERRY */
return methods->parent->pdb_add_sam_account(methods->parent, newpwd);
+#else
+ /* I don't think we should allow any modification of
+ the guest account as SID will could messed up with
+ the smbpasswd backend --jerry */
+
+ return NT_STATUS_NOT_IMPLEMENTED;
+#endif
}
NTSTATUS pdb_init_guestsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c
index 5cf1691f0dd..9299ca2e50e 100644
--- a/source/passdb/pdb_ldap.c
+++ b/source/passdb/pdb_ldap.c
@@ -356,7 +356,7 @@ static BOOL get_unix_attributes (struct ldapsam_privates *ldap_state,
}
for (values=ldap_values;*values;values++) {
- if (strcasecmp(*values, LDAP_OBJ_POSIXACCOUNT ) == 0) {
+ if (strequal(*values, LDAP_OBJ_POSIXACCOUNT )) {
break;
}
}
@@ -1983,21 +1983,22 @@ static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
return NT_STATUS_UNSUCCESSFUL;
}
- ldap_msgfree(result);
-
if (mods == NULL) {
DEBUG(4, ("ldapsam_update_group_mapping_entry: mods is empty: nothing to do\n"));
- return NT_STATUS_UNSUCCESSFUL;
+ ldap_msgfree(result);
+ return NT_STATUS_OK;
}
dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
if (!dn) {
+ ldap_msgfree(result);
return NT_STATUS_UNSUCCESSFUL;
}
rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
SAFE_FREE(dn);
ldap_mods_free(mods, True);
+ ldap_msgfree(result);
if (rc != LDAP_SUCCESS) {
char *ld_error = NULL;
@@ -2006,6 +2007,7 @@ static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
DEBUG(0, ("ldapsam_update_group_mapping_entry: failed to modify group %lu error: %s (%s)\n", (unsigned long)map->gid,
ld_error ? ld_error : "(unknown)", ldap_err2string(rc)));
SAFE_FREE(ld_error);
+ return NT_STATUS_UNSUCCESSFUL;
}
DEBUG(2, ("ldapsam_update_group_mapping_entry: successfully modified group %lu in LDAP\n", (unsigned long)map->gid));
diff --git a/source/passdb/pdb_smbpasswd.c b/source/passdb/pdb_smbpasswd.c
index 8cdbec9b9d0..562d50f89e3 100644
--- a/source/passdb/pdb_smbpasswd.c
+++ b/source/passdb/pdb_smbpasswd.c
@@ -431,7 +431,7 @@ static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_s
continue;
}
- if (!strncasecmp((char *) p, "NO PASSWORD", 11)) {
+ if (strnequal((char *) p, "NO PASSWORD", 11)) {
pw_buf->smb_passwd = NULL;
pw_buf->acct_ctrl |= ACB_PWNOTREQ;
} else {
diff --git a/source/printing/notify.c b/source/printing/notify.c
index e2146d50189..f2dd7d4f221 100644
--- a/source/printing/notify.c
+++ b/source/printing/notify.c
@@ -1,6 +1,6 @@
/*
Unix SMB/Netbios implementation.
- Version 2.2
+ Version 3.0
printing backend routines
Copyright (C) Tim Potter, 2002
Copyright (C) Gerald Carter, 2002
diff --git a/source/printing/nt_printing.c b/source/printing/nt_printing.c
index 9c95cf90856..bf8e1432c64 100644
--- a/source/printing/nt_printing.c
+++ b/source/printing/nt_printing.c
@@ -728,7 +728,7 @@ const char *get_short_archi(const char *long_archi)
static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 *minor)
{
int i;
- char *buf;
+ char *buf = NULL;
ssize_t byte_count;
if ((buf=malloc(PE_HEADER_SIZE)) == NULL) {
@@ -739,8 +739,8 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
/* Note: DOS_HEADER_SIZE < malloc'ed PE_HEADER_SIZE */
if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
- DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %d\n",
- fname, byte_count));
+ DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %lu\n",
+ fname, (unsigned long)byte_count));
goto no_version_info;
}
@@ -760,16 +760,16 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
}
if ((byte_count = vfs_read_data(fsp, buf, PE_HEADER_SIZE)) < PE_HEADER_SIZE) {
- DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %d\n",
- fname, byte_count));
+ DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %lu\n",
+ fname, (unsigned long)byte_count));
/* Assume this isn't an error... the file just looks sort of like a PE/NE file */
goto no_version_info;
}
/* The header may be a PE (Portable Executable) or an NE (New Executable) */
if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
- int num_sections;
- int section_table_bytes;
+ unsigned int num_sections;
+ unsigned int section_table_bytes;
if (SVAL(buf,PE_HEADER_MACHINE_OFFSET) != PE_HEADER_MACHINE_I386) {
DEBUG(3,("get_file_version: PE file [%s] wrong machine = 0x%x\n",
@@ -783,6 +783,9 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
/* get the section table */
num_sections = SVAL(buf,PE_HEADER_NUMBER_OF_SECTIONS);
section_table_bytes = num_sections * PE_HEADER_SECT_HEADER_SIZE;
+ if (section_table_bytes == 0)
+ goto error_exit;
+
SAFE_FREE(buf);
if ((buf=malloc(section_table_bytes)) == NULL) {
DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
@@ -791,8 +794,8 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
}
if ((byte_count = vfs_read_data(fsp, buf, section_table_bytes)) < section_table_bytes) {
- DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %d\n",
- fname, byte_count));
+ DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %lu\n",
+ fname, (unsigned long)byte_count));
goto error_exit;
}
@@ -801,8 +804,11 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
int sec_offset = i * PE_HEADER_SECT_HEADER_SIZE;
if (strcmp(".rsrc", &buf[sec_offset+PE_HEADER_SECT_NAME_OFFSET]) == 0) {
- int section_pos = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET);
- int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET);
+ unsigned int section_pos = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET);
+ unsigned int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET);
+
+ if (section_bytes == 0)
+ goto error_exit;
SAFE_FREE(buf);
if ((buf=malloc(section_bytes)) == NULL) {
@@ -819,11 +825,14 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
}
if ((byte_count = vfs_read_data(fsp, buf, section_bytes)) < section_bytes) {
- DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %d\n",
- fname, byte_count));
+ DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %lu\n",
+ fname, (unsigned long)byte_count));
goto error_exit;
}
+ if (section_bytes < VS_VERSION_INFO_UNICODE_SIZE)
+ goto error_exit;
+
for (i=0; i<section_bytes-VS_VERSION_INFO_UNICODE_SIZE; i++) {
/* Scan for 1st 3 unicoded bytes followed by word aligned magic value */
if (buf[i] == 'V' && buf[i+1] == '\0' && buf[i+2] == 'S') {
@@ -3306,10 +3315,11 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const char *sh
printername));
info.devmode = construct_nt_devicemode(printername);
}
-
- safe_strcpy(adevice, info.printername, sizeof(adevice)-1);
- fstrcpy(info.devmode->devicename, adevice);
+ safe_strcpy(adevice, info.printername, sizeof(adevice)-1);
+ if (info.devmode) {
+ fstrcpy(info.devmode->devicename, adevice);
+ }
len += unpack_values( &info.data, dbuf.dptr+len, dbuf.dsize-len );
diff --git a/source/printing/print_generic.c b/source/printing/print_generic.c
index 0b062ebdd98..1c847448da2 100644
--- a/source/printing/print_generic.c
+++ b/source/printing/print_generic.c
@@ -164,7 +164,7 @@ static int generic_job_submit(int snum, struct printjob *pjob)
pstrcpy(jobname, pjob->jobname);
pstring_sub(jobname, "'", "_");
slprintf(job_page_count, sizeof(job_page_count)-1, "%d", pjob->page_count);
- slprintf(job_size, sizeof(job_size)-1, "%d", pjob->size);
+ slprintf(job_size, sizeof(job_size)-1, "%lu", (unsigned long)pjob->size);
/* send it to the system spooler */
ret = print_run_command(snum,
diff --git a/source/rpc_client/cli_lsarpc.c b/source/rpc_client/cli_lsarpc.c
index 65115419b47..ab4fbad6131 100644
--- a/source/rpc_client/cli_lsarpc.c
+++ b/source/rpc_client/cli_lsarpc.c
@@ -322,6 +322,7 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
} else {
(*names)[i] = NULL;
+ (*domains)[i] = NULL;
(*types)[i] = SID_NAME_UNKNOWN;
}
}
diff --git a/source/rpc_client/cli_samr.c b/source/rpc_client/cli_samr.c
index f985ee9979b..e5e67f39dc9 100644
--- a/source/rpc_client/cli_samr.c
+++ b/source/rpc_client/cli_samr.c
@@ -865,6 +865,12 @@ NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
*num_mem = r.num_sids;
+ if (*num_mem == 0) {
+ *sids = NULL;
+ result = NT_STATUS_OK;
+ goto done;
+ }
+
if (!(*sids = talloc(mem_ctx, sizeof(DOM_SID) * *num_mem))) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
diff --git a/source/rpc_parse/parse_prs.c b/source/rpc_parse/parse_prs.c
index b30c41c0903..90563482391 100644
--- a/source/rpc_parse/parse_prs.c
+++ b/source/rpc_parse/parse_prs.c
@@ -1458,7 +1458,7 @@ void netsec_encode(struct netsec_auth_struct *a, int auth_flags,
static const uchar netsec_seal_sig[8] = NETSEC_SEAL_SIGNATURE;
static const uchar netsec_sign_sig[8] = NETSEC_SIGN_SIGNATURE;
- const uchar *netsec_sig;
+ const uchar *netsec_sig = NULL;
DEBUG(10,("SCHANNEL: netsec_encode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len));
@@ -1533,7 +1533,7 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags,
static const uchar netsec_seal_sig[8] = NETSEC_SEAL_SIGNATURE;
static const uchar netsec_sign_sig[8] = NETSEC_SIGN_SIGNATURE;
- const uchar *netsec_sig;
+ const uchar *netsec_sig = NULL;
uchar seq_num[8];
diff --git a/source/rpc_parse/parse_rpc.c b/source/rpc_parse/parse_rpc.c
index 1ea59feaedb..e2781b20088 100644
--- a/source/rpc_parse/parse_rpc.c
+++ b/source/rpc_parse/parse_rpc.c
@@ -147,6 +147,15 @@ interface/version dce/rpc pipe identification
}, 0x01 \
}
+#define SYNT_SHUTDOWN_V1 \
+{ \
+ { \
+ 0x894de0c0, 0x0d55, 0x11d3, \
+ { 0xa3, 0x22, 0x00, 0xc0, \
+ 0x4f, 0xa3, 0x21, 0xa1 } \
+ }, 0x01 \
+}
+
/*
* IMPORTANT!! If you update this structure, make sure to
* update the index #defines in smb.h.
@@ -165,6 +174,7 @@ const struct pipe_id_info pipe_names [] =
{ PIPE_SPOOLSS , SYNT_SPOOLSS_V1 , PIPE_SPOOLSS , TRANS_SYNT_V2 },
{ PIPE_NETDFS , SYNT_NETDFS_V3 , PIPE_NETDFS , TRANS_SYNT_V2 },
{ PIPE_ECHO , SYNT_ECHO_V1 , PIPE_ECHO , TRANS_SYNT_V2 },
+ { PIPE_SHUTDOWN, SYNT_SHUTDOWN_V1 , PIPE_SHUTDOWN , TRANS_SYNT_V2 },
{ NULL , SYNT_NONE_V0 , NULL , SYNT_NONE_V0 }
};
diff --git a/source/rpc_server/srv_dfs_nt.c b/source/rpc_server/srv_dfs_nt.c
index 751cb6e6425..ac3ed9c3947 100644
--- a/source/rpc_server/srv_dfs_nt.c
+++ b/source/rpc_server/srv_dfs_nt.c
@@ -70,6 +70,7 @@ WERROR _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u)
pstrcat(altpath, "\\");
pstrcat(altpath, sharename);
+ /* The following call can change the cwd. */
if(get_referred_path(dfspath, &jn, NULL, NULL))
{
exists = True;
@@ -79,6 +80,8 @@ WERROR _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u)
else
jn.referral_count = 1;
+ vfs_ChDir(p->conn,p->conn->connectpath);
+
jn.referral_list = (struct referral*) talloc(p->mem_ctx, jn.referral_count
* sizeof(struct referral));
@@ -100,8 +103,11 @@ WERROR _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u)
pstrcpy(jn.referral_list[jn.referral_count-1].alternate_path, altpath);
- if(!create_msdfs_link(&jn, exists))
+ if(!create_msdfs_link(&jn, exists)) {
+ vfs_ChDir(p->conn,p->conn->connectpath);
return WERR_DFS_CANT_CREATE_JUNCT;
+ }
+ vfs_ChDir(p->conn,p->conn->connectpath);
return WERR_OK;
}
@@ -147,8 +153,11 @@ WERROR _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u,
/* if no server-share pair given, remove the msdfs link completely */
if(!q_u->ptr_ServerName && !q_u->ptr_ShareName)
{
- if(!remove_msdfs_link(&jn))
+ if(!remove_msdfs_link(&jn)) {
+ vfs_ChDir(p->conn,p->conn->connectpath);
return WERR_DFS_NO_SUCH_VOL;
+ }
+ vfs_ChDir(p->conn,p->conn->connectpath);
}
else
{
@@ -175,13 +184,19 @@ WERROR _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u,
/* Only one referral, remove it */
if(jn.referral_count == 1)
{
- if(!remove_msdfs_link(&jn))
+ if(!remove_msdfs_link(&jn)) {
+ vfs_ChDir(p->conn,p->conn->connectpath);
return WERR_DFS_NO_SUCH_VOL;
+ }
+ vfs_ChDir(p->conn,p->conn->connectpath);
}
else
{
- if(!create_msdfs_link(&jn, True))
+ if(!create_msdfs_link(&jn, True)) {
+ vfs_ChDir(p->conn,p->conn->connectpath);
return WERR_DFS_CANT_CREATE_JUNCT;
+ }
+ vfs_ChDir(p->conn,p->conn->connectpath);
}
}
@@ -325,7 +340,8 @@ WERROR _dfs_enum(pipes_struct *p, DFS_Q_DFS_ENUM *q_u, DFS_R_DFS_ENUM *r_u)
int num_jn = 0;
num_jn = enum_msdfs_links(jn);
-
+ vfs_ChDir(p->conn,p->conn->connectpath);
+
DEBUG(5,("make_reply_dfs_enum: %d junctions found in Dfs, doing level %d\n", num_jn, level));
r_u->ptr_buffer = level;
@@ -351,21 +367,25 @@ WERROR _dfs_enum(pipes_struct *p, DFS_Q_DFS_ENUM *q_u, DFS_R_DFS_ENUM *r_u)
WERROR _dfs_get_info(pipes_struct *p, DFS_Q_DFS_GET_INFO *q_u,
DFS_R_DFS_GET_INFO *r_u)
{
- UNISTR2* uni_path = &q_u->uni_path;
- uint32 level = q_u->level;
- pstring path;
- struct junction_map jn;
-
- unistr2_to_ascii(path, uni_path, sizeof(path)-1);
- if(!create_junction(path, &jn))
- return WERR_DFS_NO_SUCH_SERVER;
+ UNISTR2* uni_path = &q_u->uni_path;
+ uint32 level = q_u->level;
+ pstring path;
+ struct junction_map jn;
+
+ unistr2_to_ascii(path, uni_path, sizeof(path)-1);
+ if(!create_junction(path, &jn))
+ return WERR_DFS_NO_SUCH_SERVER;
- if(!get_referred_path(path, &jn, NULL, NULL))
- return WERR_DFS_NO_SUCH_VOL;
+ /* The following call can change the cwd. */
+ if(!get_referred_path(path, &jn, NULL, NULL)) {
+ vfs_ChDir(p->conn,p->conn->connectpath);
+ return WERR_DFS_NO_SUCH_VOL;
+ }
- r_u->level = level;
- r_u->ptr_ctr = 1;
- r_u->status = init_reply_dfs_ctr(p->mem_ctx, level, &r_u->ctr, &jn, 1);
+ vfs_ChDir(p->conn,p->conn->connectpath);
+ r_u->level = level;
+ r_u->ptr_ctr = 1;
+ r_u->status = init_reply_dfs_ctr(p->mem_ctx, level, &r_u->ctr, &jn, 1);
- return r_u->status;
+ return r_u->status;
}
diff --git a/source/rpc_server/srv_lsa_hnd.c b/source/rpc_server/srv_lsa_hnd.c
index 814fa60aaba..2ec62e2c57a 100644
--- a/source/rpc_server/srv_lsa_hnd.c
+++ b/source/rpc_server/srv_lsa_hnd.c
@@ -89,8 +89,8 @@ BOOL init_pipe_handle_list(pipes_struct *p, char *pipe_name)
p->pipe_handles = hl;
- DEBUG(10,("init_pipe_handles: pipe_handles ref count = %u for pipe %s\n",
- p->pipe_handles->pipe_ref_count, pipe_name ));
+ DEBUG(10,("init_pipe_handles: pipe_handles ref count = %lu for pipe %s\n",
+ (unsigned long)p->pipe_handles->pipe_ref_count, pipe_name ));
return True;
}
diff --git a/source/rpc_server/srv_pipe_hnd.c b/source/rpc_server/srv_pipe_hnd.c
index 55def976732..57e45d477fe 100644
--- a/source/rpc_server/srv_pipe_hnd.c
+++ b/source/rpc_server/srv_pipe_hnd.c
@@ -541,7 +541,7 @@ static ssize_t unmarshall_rpc_header(pipes_struct *p)
void free_pipe_context(pipes_struct *p)
{
if (p->mem_ctx) {
- DEBUG(3,("free_pipe_context: destroying talloc pool of size %u\n", talloc_pool_size(p->mem_ctx) ));
+ DEBUG(3,("free_pipe_context: destroying talloc pool of size %lu\n", (unsigned long)talloc_pool_size(p->mem_ctx) ));
talloc_destroy_pool(p->mem_ctx);
} else {
p->mem_ctx = talloc_init("pipe %s %p", p->name, p);
diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c
index f2fb02176b5..15578f61482 100644
--- a/source/rpc_server/srv_spoolss_nt.c
+++ b/source/rpc_server/srv_spoolss_nt.c
@@ -2598,7 +2598,8 @@ static BOOL spoolss_connect_to_client(struct cli_state *the_cli,
}
the_cli->protocol = PROTOCOL_NT1;
-
+ cli_setup_signing_state(the_cli, lp_client_signing());
+
if (!cli_negprot(the_cli)) {
DEBUG(0,("spoolss_connect_to_client: machine %s rejected the negotiate protocol. Error was : %s.\n", remote_machine, cli_errstr(the_cli) ));
cli_shutdown(the_cli);
diff --git a/source/rpcclient/cmd_spoolss.c b/source/rpcclient/cmd_spoolss.c
index 05bfb2a0dcc..798949fae92 100644
--- a/source/rpcclient/cmd_spoolss.c
+++ b/source/rpcclient/cmd_spoolss.c
@@ -1246,7 +1246,7 @@ static BOOL init_drv_info_3_members (
}
for (i=0; i<len; i++)
{
- info->dependentfiles[i] = SSVAL(&info->dependentfiles[i], 0, str2[i]);
+ SSVAL(&info->dependentfiles[i], 0, str2[i]);
}
info->dependentfiles[len] = '\0';
@@ -1266,12 +1266,13 @@ static WERROR cmd_spoolss_addprinterdriver(struct cli_state *cli,
fstring driver_name;
/* parse the command arguements */
- if (argc != 3)
+ if (argc != 3 && argc != 4)
{
- printf ("Usage: %s <Environment>\\\n", argv[0]);
+ printf ("Usage: %s <Environment> \\\n", argv[0]);
printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
- printf ("\t<Default Data Type>:<Comma Separated list of Files>\n");
+ printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
+ printf ("\t[version]\n");
return WERR_OK;
}
@@ -1292,6 +1293,14 @@ static WERROR cmd_spoolss_addprinterdriver(struct cli_state *cli,
return WERR_INVALID_PARAM;
}
+ /* if printer driver version specified, override the default version
+ * used by the architecture. This allows installation of Windows
+ * 2000 (version 3) printer drivers. */
+ if (argc == 4)
+ {
+ info3.version = atoi(argv[3]);
+ }
+
ctr.info3 = &info3;
result = cli_spoolss_addprinterdriver (cli, mem_ctx, level, &ctr);
diff --git a/source/rpcclient/rpcclient.c b/source/rpcclient/rpcclient.c
index 773441a27cc..f6dfd9bffae 100644
--- a/source/rpcclient/rpcclient.c
+++ b/source/rpcclient/rpcclient.c
@@ -462,6 +462,7 @@ extern struct cmd_set dfs_commands[];
extern struct cmd_set reg_commands[];
extern struct cmd_set ds_commands[];
extern struct cmd_set echo_commands[];
+extern struct cmd_set shutdown_commands[];
static struct cmd_set *rpcclient_command_list[] = {
rpcclient_commands,
@@ -474,6 +475,7 @@ static struct cmd_set *rpcclient_command_list[] = {
dfs_commands,
reg_commands,
echo_commands,
+ shutdown_commands,
NULL
};
diff --git a/source/rpcclient/rpcclient.h b/source/rpcclient/rpcclient.h
index 1db4246d370..e1e61dc43d5 100644
--- a/source/rpcclient/rpcclient.h
+++ b/source/rpcclient/rpcclient.h
@@ -25,7 +25,7 @@
typedef enum {
RPC_RTYPE_NTSTATUS = 0,
RPC_RTYPE_WERROR,
- MAX_RPC_RETURN_TYPE,
+ MAX_RPC_RETURN_TYPE
} RPC_RETURN_TYPE;
struct cmd_set {
diff --git a/source/sam/idmap_ldap.c b/source/sam/idmap_ldap.c
index 72fcb47b039..718f134de4a 100644
--- a/source/sam/idmap_ldap.c
+++ b/source/sam/idmap_ldap.c
@@ -421,86 +421,46 @@ static NTSTATUS ldap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
{
LDAPMessage *result = NULL;
LDAPMessage *entry = NULL;
- fstring id_str;
pstring sid_str;
pstring filter;
pstring suffix;
const char *type;
- const char *obj_class;
int rc;
int count;
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
char **attr_list;
- /* first we try for a samba user or group mapping */
-
+ pstrcpy( suffix, lp_ldap_idmap_suffix() );
+ pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))",
+ LDAP_OBJ_IDMAP_ENTRY, type,
+ ((id_type & ID_USERID) ? (unsigned long)id.uid : (unsigned long)id.gid));
+
if ( id_type & ID_USERID ) {
type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER );
- obj_class = LDAP_OBJ_SAMBASAMACCOUNT;
- fstr_sprintf(id_str, "%lu", (unsigned long)id.uid );
- pstrcpy( suffix, lp_ldap_suffix());
}
else {
type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER );
- obj_class = LDAP_OBJ_GROUPMAP;
- fstr_sprintf(id_str, "%lu", (unsigned long)id.gid );
- pstrcpy( suffix, lp_ldap_group_suffix() );
}
DEBUG(5,("ldap_get_sid_from_id: Searching \"%s\"\n", filter ));
attr_list = get_attr_list( sidmap_attr_list );
- pstr_sprintf(filter, "(&(|(objectClass=%s)(objectClass=%s))(%s=%s))",
- LDAP_OBJ_IDMAP_ENTRY, obj_class, type, id_str);
-
rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE,
- filter, attr_list, 0, &result);
-
+ filter, attr_list, 0, &result);
+
if (rc != LDAP_SUCCESS) {
DEBUG(3,("ldap_get_isd_from_id: Failure looking up entry (%s)\n",
ldap_err2string(rc) ));
goto out;
}
-
- count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
-
- if (count > 1) {
- DEBUG(0,("ldap_get_sid_from_id: mapping returned [%d] entries!\n",
- count));
- goto out;
- }
-
- /* fall back to looking up an idmap entry if we didn't find and
- actual user or group */
-
- if (count == 0) {
- ldap_msgfree(result);
- result = NULL;
-
- pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))",
- LDAP_OBJ_IDMAP_ENTRY, type,
- ((id_type & ID_USERID) ? (unsigned long)id.uid :
- (unsigned long)id.gid));
-
- pstrcpy( suffix, lp_ldap_idmap_suffix() );
-
- rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE,
- filter, attr_list, 0, &result);
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(3,("ldap_get_isd_from_id: Failure looking up entry (%s)\n",
- ldap_err2string(rc) ));
- goto out;
- }
- count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
+ count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
- if (count != 1) {
- DEBUG(0,("ldap_get_sid_from_id: mapping not found for %s: %lu\n",
- type, ((id_type & ID_USERID) ? (unsigned long)id.uid :
- (unsigned long)id.gid)));
- goto out;
- }
+ if (count != 1) {
+ DEBUG(0,("ldap_get_sid_from_id: mapping not found for %s: %lu\n",
+ type, ((id_type & ID_USERID) ? (unsigned long)id.uid :
+ (unsigned long)id.gid)));
+ goto out;
}
entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result);
@@ -545,28 +505,15 @@ static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *si
DEBUG(8,("ldap_get_id_from_sid: %s (%s)\n", sid_str,
(*id_type & ID_GROUPID ? "group" : "user") ));
- /* ahhh.... ok. We have to check users and groups in places other
- than idmap (hint: we're a domain member of a Samba domain) */
-
+ suffix = lp_ldap_idmap_suffix();
+ pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))",
+ LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_SID, sid_str);
+
if ( *id_type & ID_GROUPID ) {
-
type = get_attr_key2string( sidmap_attr_list, LDAP_ATTR_GIDNUMBER );
- suffix = lp_ldap_group_suffix();
- pstr_sprintf(filter, "(&(|(objectClass=%s)(objectClass=%s))(%s=%s))",
- LDAP_OBJ_GROUPMAP, LDAP_OBJ_IDMAP_ENTRY,
- get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID ),
- sid_str);
-
}
else {
-
type = get_attr_key2string( sidmap_attr_list, LDAP_ATTR_UIDNUMBER );
- suffix = lp_ldap_suffix();
- pstr_sprintf(filter, "(&(|(&(objectClass=%s)(objectClass=%s))(objectClass=%s))(%s=%s))",
- LDAP_OBJ_SAMBASAMACCOUNT, LDAP_OBJ_POSIXACCOUNT, LDAP_OBJ_IDMAP_ENTRY,
- get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID ),
- sid_str);
-
}
DEBUG(10,("ldap_get_id_from_sid: Searching for \"%s\"\n", filter));
@@ -575,84 +522,51 @@ static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *si
attr_list = get_attr_list( sidmap_attr_list );
rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE,
- filter, attr_list, 0, &result);
-
- if ( rc != LDAP_SUCCESS ) {
- DEBUG(3,("ldap_get_id_from_sid: Failure looking up group mapping (%s)\n",
+ filter, attr_list, 0, &result);
+
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(3,("ldap_get_id_from_sid: Failure looking up idmap entry (%s)\n",
ldap_err2string(rc) ));
goto out;
}
+
+ /* check for the number of entries returned */
count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
-
+
if ( count > 1 ) {
- DEBUG(3,("ldap_get_id_from_sid: search \"%s\" returned [%d] entries. Bailing...\n",
+ DEBUG(0, ("ldap_get_id_from_sid: (2nd) search %s returned [%d] entries!\n",
filter, count));
goto out;
}
-
- /* see if we need to do a search here */
-
- if ( count == 0 ) {
-
- if ( result ) {
- ldap_msgfree(result);
- result = NULL;
- }
-
- /* look in idmap suffix */
-
- suffix = lp_ldap_idmap_suffix();
- pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))",
- LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_SID, sid_str);
-
- rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE,
- filter, attr_list, 0, &result);
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(3,("ldap_get_id_from_sid: Failure looking up idmap entry (%s)\n",
- ldap_err2string(rc) ));
- goto out;
- }
-
- /* check for the number of entries returned */
-
- count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
-
- if ( count > 1 ) {
- DEBUG(0, ("ldap_get_id_from_sid: (2nd) search %s returned [%d] entries!\n",
- filter, count));
- goto out;
- }
- /* try to allocate a new id if we still haven't found one */
+ /* try to allocate a new id if we still haven't found one */
- if ( (count==0) && !(*id_type & ID_QUERY_ONLY) ) {
- int i;
+ if ( (count==0) && !(*id_type & ID_QUERY_ONLY) ) {
+ int i;
- DEBUG(8,("ldap_get_id_from_sid: Allocating new id\n"));
+ DEBUG(8,("ldap_get_id_from_sid: Allocating new id\n"));
- for (i = 0; i < LDAP_MAX_ALLOC_ID; i++) {
- ret = ldap_allocate_id(id, *id_type);
- if ( NT_STATUS_IS_OK(ret) )
- break;
- }
+ 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) ) {
- DEBUG(0,("ldap_allocate_id: cannot acquire id lock!\n"));
- goto out;
- }
+ if ( !NT_STATUS_IS_OK(ret) ) {
+ DEBUG(0,("ldap_allocate_id: cannot acquire id lock!\n"));
+ goto out;
+ }
- DEBUG(10,("ldap_get_id_from_sid: Allocated new %cid [%ul]\n",
- (*id_type & ID_GROUPID ? 'g' : 'u'), (uint32)id->uid ));
+ DEBUG(10,("ldap_get_id_from_sid: Allocated new %cid [%ul]\n",
+ (*id_type & ID_GROUPID ? 'g' : 'u'), (uint32)id->uid ));
- ret = ldap_set_mapping(sid, *id, *id_type);
+ ret = ldap_set_mapping(sid, *id, *id_type);
- /* all done */
+ /* all done */
- goto out;
- }
+ goto out;
}
DEBUG(10,("ldap_get_id_from_sid: success\n"));
diff --git a/source/script/mkbuildoptions.awk b/source/script/mkbuildoptions.awk
index cdc5bd98813..9c226623109 100644
--- a/source/script/mkbuildoptions.awk
+++ b/source/script/mkbuildoptions.awk
@@ -242,14 +242,14 @@ END {
# add code to display the various type sizes
print " /* Output the sizes of the various types */";
print " output(screen, \"\\nType sizes:\\n\");";
- print " output(screen, \" sizeof(char): %u\\n\",sizeof(char));";
- print " output(screen, \" sizeof(int): %u\\n\",sizeof(int));";
- print " output(screen, \" sizeof(long): %u\\n\",sizeof(long));";
- print " output(screen, \" sizeof(uint8): %u\\n\",sizeof(uint8));";
- print " output(screen, \" sizeof(uint16): %u\\n\",sizeof(uint16));";
- print " output(screen, \" sizeof(uint32): %u\\n\",sizeof(uint32));";
- print " output(screen, \" sizeof(short): %u\\n\",sizeof(short));";
- print " output(screen, \" sizeof(void*): %u\\n\",sizeof(void*));";
+ print " output(screen, \" sizeof(char): %lu\\n\",(unsigned long)sizeof(char));";
+ print " output(screen, \" sizeof(int): %lu\\n\",(unsigned long)sizeof(int));";
+ print " output(screen, \" sizeof(long): %lu\\n\",(unsigned long)sizeof(long));";
+ print " output(screen, \" sizeof(uint8): %lu\\n\",(unsigned long)sizeof(uint8));";
+ print " output(screen, \" sizeof(uint16): %lu\\n\",(unsigned long)sizeof(uint16));";
+ print " output(screen, \" sizeof(uint32): %lu\\n\",(unsigned long)sizeof(uint32));";
+ print " output(screen, \" sizeof(short): %lu\\n\",(unsigned long)sizeof(short));";
+ print " output(screen, \" sizeof(void*): %lu\\n\",(unsigned long)sizeof(void*));";
##################################################
# add code to give information about modules
diff --git a/source/smbd/blocking.c b/source/smbd/blocking.c
index f43790bfe03..c0512d5539b 100644
--- a/source/smbd/blocking.c
+++ b/source/smbd/blocking.c
@@ -149,7 +149,7 @@ for fnum = %d, name = %s\n", length, (int)blr->expire_time, lock_timeout,
blr->fsp->fnum, blr->fsp->fsp_name ));
/* Push the MID of this packet on the signing queue. */
- srv_defer_sign_response(SVAL(inbuf,smb_mid), True);
+ srv_defer_sign_response(SVAL(inbuf,smb_mid));
return True;
}
diff --git a/source/smbd/dosmode.c b/source/smbd/dosmode.c
index aaee41b546a..f88964123e1 100644
--- a/source/smbd/dosmode.c
+++ b/source/smbd/dosmode.c
@@ -136,9 +136,11 @@ uint32 dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf)
if (S_ISDIR(sbuf->st_mode))
result = aDIR | (result & aRONLY);
+#if defined (HAVE_STAT_ST_BLOCKS) && defined (HAVE_STAT_ST_BLKSIZE)
if (sbuf->st_size > sbuf->st_blocks * (SMB_OFF_T)sbuf->st_blksize) {
result |= FILE_ATTRIBUTE_SPARSE;
}
+#endif
#ifdef S_ISLNK
#if LINKS_READ_ONLY
diff --git a/source/smbd/fileio.c b/source/smbd/fileio.c
index 6cf70148463..84339c3a6fc 100644
--- a/source/smbd/fileio.c
+++ b/source/smbd/fileio.c
@@ -707,8 +707,8 @@ static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size)
DO_PROFILE_INC(writecache_allocated_write_caches);
allocated_write_caches++;
- DEBUG(10,("setup_write_cache: File %s allocated write cache size %u\n",
- fsp->fsp_name, wcp->alloc_size ));
+ DEBUG(10,("setup_write_cache: File %s allocated write cache size %lu\n",
+ fsp->fsp_name, (unsigned long)wcp->alloc_size ));
return True;
}
@@ -725,7 +725,7 @@ void set_filelen_write_cache(files_struct *fsp, SMB_OFF_T file_size)
if (fsp->wcp->data_size != 0) {
pstring msg;
slprintf(msg, sizeof(msg)-1, "set_filelen_write_cache: size change \
-on file %s with write cache size = %u\n", fsp->fsp_name, fsp->wcp->data_size );
+on file %s with write cache size = %lu\n", fsp->fsp_name, (unsigned long)fsp->wcp->data_size );
smb_panic(msg);
}
fsp->wcp->file_size = file_size;
diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c
index 39072f9b912..86d982b0227 100644
--- a/source/smbd/ipc.c
+++ b/source/smbd/ipc.c
@@ -96,7 +96,7 @@ void send_trans_reply(char *outbuf,
align = ((this_lparam)%4);
if (buffer_too_large) {
- ERROR_NT(STATUS_BUFFER_OVERFLOW);
+ ERROR_BOTH(STATUS_BUFFER_OVERFLOW,ERRDOS,ERRmoredata);
}
set_message(outbuf,10,1+align+this_ldata+this_lparam,True);
@@ -281,6 +281,14 @@ static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf,
subcommand = ((int)setup[0]) & 0xFFFF;
if(!(p = get_rpc_pipe(pnum))) {
+ if (subcommand == TRANSACT_WAITNAMEDPIPEHANDLESTATE) {
+ /* Win9x does this call with a unicode pipe name, not a pnum. */
+ /* Just return success for now... */
+ DEBUG(3,("Got TRANSACT_WAITNAMEDPIPEHANDLESTATE on text pipe name\n"));
+ send_trans_reply(outbuf, NULL, 0, NULL, 0, False);
+ return -1;
+ }
+
DEBUG(1,("api_fd_reply: INVALID PIPE HANDLE: %x\n", pnum));
return api_no_reply(outbuf, mdrcnt);
}
@@ -388,7 +396,8 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
}
if ((dsoff+dscnt < dsoff) || (dsoff+dscnt < dscnt))
goto bad_param;
- if (smb_base(inbuf)+dsoff+dscnt > inbuf + size)
+ if ((smb_base(inbuf)+dsoff+dscnt > inbuf + size) ||
+ (smb_base(inbuf)+dsoff+dscnt < smb_base(inbuf)))
goto bad_param;
memcpy(data,smb_base(inbuf)+dsoff,dscnt);
@@ -402,8 +411,9 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
return(ERROR_DOS(ERRDOS,ERRnomem));
}
if ((psoff+pscnt < psoff) || (psoff+pscnt < pscnt))
- goto bad_param;
- if (smb_base(inbuf)+psoff+pscnt > inbuf + size)
+ goto bad_param;
+ if ((smb_base(inbuf)+psoff+pscnt > inbuf + size) ||
+ (smb_base(inbuf)+psoff+pscnt < smb_base(inbuf)))
goto bad_param;
memcpy(params,smb_base(inbuf)+psoff,pscnt);
@@ -487,8 +497,11 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
if (pdisp+pcnt >= tpscnt)
goto bad_param;
if ((pdisp+pcnt < pdisp) || (pdisp+pcnt < pcnt))
- goto bad_param;
- if (smb_base(inbuf) + poff + pcnt >= inbuf + bufsize)
+ goto bad_param;
+ if (pdisp > tpscnt)
+ goto bad_param;
+ if ((smb_base(inbuf) + poff + pcnt >= inbuf + bufsize) ||
+ (smb_base(inbuf) + poff + pcnt < smb_base(inbuf)))
goto bad_param;
if (params + pdisp < params)
goto bad_param;
@@ -501,7 +514,10 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
goto bad_param;
if ((ddisp+dcnt < ddisp) || (ddisp+dcnt < dcnt))
goto bad_param;
- if (smb_base(inbuf) + doff + dcnt >= inbuf + bufsize)
+ if (ddisp > tdscnt)
+ goto bad_param;
+ if ((smb_base(inbuf) + doff + dcnt >= inbuf + bufsize) ||
+ (smb_base(inbuf) + doff + dcnt < smb_base(inbuf)))
goto bad_param;
if (data + ddisp < data)
goto bad_param;
diff --git a/source/smbd/lanman.c b/source/smbd/lanman.c
index b27ccc23ef7..3ea6ab483be 100644
--- a/source/smbd/lanman.c
+++ b/source/smbd/lanman.c
@@ -522,6 +522,8 @@ static void fill_printq_info_52(connection_struct *conn, int snum,
NT_PRINTER_DRIVER_INFO_LEVEL driver;
NT_PRINTER_INFO_LEVEL *printer = NULL;
+ ZERO_STRUCT(driver);
+
if ( !W_ERROR_IS_OK(get_a_printer( NULL, &printer, 2, lp_servicename(snum))) ) {
DEBUG(3,("fill_printq_info_52: Failed to lookup printer [%s]\n",
lp_servicename(snum)));
@@ -679,6 +681,8 @@ static int get_printerdrivernumber(int snum)
NT_PRINTER_DRIVER_INFO_LEVEL driver;
NT_PRINTER_INFO_LEVEL *printer = NULL;
+ ZERO_STRUCT(driver);
+
if ( !W_ERROR_IS_OK(get_a_printer( NULL, &printer, 2, lp_servicename(snum))) ) {
DEBUG(3,("get_printerdrivernumber: Failed to lookup printer [%s]\n",
lp_servicename(snum)));
@@ -2342,15 +2346,15 @@ static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *par
pstring comment;
uint32 servertype= lp_default_server_announce();
- pstrcpy(comment,string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
+ push_ascii(comment,lp_serverstring(), MAX_SERVER_STRING_LENGTH,STR_TERMINATE);
if ((count=get_server_info(SV_TYPE_ALL,&servers,lp_workgroup()))>0) {
- for (i=0;i<count;i++)
- if (strequal(servers[i].name,local_machine))
- {
+ for (i=0;i<count;i++) {
+ if (strequal(servers[i].name,local_machine)) {
servertype = servers[i].type;
- pstrcpy(comment,servers[i].comment);
+ push_ascii(comment,servers[i].comment,sizeof(pstring),STR_TERMINATE);
}
+ }
}
SAFE_FREE(servers);
diff --git a/source/smbd/mangle_hash2.c b/source/smbd/mangle_hash2.c
index e0efb3e41bc..7e7bc8c68cf 100644
--- a/source/smbd/mangle_hash2.c
+++ b/source/smbd/mangle_hash2.c
@@ -427,7 +427,7 @@ static BOOL is_reserved_name(const char *name)
for (i=0; reserved_names[i]; i++) {
int len = strlen(reserved_names[i]);
/* note that we match on COM1 as well as COM1.foo */
- if (strncasecmp(name, reserved_names[i], len) == 0 &&
+ if (strnequal(name, reserved_names[i], len) &&
(name[len] == '.' || name[len] == 0)) {
return True;
}
diff --git a/source/smbd/notify.c b/source/smbd/notify.c
index ca6f2b783f2..9adf827c794 100644
--- a/source/smbd/notify.c
+++ b/source/smbd/notify.c
@@ -199,7 +199,7 @@ BOOL change_notify_set(char *inbuf, files_struct *fsp, connection_struct *conn,
DLIST_ADD(change_notify_list, cnbp);
/* Push the MID of this packet on the signing queue. */
- srv_defer_sign_response(SVAL(inbuf,smb_mid), True);
+ srv_defer_sign_response(SVAL(inbuf,smb_mid));
return True;
}
diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c
index b4e7a70088d..80297daaef3 100644
--- a/source/smbd/nttrans.c
+++ b/source/smbd/nttrans.c
@@ -1956,8 +1956,8 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
DEBUGADD(10,("for SID: %s\n",sid_string_static(&sid)));
if (!NT_STATUS_IS_OK(sid_to_uid(&sid, &uid))) {
- DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%u]\n",
- sid_string_static(&sid),sid_len));
+ DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%lu]\n",
+ sid_string_static(&sid),(unsigned long)sid_len));
uid = (-1);
}
@@ -2168,7 +2168,7 @@ static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf,
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));
+ DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %lu bytes data\n",data_count,(unsigned long)(8+sid_len)));
return ERROR_DOS(ERRDOS,ERRunknownlevel);
}
@@ -2301,7 +2301,7 @@ static int call_nt_transact_set_user_quota(connection_struct *conn, char *inbuf,
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));
+ DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %lu bytes data\n",data_count,(unsigned long)40+sid_len));
return ERROR_DOS(ERRDOS,ERRunknownlevel);
}
@@ -2463,7 +2463,8 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
if ((parameter_offset + parameter_count < parameter_offset) ||
(parameter_offset + parameter_count < parameter_count))
goto bad_param;
- if (smb_base(inbuf) + parameter_offset + parameter_count > inbuf + length)
+ if ((smb_base(inbuf) + parameter_offset + parameter_count > inbuf + length)||
+ (smb_base(inbuf) + parameter_offset + parameter_count < smb_base(inbuf)))
goto bad_param;
memcpy( params, smb_base(inbuf) + parameter_offset, parameter_count);
@@ -2473,7 +2474,8 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
DEBUG(10,("reply_nttrans: data_count = %d\n",data_count));
if ((data_offset + data_count < data_offset) || (data_offset + data_count < data_count))
goto bad_param;
- if (smb_base(inbuf) + data_offset + data_count > inbuf + length)
+ if ((smb_base(inbuf) + data_offset + data_count > inbuf + length) ||
+ (smb_base(inbuf) + data_offset + data_count < smb_base(inbuf)))
goto bad_param;
memcpy( data, smb_base(inbuf) + data_offset, data_count);
@@ -2534,7 +2536,10 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
if ((parameter_displacement + parameter_count < parameter_displacement) ||
(parameter_displacement + parameter_count < parameter_count))
goto bad_param;
- if (smb_base(inbuf) + parameter_offset + parameter_count >= inbuf + bufsize)
+ if (parameter_displacement > total_parameter_count)
+ goto bad_param;
+ if ((smb_base(inbuf) + parameter_offset + parameter_count >= inbuf + bufsize) ||
+ (smb_base(inbuf) + parameter_offset + parameter_count < smb_base(inbuf)))
goto bad_param;
if (parameter_displacement + params < params)
goto bad_param;
@@ -2548,7 +2553,10 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
if ((data_displacement + data_count < data_displacement) ||
(data_displacement + data_count < data_count))
goto bad_param;
- if (smb_base(inbuf) + data_offset + data_count >= inbuf + bufsize)
+ if (data_displacement > total_data_count)
+ goto bad_param;
+ if ((smb_base(inbuf) + data_offset + data_count >= inbuf + bufsize) ||
+ (smb_base(inbuf) + data_offset + data_count < smb_base(inbuf)))
goto bad_param;
if (data_displacement + data < data)
goto bad_param;
diff --git a/source/smbd/open.c b/source/smbd/open.c
index 71af23aaf92..ef7ace862ae 100644
--- a/source/smbd/open.c
+++ b/source/smbd/open.c
@@ -631,7 +631,7 @@ dev = %x, inode = %.0f\n", *p_oplock_request, share_entry->op_type, fname, (unsi
/* This isn't a real deferred packet as it's response will also increment
* the sequence.
*/
- srv_defer_sign_response(get_current_mid(), False);
+ srv_defer_sign_response(get_current_mid());
/* Oplock break - unlock to request it. */
unlock_share_entry(conn, dev, inode);
diff --git a/source/smbd/oplock_linux.c b/source/smbd/oplock_linux.c
index ac9cf5b8a61..5de9dd56e68 100644
--- a/source/smbd/oplock_linux.c
+++ b/source/smbd/oplock_linux.c
@@ -226,8 +226,8 @@ static BOOL linux_kernel_oplock_parse(char *msg_start, int msg_len, SMB_INO_T *i
{
/* Ensure that the msg length is correct. */
if (msg_len != KERNEL_OPLOCK_BREAK_MSG_LEN) {
- DEBUG(0,("incorrect length for KERNEL_OPLOCK_BREAK_CMD (was %d, should be %d).\n",
- msg_len, KERNEL_OPLOCK_BREAK_MSG_LEN));
+ DEBUG(0,("incorrect length for KERNEL_OPLOCK_BREAK_CMD (was %d, should be %lu).\n",
+ msg_len, (unsigned long)KERNEL_OPLOCK_BREAK_MSG_LEN));
return False;
}
diff --git a/source/smbd/posix_acls.c b/source/smbd/posix_acls.c
index 95b45fcc997..aa1d25c483a 100644
--- a/source/smbd/posix_acls.c
+++ b/source/smbd/posix_acls.c
@@ -460,7 +460,7 @@ static struct pai_val *load_inherited_info(files_struct *fsp)
}
} while (ret == -1);
- DEBUG(10,("load_inherited_info: ret = %d for file %s\n", ret, fsp->fsp_name));
+ DEBUG(10,("load_inherited_info: ret = %lu for file %s\n", (unsigned long)ret, fsp->fsp_name));
if (ret == -1) {
/* No attribute or not supported. */
diff --git a/source/smbd/process.c b/source/smbd/process.c
index 3c15cd18333..8a90a15d297 100644
--- a/source/smbd/process.c
+++ b/source/smbd/process.c
@@ -97,7 +97,7 @@ static BOOL push_message(ubi_slList *list_head, char *buf, int msg_len)
ubi_slAddTail( list_head, msg);
/* Push the MID of this packet on the signing queue. */
- srv_defer_sign_response(SVAL(buf,smb_mid), True);
+ srv_defer_sign_response(SVAL(buf,smb_mid));
return True;
}
@@ -637,7 +637,7 @@ static void smb_dump(const char *name, int type, char *data, ssize_t len)
if (ret != len)
DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
close(fd);
- DEBUG(0,("created %s len %d\n", fname, len));
+ DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
}
}
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index ec63be32b40..37525074930 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -669,10 +669,9 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
time_t date;
int dirtype;
int outsize = 0;
- int numentries = 0;
+ unsigned int numentries = 0;
+ unsigned int maxentries = 0;
BOOL finished = False;
- int maxentries;
- int i;
char *p;
BOOL ok = False;
int status_len;
@@ -786,6 +785,9 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
numentries = 0;
p += DIR_STRUCT_SIZE;
} else {
+ unsigned int i;
+ maxentries = MIN(maxentries, ((BUFFER_SIZE - (p - outbuf))/DIR_STRUCT_SIZE));
+
DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
conn->dirpath,lp_dontdescend(SNUM(conn))));
if (in_list(conn->dirpath, lp_dontdescend(SNUM(conn)),True))
@@ -845,7 +847,7 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
if ((! *directory) && dptr_path(dptr_num))
slprintf(directory, sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
- DEBUG( 4, ( "%s mask=%s path=%s dtype=%d nument=%d of %d\n",
+ DEBUG( 4, ( "%s mask=%s path=%s dtype=%d nument=%u of %u\n",
smb_fn_name(CVAL(inbuf,smb_com)),
mask, directory, dirtype, numentries, maxentries ) );
@@ -2784,7 +2786,11 @@ int reply_echo(connection_struct *conn,
int outsize = set_message(outbuf,1,data_len,True);
START_PROFILE(SMBecho);
- data_len = MIN(data_len, (sizeof(inbuf)-(smb_buf(inbuf)-inbuf)));
+ if (data_len > BUFFER_SIZE) {
+ DEBUG(0,("reply_echo: data_len too large.\n"));
+ END_PROFILE(SMBecho);
+ return -1;
+ }
/* copy any incoming data back out */
if (data_len > 0)
diff --git a/source/smbd/server.c b/source/smbd/server.c
index 8b890549ea3..af39bcb757d 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -250,7 +250,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
set_socket_options(s,"SO_KEEPALIVE");
set_socket_options(s,user_socket_options);
- if (listen(s, 5) == -1) {
+ if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
DEBUG(0,("listen: %s\n",strerror(errno)));
close(s);
return False;
@@ -286,7 +286,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
set_socket_options(s,"SO_KEEPALIVE");
set_socket_options(s,user_socket_options);
- if (listen(s, 5) == -1) {
+ if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
DEBUG(0,("open_sockets_smbd: listen: %s\n",
strerror(errno)));
close(s);
diff --git a/source/smbd/sesssetup.c b/source/smbd/sesssetup.c
index 427caa3ba11..314ffbb4a9b 100644
--- a/source/smbd/sesssetup.c
+++ b/source/smbd/sesssetup.c
@@ -186,7 +186,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
}
*p = 0;
- if (strcasecmp(p+1, lp_realm()) != 0) {
+ if (!strequal(p+1, lp_realm())) {
DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1));
if (!lp_allow_trusted_domains()) {
data_blob_free(&ap_rep);
@@ -198,28 +198,25 @@ static int reply_spnego_kerberos(connection_struct *conn,
/* this gives a fully qualified user name (ie. with full realm).
that leads to very long usernames, but what else can we do? */
- asprintf(&user, "%s%s%s", p+1, lp_winbind_separator(), client);
+
+ asprintf(&user, "%s%c%s", p+1, *lp_winbind_separator(), client);
- pw = Get_Pwnam(user);
- if (!pw && !foreign) {
- pw = Get_Pwnam(client);
- SAFE_FREE(user);
- user = smb_xstrdup(client);
- }
-
+ pw = smb_getpwnam( user );
+
+ SAFE_FREE(user);
SAFE_FREE(client);
- /* setup the string used by %U */
- sub_set_smb_name(user);
-
- reload_services(True);
-
if (!pw) {
DEBUG(1,("Username %s is invalid on this system\n",user));
data_blob_free(&ap_rep);
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
}
+ /* setup the string used by %U */
+
+ sub_set_smb_name(pw->pw_name);
+ reload_services(True);
+
if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info,pw))) {
DEBUG(1,("make_server_info_from_pw failed!\n"));
data_blob_free(&ap_rep);
diff --git a/source/smbd/statcache.c b/source/smbd/statcache.c
index 76406f208e5..d996f5e4938 100644
--- a/source/smbd/statcache.c
+++ b/source/smbd/statcache.c
@@ -119,8 +119,8 @@ void stat_cache_add( const char *full_orig_name, const char *orig_translated_pat
if (original_path_length != translated_path_length) {
if (original_path_length < translated_path_length) {
- DEBUG(0, ("OOPS - tried to store stat cache entry for weird length paths [%s] %u and [%s] %u)!\n",
- original_path, original_path_length, translated_path, translated_path_length));
+ DEBUG(0, ("OOPS - tried to store stat cache entry for weird length paths [%s] %lu and [%s] %lu)!\n",
+ original_path, (unsigned long)original_path_length, translated_path, (unsigned long)translated_path_length));
SAFE_FREE(original_path);
SAFE_FREE(translated_path);
return;
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index 3d53387c9f1..56d1aae3a2a 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -3297,8 +3297,8 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
srvstr_pull(inbuf, pathname, &params[2], sizeof(pathname), -1, STR_TERMINATE);
- if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
- return ERROR_DOS(ERRDOS,ERRbadfile);
+ if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0)
+ return UNIXERROR(ERRDOS,ERRbadfile);
SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
@@ -3319,7 +3319,12 @@ static int call_trans2ioctl(connection_struct *conn, char* inbuf,
{
char *pdata = *ppdata;
files_struct *fsp = file_fsp(inbuf,smb_vwv15);
+
+ /* check for an invalid fid before proceeding */
+ if (!fsp)
+ return(ERROR_DOS(ERRDOS,ERRbadfid));
+
if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
(SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
pdata = Realloc(*ppdata, 32);
@@ -3497,7 +3502,8 @@ int reply_trans2(connection_struct *conn,
unsigned int psoff = SVAL(inbuf, smb_psoff);
if ((psoff + num_params < psoff) || (psoff + num_params < num_params))
goto bad_param;
- if (smb_base(inbuf) + psoff + num_params > inbuf + length)
+ if ((smb_base(inbuf) + psoff + num_params > inbuf + length) ||
+ (smb_base(inbuf) + psoff + num_params < smb_base(inbuf)))
goto bad_param;
memcpy( params, smb_base(inbuf) + psoff, num_params);
}
@@ -3505,7 +3511,8 @@ int reply_trans2(connection_struct *conn,
unsigned int dsoff = SVAL(inbuf, smb_dsoff);
if ((dsoff + num_data < dsoff) || (dsoff + num_data < num_data))
goto bad_param;
- if (smb_base(inbuf) + dsoff + num_data > inbuf + length)
+ if ((smb_base(inbuf) + dsoff + num_data > inbuf + length) ||
+ (smb_base(inbuf) + dsoff + num_data < smb_base(inbuf)))
goto bad_param;
memcpy( data, smb_base(inbuf) + dsoff, num_data);
}
@@ -3566,7 +3573,10 @@ int reply_trans2(connection_struct *conn,
if ((param_disp + num_params < param_disp) ||
(param_disp + num_params < num_params))
goto bad_param;
- if (smb_base(inbuf) + param_off + num_params >= inbuf + bufsize)
+ if (param_disp > total_params)
+ goto bad_param;
+ if ((smb_base(inbuf) + param_off + num_params >= inbuf + bufsize) ||
+ (smb_base(inbuf) + param_off + num_params < smb_base(inbuf)))
goto bad_param;
if (params + param_disp < params)
goto bad_param;
@@ -3579,7 +3589,10 @@ int reply_trans2(connection_struct *conn,
if ((data_disp + num_data < data_disp) ||
(data_disp + num_data < num_data))
goto bad_param;
- if (smb_base(inbuf) + data_off + num_data >= inbuf + bufsize)
+ if (data_disp > total_data)
+ goto bad_param;
+ if ((smb_base(inbuf) + data_off + num_data >= inbuf + bufsize) ||
+ (smb_base(inbuf) + data_off + num_data < smb_base(inbuf)))
goto bad_param;
if (data + data_disp < data)
goto bad_param;
diff --git a/source/smbwrapper/smbw.c b/source/smbwrapper/smbw.c
index 7eb01c7da33..0ddacdf8ba5 100644
--- a/source/smbwrapper/smbw.c
+++ b/source/smbwrapper/smbw.c
@@ -1480,8 +1480,12 @@ say no to acls
st64->st_atime = st->st_atime;
st64->st_mtime = st->st_mtime;
st64->st_ctime = st->st_ctime;
+#ifdef HAVE_STAT_ST_BLKSIZE
st64->st_blksize = st->st_blksize;
+#endif
+#ifdef HAVE_STAT_ST_BLOCKS
st64->st_blocks = st->st_blocks;
+#endif
}
#endif
@@ -1545,8 +1549,12 @@ struct kernel_stat {
st->st_gid = kbuf->st_gid;
st->st_rdev = kbuf->st_rdev;
st->st_size = kbuf->st_size;
+#ifdef HAVE_STAT_ST_BLKSIZE
st->st_blksize = kbuf->st_blksize;
+#endif
+#ifdef HAVE_STAT_ST_BLOCKS
st->st_blocks = kbuf->st_blocks;
+#endif
st->st_atime = kbuf->st_atime_;
st->st_mtime = kbuf->st_mtime_;
st->st_ctime = kbuf->st_ctime_;
diff --git a/source/smbwrapper/smbw_dir.c b/source/smbwrapper/smbw_dir.c
index 6d55c1d9da2..0a6deede41f 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) || (strcasecmp(share,"IPC$") == 0)) {
+ } else if ((strcmp(srv->cli.dev,"IPC") == 0) || (strequal(share,"IPC$"))) {
DEBUG(4,("doing NetShareEnum\n"));
smbw_share_add(".",0,"", NULL);
smbw_share_add("..",0,"", NULL);
@@ -413,7 +413,7 @@ int smbw_chdir(const char *name)
}
if (strncmp(srv->cli.dev,"IPC",3) &&
- strcasecmp(share, "IPC$") &&
+ !strequal(share, "IPC$") &&
strncmp(srv->cli.dev,"LPT",3) &&
!smbw_getatr(srv, path,
&mode, NULL, NULL, NULL, NULL, NULL)) {
diff --git a/source/smbwrapper/smbw_stat.c b/source/smbwrapper/smbw_stat.c
index 6c476a8a67b..bb76ef006a4 100644
--- a/source/smbwrapper/smbw_stat.c
+++ b/source/smbwrapper/smbw_stat.c
@@ -41,8 +41,12 @@ void smbw_setup_stat(struct stat *st, char *fname, size_t size, int mode)
if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR;
st->st_size = size;
+#ifdef HAVE_STAT_ST_BLKSIZE
st->st_blksize = 512;
+#endif
+#ifdef HAVE_STAT_ST_BLOCKS
st->st_blocks = (size+511)/512;
+#endif
st->st_uid = getuid();
st->st_gid = getgid();
if (IS_DOS_DIR(mode)) {
diff --git a/source/tdb/spinlock.c b/source/tdb/spinlock.c
index 2370ce3bdd9..3fddeafb2c1 100644
--- a/source/tdb/spinlock.c
+++ b/source/tdb/spinlock.c
@@ -372,7 +372,7 @@ int tdb_create_rwlocks(int fd, unsigned int hash_size)
unsigned size, i;
tdb_rwlock_t *rwlocks;
- size = (hash_size + 1) * sizeof(tdb_rwlock_t);
+ size = TDB_SPINLOCK_SIZE(hash_size);
rwlocks = malloc(size);
if (!rwlocks)
return -1;
diff --git a/source/tdb/spinlock.h b/source/tdb/spinlock.h
index 8b0e833ff56..967fe37457f 100644
--- a/source/tdb/spinlock.h
+++ b/source/tdb/spinlock.h
@@ -39,6 +39,8 @@ int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type);
int tdb_create_rwlocks(int fd, unsigned int hash_size);
int tdb_clear_spinlocks(TDB_CONTEXT *tdb);
+#define TDB_SPINLOCK_SIZE(hash_size) (((hash_size) + 1) * sizeof(tdb_rwlock_t))
+
#else /* !USE_SPINLOCKS */
#if 0
#define tdb_create_rwlocks(fd, hash_size) 0
@@ -50,6 +52,8 @@ int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type);
int tdb_create_rwlocks(int fd, unsigned int hash_size);
#endif
int tdb_clear_spinlocks(TDB_CONTEXT *tdb);
+#define TDB_SPINLOCK_SIZE(hash_size) 0
+
#endif
#endif
diff --git a/source/tdb/tdb.c b/source/tdb/tdb.c
index f5809ef63ad..c98b0936ed0 100644
--- a/source/tdb/tdb.c
+++ b/source/tdb/tdb.c
@@ -77,6 +77,8 @@
#define TDB_DEAD(r) ((r)->magic == TDB_DEAD_MAGIC)
#define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r))
#define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off))
+#define TDB_DATA_START(hash_size) (TDB_HASH_TOP(hash_size-1) + TDB_SPINLOCK_SIZE(hash_size))
+
/* NB assumes there is a local variable called "tdb" that is the
* current context, also takes doubly-parenthesized print-style
@@ -235,10 +237,15 @@ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset,
tdb->fd, offset, rw_type, lck_type));
}
/* Was it an alarm timeout ? */
- if (errno == EINTR && palarm_fired && *palarm_fired)
+ if (errno == EINTR && palarm_fired && *palarm_fired) {
+ TDB_LOG((tdb, 5, "tdb_brlock timed out (fd=%d) at offset %d rw_type=%d lck_type=%d\n",
+ tdb->fd, offset, rw_type, lck_type));
return TDB_ERRCODE(TDB_ERR_LOCK_TIMEOUT, -1);
+ }
/* Otherwise - generic lock error. */
/* errno set by fcntl */
+ TDB_LOG((tdb, 5, "tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d: %s\n",
+ tdb->fd, offset, rw_type, lck_type, strerror(errno)));
return TDB_ERRCODE(TDB_ERR_LOCK, -1);
}
return 0;
@@ -663,10 +670,10 @@ static int tdb_free(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec)
left:
/* Look left */
left = offset - sizeof(tdb_off);
- if (left > TDB_HASH_TOP(tdb->header.hash_size-1)) {
+ if (left > TDB_DATA_START(tdb->header.hash_size)) {
struct list_struct l;
tdb_off leftsize;
-
+
/* Read in tailer and jump back to header */
if (ofs_read(tdb, left, &leftsize) == -1) {
TDB_LOG((tdb, 0, "tdb_free: left offset read failed at %u\n", left));
diff --git a/source/tdb/tdbtorture.c b/source/tdb/tdbtorture.c
index e27bbff9909..3f704e537ea 100644
--- a/source/tdb/tdbtorture.c
+++ b/source/tdb/tdbtorture.c
@@ -5,6 +5,7 @@
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
+#include <signal.h>
#include <stdarg.h>
#include <sys/mman.h>
#include <sys/stat.h>
diff --git a/source/torture/cmd_vfs.c b/source/torture/cmd_vfs.c
index 8317a57a20d..bfce4b88b41 100644
--- a/source/torture/cmd_vfs.c
+++ b/source/torture/cmd_vfs.c
@@ -522,8 +522,12 @@ static NTSTATUS cmd_stat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
else if (S_ISLNK(st.st_mode)) printf(" Symbolic Link\n");
else if (S_ISSOCK(st.st_mode)) printf(" Socket\n");
printf(" Size: %10u", (unsigned int)st.st_size);
+#ifdef HAVE_STAT_ST_BLOCKS
printf(" Blocks: %9u", (unsigned int)st.st_blocks);
+#endif
+#ifdef HAVE_STAT_ST_BLKSIZE
printf(" IO Block: %u\n", (unsigned int)st.st_blksize);
+#endif
printf(" Device: 0x%10x", (unsigned int)st.st_dev);
printf(" Inode: %10u", (unsigned int)st.st_ino);
printf(" Links: %10u\n", (unsigned int)st.st_nlink);
@@ -586,8 +590,12 @@ static NTSTATUS cmd_fstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
else if (S_ISLNK(st.st_mode)) printf(" Symbolic Link\n");
else if (S_ISSOCK(st.st_mode)) printf(" Socket\n");
printf(" Size: %10u", (unsigned int)st.st_size);
+#ifdef HAVE_STAT_ST_BLOCKS
printf(" Blocks: %9u", (unsigned int)st.st_blocks);
+#endif
+#ifdef HAVE_STAT_ST_BLKSIZE
printf(" IO Block: %u\n", (unsigned int)st.st_blksize);
+#endif
printf(" Device: 0x%10x", (unsigned int)st.st_dev);
printf(" Inode: %10u", (unsigned int)st.st_ino);
printf(" Links: %10u\n", (unsigned int)st.st_nlink);
@@ -638,8 +646,12 @@ static NTSTATUS cmd_lstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
else if (S_ISLNK(st.st_mode)) printf(" Symbolic Link\n");
else if (S_ISSOCK(st.st_mode)) printf(" Socket\n");
printf(" Size: %10u", (unsigned int)st.st_size);
+#ifdef HAVE_STAT_ST_BLOCKS
printf(" Blocks: %9u", (unsigned int)st.st_blocks);
+#endif
+#ifdef HAVE_STAT_ST_BLKSIZE
printf(" IO Block: %u\n", (unsigned int)st.st_blksize);
+#endif
printf(" Device: 0x%10x", (unsigned int)st.st_dev);
printf(" Inode: %10u", (unsigned int)st.st_ino);
printf(" Links: %10u\n", (unsigned int)st.st_nlink);
diff --git a/source/torture/denytest.c b/source/torture/denytest.c
index 3a7906fb33b..89b0fdf93f6 100644
--- a/source/torture/denytest.c
+++ b/source/torture/denytest.c
@@ -1427,7 +1427,7 @@ BOOL torture_denytest1(int dummy)
cli_close(cli1, fnum1);
}
- printf("testing %d entries\n", ARRAY_SIZE(denytable1));
+ printf("testing %ld entries\n", (unsigned long)ARRAY_SIZE(denytable1));
for (i=0; i<ARRAY_SIZE(denytable1); i++) {
enum deny_result res;
diff --git a/source/torture/mangle_test.c b/source/torture/mangle_test.c
index 9a719349b65..f31621b23b7 100644
--- a/source/torture/mangle_test.c
+++ b/source/torture/mangle_test.c
@@ -85,7 +85,7 @@ static BOOL test_one(struct cli_state *cli, const char *name)
data = tdb_fetch_bystring(tdb, shortname);
if (data.dptr) {
/* maybe its a duplicate long name? */
- if (strcasecmp(name, data.dptr) != 0) {
+ if (!strequal(name, data.dptr)) {
/* we have a collision */
collisions++;
printf("Collision between %s and %s -> %s "
diff --git a/source/torture/torture.c b/source/torture/torture.c
index d20c48d6454..bf3f0c6194d 100644
--- a/source/torture/torture.c
+++ b/source/torture/torture.c
@@ -427,9 +427,9 @@ static BOOL rw_torture3(struct cli_state *c, char *lockfname)
sizeof(buf)-count);
if (sent < 0)
{
- printf("read failed offset:%d size:%d (%s)\n",
- count, sizeof(buf)-count,
- cli_errstr(c));
+ printf("read failed offset:%d size:%ld (%s)\n",
+ count, (unsigned long)sizeof(buf)-count,
+ cli_errstr(c));
correct = False;
sent = 0;
}
@@ -438,8 +438,7 @@ static BOOL rw_torture3(struct cli_state *c, char *lockfname)
if (memcmp(buf_rd+count, buf+count, sent) != 0)
{
printf("read/write compare failed\n");
- printf("offset: %d req %d recvd %d\n",
- count, sizeof(buf)-count, sent);
+ printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
correct = False;
break;
}
@@ -504,7 +503,8 @@ static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
printf("read failed (%s)\n", cli_errstr(c2));
- printf("read %d, expected %d\n", bytes_read, buf_size);
+ printf("read %d, expected %ld\n", bytes_read,
+ (unsigned long)buf_size);
correct = False;
break;
}
@@ -620,9 +620,11 @@ static BOOL run_readwritelarge(int dummy)
}
if (fsize == sizeof(buf))
- printf("readwritelarge test 1 succeeded (size = %x)\n", fsize);
+ printf("readwritelarge test 1 succeeded (size = %lx)\n",
+ (unsigned long)fsize);
else {
- printf("readwritelarge test 1 failed (size = %x)\n", fsize);
+ printf("readwritelarge test 1 failed (size = %lx)\n",
+ (unsigned long)fsize);
correct = False;
}
@@ -652,9 +654,11 @@ static BOOL run_readwritelarge(int dummy)
}
if (fsize == sizeof(buf))
- printf("readwritelarge test 2 succeeded (size = %x)\n", fsize);
+ printf("readwritelarge test 2 succeeded (size = %lx)\n",
+ (unsigned long)fsize);
else {
- printf("readwritelarge test 2 failed (size = %x)\n", fsize);
+ printf("readwritelarge test 2 failed (size = %lx)\n",
+ (unsigned long)fsize);
correct = False;
}
diff --git a/source/torture/utable.c b/source/torture/utable.c
index 3ec5932b791..5d819cc6af0 100644
--- a/source/torture/utable.c
+++ b/source/torture/utable.c
@@ -165,8 +165,8 @@ BOOL torture_casetable(int dummy)
int c2[MAX_EQUIVALENCE];
if (size/sizeof(int) >= MAX_EQUIVALENCE) {
- printf("too many chars match?? size=%d c=0x%04x\n",
- size, c);
+ printf("too many chars match?? size=%ld c=0x%04x\n",
+ (unsigned long)size, c);
cli_close(cli, fnum);
return False;
}
diff --git a/source/utils/net.c b/source/utils/net.c
index 42966b4f830..75fa607caef 100644
--- a/source/utils/net.c
+++ b/source/utils/net.c
@@ -72,7 +72,7 @@ const char *opt_container = "cn=Users";
int opt_flags = -1;
int opt_timeout = 0;
const char *opt_target_workgroup = NULL;
-static int opt_machine_pass = 0;
+int opt_machine_pass = 0;
BOOL opt_have_ip = False;
struct in_addr opt_dest_ip;
@@ -84,14 +84,14 @@ uint32 get_sec_channel_type(const char *param)
if (!(param && *param)) {
return get_default_sec_channel();
} else {
- if (strcasecmp(param, "PDC")==0) {
+ if (strequal(param, "PDC")) {
return SEC_CHAN_BDC;
- } else if (strcasecmp(param, "BDC")==0) {
+ } else if (strequal(param, "BDC")) {
return SEC_CHAN_BDC;
- } else if (strcasecmp(param, "MEMBER")==0) {
+ } else if (strequal(param, "MEMBER")) {
return SEC_CHAN_WKSTA;
#if 0
- } else if (strcasecmp(param, "DOMAIN")==0) {
+ } else if (strequal(param, "DOMAIN")) {
return SEC_CHAN_DOMAIN;
#endif
} else {
@@ -130,7 +130,7 @@ NTSTATUS connect_to_ipc(struct cli_state **c, struct in_addr *server_ip,
{
NTSTATUS nt_status;
- if (!opt_password) {
+ if (!opt_password && !opt_machine_pass) {
char *pass = getpass("Password:");
if (pass) {
opt_password = strdup(pass);
diff --git a/source/utils/net.h b/source/utils/net.h
index f83d0169bfd..78c0aad86a7 100644
--- a/source/utils/net.h
+++ b/source/utils/net.h
@@ -48,6 +48,7 @@ extern const char *opt_workgroup;
extern int opt_long_list_entries;
extern int opt_reboot;
extern int opt_force;
+extern int opt_machine_pass;
extern int opt_timeout;
extern const char *opt_host;
extern const char *opt_user_name;
diff --git a/source/utils/net_ads.c b/source/utils/net_ads.c
index 3b955742d84..cad93608dc4 100644
--- a/source/utils/net_ads.c
+++ b/source/utils/net_ads.c
@@ -145,7 +145,7 @@ static ADS_STRUCT *ads_startup(void)
}
retry:
- if (!opt_password && need_password) {
+ if (!opt_password && need_password && !opt_machine_pass) {
char *prompt;
asprintf(&prompt,"%s password: ", opt_user_name);
opt_password = getpass(prompt);
diff --git a/source/utils/net_rpc.c b/source/utils/net_rpc.c
index 85818152d1d..298e8ff6690 100644
--- a/source/utils/net_rpc.c
+++ b/source/utils/net_rpc.c
@@ -1461,7 +1461,7 @@ int net_rpc_file(int argc, const char **argv)
/**
- * ABORT the shutdown of a remote RPC Server
+ * ABORT the shutdown of a remote RPC Server over, initshutdown pipe
*
* All parameters are provided by the run_rpc_command function, except for
* argc, argv which are passed through.
@@ -1476,11 +1476,47 @@ int net_rpc_file(int argc, const char **argv)
* @return Normal NTSTATUS return.
**/
-static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
+static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid,
+ struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ result = cli_shutdown_abort(cli, mem_ctx);
+
+ if (NT_STATUS_IS_OK(result))
+ DEBUG(5,("cmd_shutdown_abort: query succeeded\n"));
+ else
+ DEBUG(5,("cmd_shutdown_abort: query failed\n"));
+
+ return result;
+}
+
+
+/**
+ * ABORT the shutdown of a remote RPC Server, over winreg pipe
+ *
+ * All parameters are provided by the run_rpc_command function, except for
+ * argc, argv which are passed through.
+ *
+ * @param domain_sid The domain sid aquired from the remote server
+ * @param cli A cli_state connected to the server.
+ * @param mem_ctx Talloc context, destoyed on compleation of the function.
+ * @param argc Standard main() style argc
+ * @param argv Standard main() style argv. Initial components are already
+ * stripped
+ *
+ * @return Normal NTSTATUS return.
+ **/
+
+static NTSTATUS rpc_reg_shutdown_abort_internals(const DOM_SID *domain_sid,
+ struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, const char **argv)
+{
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
result = cli_reg_abort_shutdown(cli, mem_ctx);
if (NT_STATUS_IS_OK(result))
@@ -1491,7 +1527,6 @@ static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid, struct c
return result;
}
-
/**
* ABORT the Shut down of a remote RPC server
*
@@ -1504,7 +1539,17 @@ static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid, struct c
static int rpc_shutdown_abort(int argc, const char **argv)
{
- return run_rpc_command(NULL, PI_WINREG, 0, rpc_shutdown_abort_internals,
+ int rc = run_rpc_command(NULL, PI_SHUTDOWN, 0,
+ rpc_shutdown_abort_internals,
+ argc, argv);
+
+ if (rc == 0)
+ return rc;
+
+ DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n"));
+
+ return run_rpc_command(NULL, PI_WINREG, 0,
+ rpc_reg_shutdown_abort_internals,
argc, argv);
}
diff --git a/source/utils/net_rpc_samsync.c b/source/utils/net_rpc_samsync.c
index 64f2d3f68f9..d1c8300a497 100644
--- a/source/utils/net_rpc_samsync.c
+++ b/source/utils/net_rpc_samsync.c
@@ -182,6 +182,9 @@ static void dump_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret
result = cli_netlogon_sam_sync(cli, mem_ctx, ret_creds, db_type,
sync_context,
&num_deltas, &hdr_deltas, &deltas);
+ if (NT_STATUS_IS_ERR(result))
+ break;
+
clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), ret_creds);
for (i = 0; i < num_deltas; i++) {
display_sam_entry(&hdr_deltas[i], &deltas[i]);
diff --git a/source/utils/ntlm_auth.c b/source/utils/ntlm_auth.c
index 7cd7e0b0875..13b9550347d 100644
--- a/source/utils/ntlm_auth.c
+++ b/source/utils/ntlm_auth.c
@@ -1984,8 +1984,8 @@ enum {
if ((challenge_len = strhex_to_str(challenge,
strlen(hex_challenge),
hex_challenge)) != 8) {
- x_fprintf(x_stderr, "hex decode of %s failed (only got %u bytes)!\n",
- hex_challenge, challenge_len);
+ x_fprintf(x_stderr, "hex decode of %s failed (only got %lu bytes)!\n",
+ hex_challenge, (unsigned long)challenge_len);
exit(1);
}
opt_challenge = data_blob(challenge, challenge_len);
diff --git a/source/utils/profiles.c b/source/utils/profiles.c
index 20b1222e723..a31674dfb2e 100644
--- a/source/utils/profiles.c
+++ b/source/utils/profiles.c
@@ -614,6 +614,7 @@ int main(int argc, char *argv[])
base = mmap(&start, sbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
#else
base = (char *)-1;
+ errno = ENOSYS;
#endif
if ((int)base == -1) {
diff --git a/source/utils/smbcontrol.c b/source/utils/smbcontrol.c
index 190627e2a52..eae1f97b58b 100644
--- a/source/utils/smbcontrol.c
+++ b/source/utils/smbcontrol.c
@@ -203,7 +203,8 @@ static void profilelevel_cb(int msg_type, pid_t pid, void *buf, size_t len)
num_replies++;
if (len != sizeof(int)) {
- fprintf(stderr, "invalid message length %d returned\n", len);
+ fprintf(stderr, "invalid message length %ld returned\n",
+ (unsigned long)len);
return;
}
diff --git a/source/utils/smbcquotas.c b/source/utils/smbcquotas.c
index 64321d5bfc3..0bd87554209 100644
--- a/source/utils/smbcquotas.c
+++ b/source/utils/smbcquotas.c
@@ -140,7 +140,7 @@ static int parse_quota_set(pstring set_str, pstring username_str, enum SMB_QUOTA
BOOL enable = False;
BOOL deny = False;
- if (strncasecmp(set_str,"UQLIM:",6)==0) {
+ if (strnequal(set_str,"UQLIM:",6)) {
p += 6;
*qtype = SMB_USER_QUOTA_TYPE;
*cmd = QUOTA_SETLIM;
@@ -154,12 +154,12 @@ static int parse_quota_set(pstring set_str, pstring username_str, enum SMB_QUOTA
fstrcpy(username_str,p);
p = p2;
- } else if (strncasecmp(set_str,"FSQLIM:",7)==0) {
+ } else if (strnequal(set_str,"FSQLIM:",7)) {
p +=7;
*qtype = SMB_USER_FS_QUOTA_TYPE;
*cmd = QUOTA_SETLIM;
todo = PARSE_LIM;
- } else if (strncasecmp(set_str,"FSQFLAGS:",9)==0) {
+ } else if (strnequal(set_str,"FSQFLAGS:",9)) {
p +=9;
todo = PARSE_FLAGS;
*qtype = SMB_USER_FS_QUOTA_TYPE;
@@ -189,13 +189,13 @@ static int parse_quota_set(pstring set_str, pstring username_str, enum SMB_QUOTA
p2++;
}
- if (strncasecmp(p,"QUOTA_ENABLED",13)==0) {
+ if (strnequal(p,"QUOTA_ENABLED",13)) {
enable = True;
- } else if (strncasecmp(p,"DENY_DISK",9)==0) {
+ } else if (strnequal(p,"DENY_DISK",9)) {
deny = True;
- } else if (strncasecmp(p,"LOG_SOFTLIMIT",13)==0) {
+ } else if (strnequal(p,"LOG_SOFTLIMIT",13)) {
pqt->qflags |= QUOTAS_LOG_THRESHOLD;
- } else if (strncasecmp(p,"LOG_HARDLIMIT",13)==0) {
+ } else if (strnequal(p,"LOG_HARDLIMIT",13)) {
pqt->qflags |= QUOTAS_LOG_LIMIT;
} else {
return -1;
diff --git a/source/utils/smbfilter.c b/source/utils/smbfilter.c
index 1a0d639f025..5d67c8fc7cf 100644
--- a/source/utils/smbfilter.c
+++ b/source/utils/smbfilter.c
@@ -47,7 +47,7 @@ static void save_file(const char *fname, void *packet, size_t length)
return;
}
close(fd);
- printf("Wrote %d bytes to %s\n", length, fname);
+ printf("Wrote %ld bytes to %s\n", (unsigned long)length, fname);
}
static void filter_reply(char *buf)
diff --git a/source/utils/testparm.c b/source/utils/testparm.c
index 085156305b1..a74c2eaa973 100644
--- a/source/utils/testparm.c
+++ b/source/utils/testparm.c
@@ -47,28 +47,28 @@ static int do_global_checks(void)
SMB_STRUCT_STAT st;
if (lp_security() >= SEC_DOMAIN && !lp_encrypted_passwords()) {
- printf("ERROR: in 'security=domain' mode the 'encrypt passwords' parameter must always be set to 'true'.\n");
+ fprintf(stderr, "ERROR: in 'security=domain' mode the 'encrypt passwords' parameter must always be set to 'true'.\n");
ret = 1;
}
if (lp_wins_support() && lp_wins_server_list()) {
- printf("ERROR: both 'wins support = true' and 'wins server = <server list>' \
+ fprintf(stderr, "ERROR: both 'wins support = true' and 'wins server = <server list>' \
cannot be set in the smb.conf file. nmbd will abort with this setting.\n");
ret = 1;
}
if (!directory_exist(lp_lockdir(), &st)) {
- printf("ERROR: lock directory %s does not exist\n",
+ fprintf(stderr, "ERROR: lock directory %s does not exist\n",
lp_lockdir());
ret = 1;
} else if ((st.st_mode & 0777) != 0755) {
- printf("WARNING: lock directory %s should have permissions 0755 for browsing to work\n",
+ fprintf(stderr, "WARNING: lock directory %s should have permissions 0755 for browsing to work\n",
lp_lockdir());
ret = 1;
}
if (!directory_exist(lp_piddir(), &st)) {
- printf("ERROR: pid directory %s does not exist\n",
+ fprintf(stderr, "ERROR: pid directory %s does not exist\n",
lp_piddir());
ret = 1;
}
@@ -84,7 +84,7 @@ cannot be set in the smb.conf file. nmbd will abort with this setting.\n");
else if(lp_security() == SEC_DOMAIN)
pstrcpy(sec_setting, "domain");
- printf("ERROR: The setting 'security=%s' requires the 'password server' parameter be set \
+ fprintf(stderr, "ERROR: The setting 'security=%s' requires the 'password server' parameter be set \
to a valid password server.\n", sec_setting );
ret = 1;
}
@@ -95,7 +95,7 @@ to a valid password server.\n", sec_setting );
*/
if(*lp_hosts_equiv() && !lp_hostname_lookups()) {
- printf("ERROR: The setting 'hosts equiv = %s' requires that 'hostname lookups = yes'.\n", lp_hosts_equiv());
+ fprintf(stderr, "ERROR: The setting 'hosts equiv = %s' requires that 'hostname lookups = yes'.\n", lp_hosts_equiv());
ret = 1;
}
@@ -114,7 +114,7 @@ to a valid password server.\n", sec_setting );
#endif
if(lp_passwd_program() == NULL) {
- printf("ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd program' \
+ fprintf( stderr, "ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd program' \
parameter.\n" );
ret = 1;
} else {
@@ -128,7 +128,7 @@ parameter.\n" );
next_token(&p, truncated_prog, NULL, sizeof(pstring));
if(access(truncated_prog, F_OK) == -1) {
- printf("ERROR: the 'unix password sync' parameter is set and the 'passwd program' (%s) \
+ fprintf(stderr, "ERROR: the 'unix password sync' parameter is set and the 'passwd program' (%s) \
cannot be executed (error was %s).\n", truncated_prog, strerror(errno) );
ret = 1;
}
@@ -139,7 +139,7 @@ cannot be executed (error was %s).\n", truncated_prog, strerror(errno) );
#endif
if(lp_passwd_chat() == NULL) {
- printf("ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd chat' \
+ fprintf(stderr, "ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd chat' \
parameter.\n");
ret = 1;
}
@@ -151,7 +151,7 @@ parameter.\n");
if(lp_encrypted_passwords()) {
if(strstr( lp_passwd_chat(), "%o")!=NULL) {
- printf("ERROR: the 'passwd chat' script [%s] expects to use the old plaintext password \
+ fprintf(stderr, "ERROR: the 'passwd chat' script [%s] expects to use the old plaintext password \
via the %%o substitution. With encrypted passwords this is not possible.\n", lp_passwd_chat() );
ret = 1;
}
@@ -159,32 +159,32 @@ via the %%o substitution. With encrypted passwords this is not possible.\n", lp_
}
if (strlen(lp_winbind_separator()) != 1) {
- printf("ERROR: the 'winbind separator' parameter must be a single character.\n");
+ fprintf(stderr,"ERROR: the 'winbind separator' parameter must be a single character.\n");
ret = 1;
}
if (*lp_winbind_separator() == '+') {
- printf("'winbind separator = +' might cause problems with group membership.\n");
+ fprintf(stderr,"'winbind separator = +' might cause problems with group membership.\n");
}
if (lp_algorithmic_rid_base() < BASE_RID) {
/* Try to prevent admin foot-shooting, we can't put algorithmic
rids below 1000, that's the 'well known RIDs' on NT */
- printf("'algorithmic rid base' must be equal to or above %lu\n", BASE_RID);
+ fprintf(stderr,"'algorithmic rid base' must be equal to or above %lu\n", BASE_RID);
}
if (lp_algorithmic_rid_base() & 1) {
- printf("'algorithmic rid base' must be even.\n");
+ fprintf(stderr,"'algorithmic rid base' must be even.\n");
}
#ifndef HAVE_DLOPEN
if (lp_preload_modules()) {
- printf("WARNING: 'preload modules = ' set while loading plugins not supported.\n");
+ fprintf(stderr,"WARNING: 'preload modules = ' set while loading plugins not supported.\n");
}
#endif
if (!lp_passdb_backend()) {
- printf("ERROR: passdb backend must have a value or be left out\n");
+ fprintf(stderr,"ERROR: passdb backend must have a value or be left out\n");
}
return ret;
@@ -236,27 +236,27 @@ via the %%o substitution. With encrypted passwords this is not possible.\n", lp_
set_local_machine_name(new_local_machine, True);
}
- dbf = x_stdout;
+ dbf = x_stderr;
DEBUGLEVEL = 2;
AllowDebugChange = False;
- printf("Load smb config files from %s\n",config_file);
+ fprintf(stderr,"Load smb config files from %s\n",config_file);
if (!lp_load(config_file,False,True,False)) {
- printf("Error loading services.\n");
+ fprintf(stderr,"Error loading services.\n");
return(1);
}
- printf("Loaded services file OK.\n");
+ fprintf(stderr,"Loaded services file OK.\n");
ret = do_global_checks();
for (s=0;s<1000;s++) {
if (VALID_SNUM(s))
if (strlen(lp_servicename(s)) > 12) {
- printf( "WARNING: You have some share names that are longer than 12 characters.\n" );
- printf( "These may not be accessible to some older clients.\n" );
- printf( "(Eg. Windows9x, WindowsMe, and smbclient prior to Samba 3.0.)\n" );
+ fprintf(stderr, "WARNING: You have some share names that are longer than 12 characters.\n" );
+ fprintf(stderr, "These may not be accessible to some older clients.\n" );
+ fprintf(stderr, "(Eg. Windows9x, WindowsMe, and smbclient prior to Samba 3.0.)\n" );
break;
}
}
@@ -271,7 +271,7 @@ via the %%o substitution. With encrypted passwords this is not possible.\n", lp_
char *hasstar = strchr_m(deny_list[i], '*');
char *hasquery = strchr_m(deny_list[i], '?');
if(hasstar || hasquery) {
- printf("Invalid character %c in hosts deny list (%s) for service %s.\n",
+ fprintf(stderr,"Invalid character %c in hosts deny list (%s) for service %s.\n",
hasstar ? *hasstar : *hasquery, deny_list[i], lp_servicename(s) );
}
}
@@ -282,35 +282,35 @@ via the %%o substitution. With encrypted passwords this is not possible.\n", lp_
char *hasstar = strchr_m(allow_list[i], '*');
char *hasquery = strchr_m(allow_list[i], '?');
if(hasstar || hasquery) {
- printf("Invalid character %c in hosts allow list (%s) for service %s.\n",
+ fprintf(stderr,"Invalid character %c in hosts allow list (%s) for service %s.\n",
hasstar ? *hasstar : *hasquery, allow_list[i], lp_servicename(s) );
}
}
}
if(lp_level2_oplocks(s) && !lp_oplocks(s)) {
- printf("Invalid combination of parameters for service %s. \
+ fprintf(stderr,"Invalid combination of parameters for service %s. \
Level II oplocks can only be set if oplocks are also set.\n",
lp_servicename(s) );
}
if (lp_map_hidden(s) && !(lp_create_mask(s) & S_IXOTH)) {
- printf("Invalid combination of parameters for service %s. \
+ fprintf(stderr,"Invalid combination of parameters for service %s. \
Map hidden can only work if create mask includes octal 01 (S_IXOTH).\n",
lp_servicename(s) );
}
if (lp_map_hidden(s) && (lp_force_create_mode(s) & S_IXOTH)) {
- printf("Invalid combination of parameters for service %s. \
+ fprintf(stderr,"Invalid combination of parameters for service %s. \
Map hidden can only work if force create mode excludes octal 01 (S_IXOTH).\n",
lp_servicename(s) );
}
if (lp_map_system(s) && !(lp_create_mask(s) & S_IXGRP)) {
- printf("Invalid combination of parameters for service %s. \
+ fprintf(stderr,"Invalid combination of parameters for service %s. \
Map system can only work if create mask includes octal 010 (S_IXGRP).\n",
lp_servicename(s) );
}
if (lp_map_system(s) && (lp_force_create_mode(s) & S_IXGRP)) {
- printf("Invalid combination of parameters for service %s. \
+ fprintf(stderr,"Invalid combination of parameters for service %s. \
Map system can only work if force create mode excludes octal 010 (S_IXGRP).\n",
lp_servicename(s) );
}
@@ -319,29 +319,29 @@ via the %%o substitution. With encrypted passwords this is not possible.\n", lp_
if (!silent_mode) {
- printf("Server role: ");
+ fprintf(stderr,"Server role: ");
switch(lp_server_role()) {
case ROLE_STANDALONE:
- printf("ROLE_STANDALONE\n");
+ fprintf(stderr,"ROLE_STANDALONE\n");
break;
case ROLE_DOMAIN_MEMBER:
- printf("ROLE_DOMAIN_MEMBER\n");
+ fprintf(stderr,"ROLE_DOMAIN_MEMBER\n");
break;
case ROLE_DOMAIN_BDC:
- printf("ROLE_DOMAIN_BDC\n");
+ fprintf(stderr,"ROLE_DOMAIN_BDC\n");
break;
case ROLE_DOMAIN_PDC:
- printf("ROLE_DOMAIN_PDC\n");
+ fprintf(stderr,"ROLE_DOMAIN_PDC\n");
break;
default:
- printf("Unknown -- internal error?\n");
+ fprintf(stderr,"Unknown -- internal error?\n");
break;
}
}
if (!cname) {
if (!silent_mode) {
- printf("Press enter to see a dump of your service definitions\n");
+ fprintf(stderr,"Press enter to see a dump of your service definitions\n");
fflush(stdout);
getc(stdin);
}
@@ -354,10 +354,10 @@ via the %%o substitution. With encrypted passwords this is not possible.\n", lp_
if (VALID_SNUM(s)) {
if (allow_access(lp_hostsdeny(-1), lp_hostsallow(-1), cname, caddr)
&& allow_access(lp_hostsdeny(s), lp_hostsallow(s), cname, caddr)) {
- printf("Allow connection from %s (%s) to %s\n",
+ fprintf(stderr,"Allow connection from %s (%s) to %s\n",
cname,caddr,lp_servicename(s));
} else {
- printf("Deny connection from %s (%s) to %s\n",
+ fprintf(stderr,"Deny connection from %s (%s) to %s\n",
cname,caddr,lp_servicename(s));
}
}
diff --git a/source/web/cgi.c b/source/web/cgi.c
index 212c2884b60..6778e596569 100644
--- a/source/web/cgi.c
+++ b/source/web/cgi.c
@@ -114,7 +114,7 @@ void cgi_load_variables(void)
if (len > 0 &&
(request_post ||
((s=getenv("REQUEST_METHOD")) &&
- strcasecmp(s,"POST")==0))) {
+ strequal(s,"POST")))) {
while (len && (line=grab_line(f, &len))) {
p = strchr_m(line,'=');
if (!p) continue;
@@ -224,9 +224,9 @@ static void cgi_setup_error(const char *err, const char *header, const char *inf
/* damn browsers don't like getting cut off before they give a request */
char line[1024];
while (fgets(line, sizeof(line)-1, stdin)) {
- if (strncasecmp(line,"GET ", 4)==0 ||
- strncasecmp(line,"POST ", 5)==0 ||
- strncasecmp(line,"PUT ", 4)==0) {
+ if (strnequal(line,"GET ", 4) ||
+ strnequal(line,"POST ", 5) ||
+ strnequal(line,"PUT ", 4)) {
break;
}
}
@@ -301,7 +301,7 @@ static BOOL cgi_handle_authorization(char *line)
fstring user, user_pass;
struct passwd *pass = NULL;
- if (strncasecmp(line,"Basic ", 6)) {
+ if (!strnequal(line,"Basic ", 6)) {
goto err;
}
line += 6;
@@ -342,6 +342,9 @@ static BOOL cgi_handle_authorization(char *line)
* Password was ok.
*/
+ if ( initgroups(pass->pw_name, pass->pw_gid) != 0 )
+ goto err;
+
become_user_permanently(pass->pw_uid, pass->pw_gid);
/* Save the users name */
@@ -486,22 +489,22 @@ void cgi_setup(const char *rootdir, int auth_required)
and handle authentication etc */
while (fgets(line, sizeof(line)-1, stdin)) {
if (line[0] == '\r' || line[0] == '\n') break;
- if (strncasecmp(line,"GET ", 4)==0) {
+ if (strnequal(line,"GET ", 4)) {
got_request = True;
url = strdup(&line[4]);
- } else if (strncasecmp(line,"POST ", 5)==0) {
+ } else if (strnequal(line,"POST ", 5)) {
got_request = True;
request_post = 1;
url = strdup(&line[5]);
- } else if (strncasecmp(line,"PUT ", 4)==0) {
+ } else if (strnequal(line,"PUT ", 4)) {
got_request = True;
cgi_setup_error("400 Bad Request", "",
"This server does not accept PUT requests");
- } else if (strncasecmp(line,"Authorization: ", 15)==0) {
+ } else if (strnequal(line,"Authorization: ", 15)) {
authenticated = cgi_handle_authorization(&line[15]);
- } else if (strncasecmp(line,"Content-Length: ", 16)==0) {
+ } else if (strnequal(line,"Content-Length: ", 16)) {
content_length = atoi(&line[16]);
- } else if (strncasecmp(line,"Accept-Language: ", 17)==0) {
+ } else if (strnequal(line,"Accept-Language: ", 17)) {
web_set_lang(&line[17]);
}
/* ignore all other requests! */