diff options
author | Gerald Carter <jerry@samba.org> | 2003-11-07 15:52:30 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2003-11-07 15:52:30 +0000 |
commit | 16609b588b9703f9e12a0b6252dc31bfa9911b99 (patch) | |
tree | 3f7212610daef334f063a424e49036dba763e853 /source | |
parent | 53d8dfad13e2063ee1161ad4e8ff98683725cbdf (diff) | |
download | samba-16609b588b9703f9e12a0b6252dc31bfa9911b99.tar.gz |
syncing tree with SAMBA_3_0
Diffstat (limited to 'source')
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, ¶ms[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! */ |