From a834a73e341059be154426390304a42e4a011f72 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Sep 2002 15:19:00 +0000 Subject: [PATCH] sync'ing up for 3.0alpha20 release (This used to be commit 65e7b5273bb58802bf0c389b77f7fcae0a1f6139) --- source3/CodingSuggestions | 2 +- source3/Makefile.in | 189 +- source3/acconfig.h | 11 +- source3/auth/auth_builtin.c | 11 +- source3/auth/auth_domain.c | 7 +- source3/auth/auth_sam.c | 19 +- source3/auth/auth_server.c | 6 +- source3/auth/auth_util.c | 647 ++++-- source3/auth/auth_winbind.c | 2 +- source3/client/client.c | 155 +- source3/client/smbmnt.c | 4 +- source3/configure | 2276 +++++++++++++-------- source3/configure.in | 368 +++- source3/groupdb/aliasdb.c | 4 +- source3/groupdb/groupdb.c | 4 +- source3/groupdb/mapping.c | 54 +- source3/include/ads.h | 130 +- source3/include/asn_1.h | 1 + source3/include/client.h | 1 + source3/include/config.h.in | 16 + source3/include/debug.h | 7 +- source3/include/doserr.h | 13 +- source3/include/includes.h | 44 +- source3/include/libsmbclient.h | 2 +- source3/include/local.h | 7 +- source3/include/messages.h | 8 + source3/include/nt_printing.h | 17 +- source3/include/printing.h | 1 + source3/include/rpc_netlogon.h | 193 +- source3/include/rpc_spoolss.h | 4 +- source3/include/smb.h | 100 +- source3/include/smb_acls.h | 3 - source3/include/smb_macros.h | 18 +- source3/include/smbprofile.h | 5 +- source3/include/trans2.h | 21 +- source3/include/version.h | 2 +- source3/include/vfs.h | 7 +- source3/lib/account_pol.c | 4 +- source3/lib/charcnv.c | 10 +- source3/lib/debug.c | 18 +- source3/lib/error.c | 3 + source3/lib/messages.c | 94 +- source3/lib/popt_common.c | 4 +- source3/lib/readline.c | 18 + source3/lib/server_mutex.c | 5 +- source3/lib/substitute.c | 22 +- source3/lib/system.c | 15 +- source3/lib/system_smbd.c | 11 +- source3/lib/time.c | 6 + source3/lib/username.c | 57 - source3/lib/util.c | 106 +- source3/lib/util_seaccess.c | 62 +- source3/lib/util_sid.c | 24 +- source3/lib/util_sock.c | 7 +- source3/lib/util_unistr.c | 10 + source3/lib/xfile.c | 34 + source3/libads/ads_status.c | 48 +- source3/libads/kerberos.c | 8 +- source3/libads/krb5_setpw.c | 14 +- source3/libads/ldap.c | 94 +- source3/libads/ldap_printer.c | 2 +- source3/libads/sasl.c | 254 ++- source3/libads/util.c | 2 +- source3/libsmb/asn1.c | 21 +- source3/libsmb/cliconnect.c | 279 +-- source3/libsmb/clientgen.c | 144 +- source3/libsmb/clierror.c | 4 +- source3/libsmb/clifile.c | 2 +- source3/libsmb/clikrb5.c | 23 +- source3/libsmb/clilist.c | 48 +- source3/libsmb/clireadwrite.c | 2 +- source3/libsmb/clispnego.c | 92 +- source3/libsmb/libsmb_cache.c | 4 +- source3/libsmb/libsmbclient.c | 12 +- source3/libsmb/namecache.c | 53 +- source3/libsmb/nterr.c | 2 +- source3/libsmb/smbencrypt.c | 60 +- source3/libsmb/trust_passwd.c | 5 +- source3/locking/locking.c | 2 +- source3/nmbd/nmbd_processlogon.c | 3 +- source3/nmbd/nmbd_synclists.c | 6 +- source3/nsswitch/pam_winbind.c | 21 +- source3/nsswitch/pam_winbind.h | 3 +- source3/nsswitch/wb_common.c | 78 +- source3/nsswitch/wbinfo.c | 104 +- source3/nsswitch/winbind_nss.c | 14 +- source3/nsswitch/winbind_nss_config.h | 12 + source3/nsswitch/winbindd.c | 5 +- source3/nsswitch/winbindd_ads.c | 8 +- source3/nsswitch/winbindd_cm.c | 44 +- source3/nsswitch/winbindd_nss.h | 3 + source3/nsswitch/winbindd_pam.c | 6 +- source3/nsswitch/winbindd_rpc.c | 5 +- source3/nsswitch/winbindd_util.c | 10 +- source3/pam_smbpass/pam_smb_passwd.c | 9 +- source3/param/loadparm.c | 502 +++-- source3/passdb/machine_sid.c | 11 +- source3/passdb/passdb.c | 70 +- source3/passdb/pdb_get_set.c | 25 +- source3/passdb/pdb_interface.c | 5 +- source3/passdb/pdb_ldap.c | 290 +-- source3/passdb/pdb_nisplus.c | 2493 ++++++++++++----------- source3/passdb/pdb_plugin.c | 4 +- source3/passdb/pdb_smbpasswd.c | 13 +- source3/passdb/secrets.c | 94 +- source3/printing/notify.c | 120 +- source3/printing/nt_printing.c | 615 ++++-- source3/printing/print_cups.c | 8 +- source3/printing/printfsp.c | 2 +- source3/printing/printing.c | 427 +++- source3/profile/profile.c | 10 + source3/registry/reg_frontend.c | 315 --- source3/registry/reg_printing.c | 140 +- source3/rpc_client/cli_netlogon.c | 152 +- source3/rpc_client/cli_pipe.c | 2 +- source3/rpc_client/cli_spoolss.c | 283 ++- source3/rpc_client/cli_spoolss_notify.c | 3 + source3/rpc_parse/parse_misc.c | 3 - source3/rpc_parse/parse_net.c | 284 +-- source3/rpc_parse/parse_prs.c | 8 +- source3/rpc_parse/parse_reg.c | 76 +- source3/rpc_parse/parse_spoolss.c | 149 +- source3/rpc_parse/parse_srv.c | 6 +- source3/rpc_server/srv_lsa_nt.c | 2 + source3/rpc_server/srv_netlog_nt.c | 4 +- source3/rpc_server/srv_pipe.c | 38 +- source3/rpc_server/srv_reg_nt.c | 14 +- source3/rpc_server/srv_samr_nt.c | 131 +- source3/rpc_server/srv_spoolss_nt.c | 1898 ++++++++++------- source3/rpc_server/srv_srvsvc_nt.c | 6 +- source3/rpcclient/cmd_lsarpc.c | 11 +- source3/rpcclient/cmd_netlogon.c | 39 +- source3/rpcclient/cmd_spoolss.c | 39 +- source3/rpcclient/rpcclient.c | 66 +- source3/rpcclient/samsync.c | 30 +- source3/smbd/blocking.c | 34 +- source3/smbd/conn.c | 24 +- source3/smbd/connection.c | 84 +- source3/smbd/dir.c | 121 +- source3/smbd/filename.c | 2 +- source3/smbd/mangle_hash.c | 2 +- source3/smbd/mangle_hash2.c | 16 +- source3/smbd/negprot.c | 14 +- source3/smbd/nttrans.c | 108 +- source3/smbd/open.c | 65 +- source3/smbd/password.c | 162 +- source3/smbd/posix_acls.c | 30 +- source3/smbd/process.c | 288 +-- source3/smbd/reply.c | 547 +++-- source3/smbd/sec_ctx.c | 13 +- source3/smbd/server.c | 10 +- source3/smbd/service.c | 39 +- source3/smbd/sesssetup.c | 40 +- source3/smbd/trans2.c | 69 +- source3/smbd/uid.c | 42 +- source3/smbd/vfs-wrap.c | 15 + source3/smbd/vfs.c | 9 +- source3/tdb/spinlock.c | 1 + source3/tdb/tdb.c | 18 + source3/tdb/tdb.h | 1 + source3/tdb/tdbbackup.c | 1 + source3/tdb/tdbdump.c | 1 + source3/tdb/tdbtest.c | 1 + source3/tdb/tdbtool.c | 1 + source3/torture/torture.c | 155 +- source3/utils/net.c | 76 +- source3/utils/net_ads.c | 50 +- source3/utils/net_help.c | 5 +- source3/utils/net_rpc.c | 105 +- source3/utils/net_rpc_join.c | 3 +- source3/utils/pdbedit.c | 13 +- source3/utils/smbcontrol.c | 5 + source3/utils/smbpasswd.c | 36 +- source3/utils/status.c | 6 + source3/utils/testparm.c | 12 +- source3/web/swat.c | 343 +++- 176 files changed, 10966 insertions(+), 6364 deletions(-) diff --git a/source3/CodingSuggestions b/source3/CodingSuggestions index e5f366ec710..5e99bc54cae 100644 --- a/source3/CodingSuggestions +++ b/source3/CodingSuggestions @@ -29,7 +29,7 @@ programmers who have contributed. The indent utility can be used to format C files in the general samba coding style. The arguments you should give to indent are: --bad -bap -br -ce -cdw -nbc -brs -bbb -nbc -npsl +-bad -bap -br -ce -cdw -nbc -brs -bbb -nbc -npsl -ut -i8 Following are some considerations you should use when adding new code to Samba. First and foremost remember that: diff --git a/source3/Makefile.in b/source3/Makefile.in index 2db6d550113..f3d9b7ec099 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -18,9 +18,11 @@ LDFLAGS=@LDFLAGS@ LDSHFLAGS=@LDSHFLAGS@ @LDFLAGS@ @CFLAGS@ AWK=@AWK@ DYNEXP=@DYNEXP@ +PYTHON=@PYTHON@ TERMLDFLAGS=@TERMLDFLAGS@ TERMLIBS=@TERMLIBS@ +PRINTLIBS=@PRINTLIBS@ LINK=$(CC) $(FLAGS) $(LDFLAGS) @@ -106,7 +108,7 @@ LPROGS = $(WINBIND_PAM_PROGS) $(WINBIND_LPROGS) PROGS = $(PROGS1) $(PROGS2) $(MPROGS) bin/nmblookup bin/pdbedit bin/smbgroupedit TORTURE_PROGS = bin/smbtorture bin/msgtest bin/masktest bin/locktest \ - bin/locktest2 bin/nsstest + bin/locktest2 bin/nsstest bin/vfstest SHLIBS = @LIBSMBCLIENT@ SCRIPTS = $(srcdir)/script/smbtar $(srcdir)/script/addtosmbpass $(srcdir)/script/convert_smbpasswd \ @@ -124,7 +126,7 @@ TDB_OBJ = $(TDBBASE_OBJ) tdb/tdbutil.o LIB_OBJ = lib/charcnv.o lib/debug.o lib/fault.o \ lib/getsmbpass.o lib/interface.o lib/md4.o \ lib/interfaces.o lib/pidfile.o lib/replace.o \ - lib/signal.o lib/system.o lib/time.o \ + lib/signal.o lib/system.o lib/sendfile.o lib/time.o \ lib/ufc.o lib/genrand.o lib/username.o \ lib/util_getent.o lib/util_pw.o lib/access.o lib/smbrun.o \ lib/bitmap.o lib/crc32.o lib/snprintf.o lib/dprintf.o \ @@ -134,11 +136,11 @@ LIB_OBJ = lib/charcnv.o lib/debug.o lib/fault.o \ lib/util.o lib/util_sock.o lib/util_sec.o \ lib/talloc.o lib/hash.o lib/substitute.o lib/fsusage.o \ lib/ms_fnmatch.o lib/select.o lib/error.o lib/messages.o \ - lib/server_mutex.o lib/tallocmsg.o lib/dmallocmsg.o \ + lib/tallocmsg.o lib/dmallocmsg.o \ lib/md5.o lib/hmacmd5.o lib/iconv.o lib/smbpasswd.o \ nsswitch/wb_client.o nsswitch/wb_common.o \ lib/pam_errors.o intl/lang_tdb.o lib/account_pol.o \ - lib/adt_tree.o lib/popt_common.o $(TDB_OBJ) + lib/adt_tree.o lib/popt_common.o lib/gencache.o $(TDB_OBJ) LIB_SMBD_OBJ = lib/system_smbd.o lib/util_smbd.o @@ -152,7 +154,7 @@ PARAM_OBJ = param/loadparm.o param/params.o dynconfig.o LIBADS_OBJ = libads/ldap.o libads/ldap_printer.o libads/sasl.o \ libads/krb5_setpw.o libads/kerberos.o libads/ldap_user.o \ libads/ads_struct.o libads/ads_status.o \ - libads/disp_sec.o + libads/disp_sec.o libads/ads_utils.o LIBADS_SERVER_OBJ = libads/util.o libads/kerberos_verify.o @@ -180,8 +182,9 @@ LIBMSRPC_SERVER_OBJ = libsmb/trust_passwd.o LIBMSRPC_PICOBJ = $(LIBMSRPC_OBJ:.o=.po) +REGOBJS_OBJ = registry/reg_objects.o REGISTRY_OBJ = registry/reg_frontend.o registry/reg_cachehook.o registry/reg_printing.o \ - registry/reg_db.o + registry/reg_db.o RPC_SERVER_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o \ rpc_server/srv_lsa_hnd.o rpc_server/srv_netlog.o rpc_server/srv_netlog_nt.o \ @@ -190,7 +193,7 @@ RPC_SERVER_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o \ rpc_server/srv_srvsvc.o rpc_server/srv_srvsvc_nt.o \ rpc_server/srv_util.o rpc_server/srv_wkssvc.o rpc_server/srv_wkssvc_nt.o \ rpc_server/srv_pipe.o rpc_server/srv_dfs.o rpc_server/srv_dfs_nt.o \ - rpc_server/srv_spoolss.o rpc_server/srv_spoolss_nt.o $(REGISTRY_OBJ) + rpc_server/srv_spoolss.o rpc_server/srv_spoolss_nt.o # this includes only the low level parse code, not stuff # that requires knowledge of security contexts @@ -201,7 +204,8 @@ RPC_PARSE_OBJ = rpc_parse/parse_lsa.o rpc_parse/parse_net.o \ rpc_parse/parse_reg.o rpc_parse/parse_rpc.o \ rpc_parse/parse_samr.o rpc_parse/parse_srv.o \ rpc_parse/parse_wks.o \ - rpc_parse/parse_spoolss.o rpc_parse/parse_dfs.o + rpc_parse/parse_spoolss.o rpc_parse/parse_dfs.o \ + $(REGOBJS_OBJ) RPC_CLIENT_OBJ = rpc_client/cli_pipe.o @@ -213,8 +217,15 @@ PASSDB_GET_SET_OBJ = passdb/pdb_get_set.o PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \ passdb/machine_sid.o passdb/pdb_smbpasswd.o \ passdb/pdb_tdb.o passdb/pdb_ldap.o passdb/pdb_plugin.o \ - passdb/pdb_nisplus.o passdb/pdb_unix.o passdb/util_sam_sid.o \ - passdb/pdb_compat.o + passdb/pdb_unix.o passdb/util_sam_sid.o \ + passdb/pdb_compat.o passdb/pdb_nisplus.o + +SAM_STATIC_MODULES = sam/sam_plugin.o + +SAM_OBJ = sam/account.o sam/get_set_account.o sam/get_set_group.o \ + sam/get_set_domain.o sam/interface.o sam/api.o $(SAM_STATIC_MODULES) + +SAMTEST_OBJ = torture/samtest.o torture/cmd_sam.o $(SAM_OBJ) $(LIB_OBJ) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(READLINE_OBJ) lib/util_seaccess.o $(LIBADS_OBJ) $(PASSDB_OBJ) $(SECRETS_OBJ) $(GROUPDB_OBJ) GROUPDB_OBJ = groupdb/mapping.o @@ -232,25 +243,37 @@ UNIGRP_OBJ = libsmb/netlogon_unigrp.o AUTH_OBJ = auth/auth.o auth/auth_sam.o auth/auth_server.o auth/auth_domain.o \ auth/auth_rhosts.o auth/auth_unix.o auth/auth_util.o auth/auth_winbind.o \ - auth/auth_builtin.o auth/auth_compat.o $(PLAINTEXT_AUTH_OBJ) $(UNIGRP_OBJ) + auth/auth_builtin.o auth/auth_compat.o \ + $(PLAINTEXT_AUTH_OBJ) $(UNIGRP_OBJ) MANGLE_OBJ = smbd/mangle.o smbd/mangle_hash.o smbd/mangle_map.o smbd/mangle_hash2.o -SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \ - smbd/utmp.o smbd/session.o \ - smbd/dfree.o smbd/dir.o smbd/password.o smbd/conn.o smbd/fileio.o \ - smbd/ipc.o smbd/lanman.o smbd/negprot.o \ - smbd/message.o smbd/nttrans.o smbd/pipes.o \ - smbd/reply.o smbd/sesssetup.o smbd/trans2.o smbd/uid.o \ - smbd/dosmode.o smbd/filename.o smbd/open.o smbd/close.o \ - smbd/blocking.o smbd/sec_ctx.o \ - smbd/vfs.o smbd/vfs-wrap.o smbd/statcache.o \ - smbd/posix_acls.o lib/sysacls.o \ - smbd/process.o smbd/service.o smbd/error.o \ - printing/printfsp.o lib/util_seaccess.o smbd/srvstr.o \ - smbd/build_options.o \ - smbd/change_trust_pw.o \ - $(MANGLE_OBJ) +SMBD_OBJ_MAIN = smbd/server.o + +SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \ + smbd/utmp.o smbd/session.o \ + smbd/dfree.o smbd/dir.o smbd/password.o smbd/conn.o smbd/fileio.o \ + smbd/ipc.o smbd/lanman.o smbd/negprot.o \ + smbd/message.o smbd/nttrans.o smbd/pipes.o \ + smbd/reply.o smbd/sesssetup.o smbd/trans2.o smbd/uid.o \ + smbd/dosmode.o smbd/filename.o smbd/open.o smbd/close.o \ + smbd/blocking.o smbd/sec_ctx.o \ + smbd/vfs.o smbd/vfs-wrap.o smbd/statcache.o \ + smbd/posix_acls.o lib/sysacls.o lib/server_mutex.o \ + smbd/process.o smbd/service.o smbd/error.o \ + printing/printfsp.o lib/util_seaccess.o smbd/srvstr.o \ + smbd/build_options.o \ + smbd/change_trust_pw.o \ + $(MANGLE_OBJ) + +SMBD_OBJ_BASE = $(SMBD_OBJ_SRV) $(MSDFS_OBJ) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \ + $(RPC_SERVER_OBJ) $(RPC_PARSE_OBJ) $(SECRETS_OBJ) \ + $(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) \ + $(LIB_OBJ) $(PRINTBACKEND_OBJ) $(QUOTAOBJS) $(OPLOCK_OBJ) \ + $(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \ + $(LIBMSRPC_OBJ) $(LIBMSRPC_SERVER_OBJ) \ + $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) \ + $(LIB_SMBD_OBJ) $(REGISTRY_OBJ) PRINTING_OBJ = printing/pcap.o printing/print_svid.o \ @@ -261,15 +284,7 @@ PRINTBACKEND_OBJ = printing/printing.o printing/nt_printing.o printing/notify.o MSDFS_OBJ = msdfs/msdfs.o -SMBD_OBJ = $(SMBD_OBJ1) $(MSDFS_OBJ) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \ - $(RPC_SERVER_OBJ) $(RPC_PARSE_OBJ) $(SECRETS_OBJ) \ - $(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) \ - $(LIB_OBJ) $(PRINTBACKEND_OBJ) $(QUOTAOBJS) $(OPLOCK_OBJ) \ - $(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \ - $(LIBMSRPC_OBJ) $(LIBMSRPC_SERVER_OBJ) \ - $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) \ - $(LIB_SMBD_OBJ) - +SMBD_OBJ = $(SMBD_OBJ_MAIN) $(SMBD_OBJ_BASE) NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o nmbd/nmbd_become_dmb.o \ nmbd/nmbd_become_lmb.o nmbd/nmbd_browserdb.o \ @@ -343,13 +358,6 @@ RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \ $(READLINE_OBJ) $(GROUPDB_OBJ) \ $(LIBADS_OBJ) $(SECRETS_OBJ) -SAMSYNC_OBJ1 = rpcclient/samsync.o rpcclient/display_sec.o - -SAMSYNC_OBJ = $(SAMSYNC_OBJ1) \ - $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \ - $(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(LIBMSRPC_OBJ) \ - $(GROUPDB_OBJ) $(SECRETS_OBJ) - PAM_WINBIND_OBJ = nsswitch/pam_winbind.po nsswitch/wb_common.po lib/snprintf.po SMBW_OBJ1 = smbwrapper/smbw.o \ @@ -373,12 +381,13 @@ CLIENT_OBJ1 = client/client.o client/clitar.o CLIENT_OBJ = $(CLIENT_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \ $(READLINE_OBJ) -NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_help.o \ - utils/net_rap.o utils/net_rpc.o \ - utils/net_rpc_join.o utils/net_time.o utils/net_lookup.o +NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_ads_cldap.o utils/net_help.o \ + utils/net_rap.o utils/net_rpc.o utils/net_rpc_samsync.o \ + utils/net_rpc_join.o utils/net_time.o utils/net_lookup.o \ + utils/net_cache.o NET_OBJ = $(NET_OBJ1) $(SECRETS_OBJ) $(LIBSMB_OBJ) \ - $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ) \ + $(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \ $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \ $(LIBMSRPC_OBJ) $(LIBMSRPC_SERVER_OBJ) \ $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) @@ -414,6 +423,8 @@ LOCKTEST_OBJ = torture/locktest.o $(LOCKING_OBJ) $(LIBSMB_OBJ) $(PARAM_OBJ) \ NSSTEST_OBJ = torture/nsstest.o $(LIBSMB_OBJ) $(PARAM_OBJ) \ $(UBIQX_OBJ) $(LIB_OBJ) +VFSTEST_OBJ = torture/cmd_vfs.o torture/vfstest.o $(SMBD_OBJ_BASE) $(READLINE_OBJ) + LOCKTEST2_OBJ = torture/locktest2.o $(LOCKING_OBJ) $(LIBSMB_OBJ) $(PARAM_OBJ) \ $(UBIQX_OBJ) $(LIB_OBJ) @@ -438,15 +449,16 @@ DEBUG2HTML_OBJ = utils/debug2html.o ubiqx/debugparse.o SMBFILTER_OBJ = utils/smbfilter.o $(LIBSMB_OBJ) $(PARAM_OBJ) \ $(UBIQX_OBJ) $(LIB_OBJ) -PROTO_OBJ = $(SMBD_OBJ1) $(NMBD_OBJ1) $(SWAT_OBJ1) $(LIB_OBJ) $(LIBSMB_OBJ) \ - $(SMBWRAPPER_OBJ1) $(SMBTORTURE_OBJ1) $(RPCCLIENT_OBJ1) \ +PROTO_OBJ = $(SMBD_OBJ_MAIN) \ + $(SMBD_OBJ_SRV) $(NMBD_OBJ1) $(SWAT_OBJ1) $(LIB_OBJ) $(LIBSMB_OBJ) \ + $(SMBW_OBJ1) $(SMBWRAPPER_OBJ1) $(SMBTORTURE_OBJ1) $(RPCCLIENT_OBJ1) \ $(LIBMSRPC_OBJ) $(LIBMSRPC_SERVER_OBJ) $(RPC_CLIENT_OBJ) \ $(RPC_SERVER_OBJ) $(RPC_PARSE_OBJ) \ $(AUTH_OBJ) $(PARAM_OBJ) $(LOCKING_OBJ) $(SECRETS_OBJ) \ $(PRINTING_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) $(NOTIFY_OBJ) \ $(QUOTAOBJS) $(PASSDB_OBJ) $(GROUPDB_OBJ) $(MSDFS_OBJ) \ $(READLINE_OBJ) $(PROFILE_OBJ) $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) \ - $(LIB_SMBD_OBJ) + $(LIB_SMBD_OBJ) $(SAM_OBJ) $(REGISTRY_OBJ) NSS_OBJ_0 = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) $(LIBSMB_OBJ) \ $(LIB_OBJ) $(NSSWINS_OBJ) @@ -486,7 +498,7 @@ WINBINDD_OBJ = \ $(LIBNMB_OBJ) $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \ $(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) \ $(PROFILE_OBJ) $(UNIGRP_OBJ) \ - $(SECRETS_OBJ) $(LIBADS_OBJ) + $(SECRETS_OBJ) $(LIBADS_OBJ) WBINFO_OBJ = nsswitch/wbinfo.o libsmb/smbencrypt.o libsmb/smbdes.o @@ -534,7 +546,7 @@ nsswitch : SHOWFLAGS $(WINBIND_PROGS) $(WINBIND_SPROGS) $(LPROGS) wins : SHOWFLAGS nsswitch/libnss_wins.so -everything: all libsmbclient debug2html smbfilter talloctort bin/samsync bin/make_printerdef +everything: all libsmbclient debug2html smbfilter talloctort bin/make_printerdef .SUFFIXES: .SUFFIXES: .c .o .po .po32 .lo @@ -605,7 +617,7 @@ bin/.dummy: bin/smbd: $(SMBD_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SMBD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) + @$(CC) $(FLAGS) -o $@ $(SMBD_OBJ) $(LDFLAGS) $(DYNEXP) $(PRINTLIBS) $(LIBS) bin/nmbd: $(NMBD_OBJ) bin/.dummy @echo Linking $@ @@ -617,16 +629,12 @@ bin/wrepld: $(WREPL_OBJ) bin/.dummy bin/swat: $(SWAT_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SWAT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) + @$(CC) $(FLAGS) -o $@ $(SWAT_OBJ) $(LDFLAGS) $(DYNEXP) $(PRINTLIBS) $(LIBS) bin/rpcclient: $(RPCCLIENT_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(RPCCLIENT_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @BUILD_POPT@ -bin/samsync: $(SAMSYNC_OBJ) bin/.dummy - @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SAMSYNC_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) - bin/smbclient: $(CLIENT_OBJ) bin/.dummy @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(CLIENT_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @@ -657,7 +665,7 @@ bin/testparm: $(TESTPARM_OBJ) bin/.dummy bin/testprns: $(TESTPRNS_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(TESTPRNS_OBJ) $(LDFLAGS) $(LIBS) + @$(CC) $(FLAGS) -o $@ $(TESTPRNS_OBJ) $(LDFLAGS) $(PRINTLIBS) $(LIBS) bin/smbstatus: $(STATUS_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ @@ -679,6 +687,10 @@ bin/pdbedit: $(PDBEDIT_OBJ) bin/.dummy @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(PDBEDIT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @BUILD_POPT@ +bin/samtest: $(SAMTEST_OBJ) bin/.dummy + @echo Linking $@ + @$(CC) $(FLAGS) -o $@ $(SAMTEST_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(LIBS) @BUILD_POPT@ + bin/smbgroupedit: $(SMBGROUPEDIT_OBJ) bin/.dummy @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(SMBGROUPEDIT_OBJ) $(LDFLAGS) $(LIBS) @@ -719,6 +731,10 @@ bin/nsstest: $(NSSTEST_OBJ) bin/.dummy @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(NSSTEST_OBJ) $(LDFLAGS) $(LIBS) +bin/vfstest: $(VFSTEST_OBJ) bin/.dummy + @echo Linking $@ + @$(CC) $(FLAGS) -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(PRINTLIBS) $(LIBS) @BUILD_POPT@ + bin/locktest2: $(LOCKTEST2_OBJ) bin/.dummy @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(LOCKTEST2_OBJ) $(LDFLAGS) $(LIBS) @@ -802,10 +818,6 @@ bin/pam_smbpass.@SHLIBEXT@: $(PAM_SMBPASS_PICOOBJ) bin/libmsrpc.a: $(LIBMSRPC_PICOBJ) -$(AR) -rc $@ $(LIBMSRPC_PICOBJ) -bin/spamsync: rpcclient/samsync.o bin/libmsrpc.a - @$(LINK) -o $@ rpcclient/samsync.o bin/libmsrpc.a \ - $(UBIQX_OBJ) $(LIBS) - bin/tdbbackup: $(TDBBACKUP_OBJ) bin/.dummy @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(TDBBACKUP_OBJ) @@ -836,6 +848,53 @@ installclientlib: -$(INSTALLCMD) -d ${prefix}/include -$(INSTALLCMD) include/libsmbclient.h ${prefix}/include +# Python extensions + +PYTHON_OBJS = $(LIB_OBJ) $(LIBSMB_OBJ) $(RPC_PARSE_OBJ) $(UBIQX_OBJ) \ + $(PARAM_OBJ) $(LIBMSRPC_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) $(SECRETS_OBJ) + +PY_SPOOLSS_PROTO_OBJ = python/py_spoolss.o \ + python/py_spoolss_printers.o python/py_spoolss_printers_conv.o\ + python/py_spoolss_forms.o python/py_spoolss_forms_conv.o \ + python/py_spoolss_ports.o python/py_spoolss_ports_conv.o \ + python/py_spoolss_drivers.o python/py_spoolss_drivers_conv.o \ + python/py_spoolss_jobs.o python/py_spoolss_jobs_conv.o \ + python/py_spoolss_printerdata.o + +PY_LSA_PROTO_OBJ = python/py_lsa.o + +PY_COMMON_PROTO_OBJ = python/py_common.c python/py_ntsec.c + +python_proto: python_spoolss_proto python_lsa_proto python_common_proto + +python_spoolss_proto: + @cd $(srcdir) && $(SHELL) script/mkproto.sh $(AWK) \ + -h _PY_SPOOLSS_PROTO_H python/py_spoolss_proto.h \ + $(PY_SPOOLSS_PROTO_OBJ) + +python_lsa_proto: + @cd $(srcdir) && $(SHELL) script/mkproto.sh $(AWK) \ + -h _PY_LSA_PROTO_H python/py_lsa_proto.h \ + $(PY_LSA_PROTO_OBJ) + +python_common_proto: + @cd $(srcdir) && $(SHELL) script/mkproto.sh $(AWK) \ + -h _PY_COMMON_PROTO_H python/py_common_proto.h \ + $(PY_COMMON_PROTO_OBJ) + +python_ext: $(PYTHON_OBJS) + PYTHON_OBJS="$(PYTHON_OBJS)" PYTHON_CFLAGS="$(CFLAGS) $(CPPFLAGS) $(FLAGS)" \ + LIBS="$(LIBS)" \ + $(PYTHON) python/setup.py build + +python_install: $(PYTHON_OBJS) + PYTHON_OBJS="$(PYTHON_OBJS)" PYTHON_CFLAGS="$(CFLAGS) $(CPPFLAGS)" \ + LIBS="$(LIBS)" \ + $(PYTHON) python/setup.py install + +python_clean: + @if test -n "$(PYTHON)"; then $(PYTHON) python/setup.py clean; fi + # revert to the previously installed version revert: @$(SHELL) $(srcdir)/script/revert.sh $(SBINDIR) $(SPROGS) @@ -871,9 +930,9 @@ uninstallscripts: # Toplevel clean files TOPFILES=dynconfig.o dynconfig.po -clean: delheaders +clean: delheaders python_clean -rm -f core */*~ *~ */*.o */*.po */*.po32 */*.@SHLIBEXT@ \ - $(TOPFILES) $(PROGS) $(SPROGS) .headers.stamp + $(TOPFILES) $(PROGS) $(SPROGS) .headers.stamp # Making this target will just make sure that the prototype files # exist, not necessarily that they are up to date. Since they're @@ -949,7 +1008,7 @@ etags: ctags: ctags `find $(srcdir) -name "*.[ch]" | grep -v /CVS/` -realclean: clean +realclean: clean delheaders -rm -f config.log $(PROGS) $(SPROGS) bin/.dummy -rmdir bin diff --git a/source3/acconfig.h b/source3/acconfig.h index 274bc4aaadd..45d63669354 100644 --- a/source3/acconfig.h +++ b/source3/acconfig.h @@ -166,6 +166,7 @@ #undef MMAP_BLACKLIST #undef HAVE_IMMEDIATE_STRUCTURES #undef HAVE_CUPS +#undef WITH_SAM #undef WITH_LDAP_SAM #undef WITH_NISPLUS_SAM #undef WITH_TDB_SAM @@ -186,6 +187,7 @@ #undef HAVE_LDAP #undef HAVE_STAT_ST_BLOCKS #undef STAT_ST_BLOCKSIZE +#undef HAVE_STAT_ST_BLKSIZE #undef HAVE_DEVICE_MAJOR_FN #undef HAVE_DEVICE_MINOR_FN #undef HAVE_PASSWD_PW_COMMENT @@ -220,4 +222,11 @@ #endif #undef LDAP_SET_REBIND_PROC_ARGS - +#undef HAVE_SENDFILE +#undef HAVE_SENDFILE64 +#undef LINUX_SENDFILE_API +#undef LINUX_BROKEN_SENDFILE_API +#undef WITH_SENDFILE +#undef FREEBSD_SENDFILE_API +#undef HPUX_SENDFILE_API +#undef WITH_ADS diff --git a/source3/auth/auth_builtin.c b/source3/auth/auth_builtin.c index 5ce7075ab9f..d54a8660b35 100644 --- a/source3/auth/auth_builtin.c +++ b/source3/auth/auth_builtin.c @@ -41,13 +41,8 @@ static NTSTATUS check_guest_security(const struct auth_context *auth_context, NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE; if (!(user_info->internal_username.str - && *user_info->internal_username.str)) { - if (make_server_info_guest(server_info)) { - nt_status = NT_STATUS_OK; - } else { - nt_status = NT_STATUS_NO_SUCH_USER; - } - } + && *user_info->internal_username.str)) + nt_status = make_server_info_guest(server_info); return nt_status; } @@ -194,7 +189,7 @@ NTSTATUS auth_init_plugin(struct auth_context *auth_context, const char *param, trim_string(plugin_name, " ", " "); DEBUG(5, ("Trying to load auth plugin %s\n", plugin_name)); - dl_handle = sys_dlopen(plugin_name, RTLD_NOW | RTLD_GLOBAL ); + dl_handle = sys_dlopen(plugin_name, RTLD_NOW ); if (!dl_handle) { DEBUG(0, ("Failed to load auth plugin %s using sys_dlopen (%s)\n", plugin_name, sys_dlerror())); return NT_STATUS_UNSUCCESSFUL; diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index d48cec5b293..2e51a852816 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -48,7 +48,7 @@ static NTSTATUS ads_resolve_dc(fstring remote_machine, DEBUG(4,("ads_resolve_dc: realm=%s\n", ads->config.realm)); - ads->auth.no_bind = 1; + ads->auth.flags |= ADS_AUTH_NO_BIND; #ifdef HAVE_ADS /* a full ads_connect() is actually overkill, as we don't srictly need @@ -131,6 +131,7 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli, struct in_addr dest_ip; fstring remote_machine; NTSTATUS result; + uint32 neg_flags = 0x000001ff; if (lp_security() == SEC_ADS) { result = ads_resolve_dc(remote_machine, &dest_ip); @@ -206,7 +207,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli))); return NT_STATUS_NO_MEMORY; } - result = cli_nt_setup_creds(*cli, sec_chan, trust_passwd); + result = cli_nt_setup_creds(*cli, sec_chan, trust_passwd, &neg_flags, 2); if (!NT_STATUS_IS_OK(result)) { DEBUG(0,("connect_to_domain_password_server: unable to setup the PDC credentials to machine \ @@ -250,7 +251,7 @@ static NTSTATUS attempt_connect_to_dc(struct cli_state **cli, } /*********************************************************************** - We have been asked to dynamcially determine the IP addresses of + We have been asked to dynamically determine the IP addresses of the PDC and BDC's for DOMAIN, and query them in turn. ************************************************************************/ static NTSTATUS find_connect_pdc(struct cli_state **cli, diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c index 155370546a5..bc98f46dc2f 100644 --- a/source3/auth/auth_sam.c +++ b/source3/auth/auth_sam.c @@ -106,7 +106,10 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response, client_key_data = data_blob(ntv2_response.data+16, ntv2_response.length-16); memcpy(client_response, ntv2_response.data, sizeof(client_response)); - ntv2_owf_gen(part_passwd, user, domain, kr); + if (!ntv2_owf_gen(part_passwd, user, domain, kr)) { + return False; + } + SMBOWFencrypt_ntv2(kr, sec_blob, client_key_data, value_from_encryption); if (user_sess_key != NULL) { @@ -233,17 +236,17 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context, return NT_STATUS_OK; } else { if (lp_ntlm_auth()) { - /* Apparently NT accepts NT responses in the LM feild - - I think this is related to Win9X pass-though authenticaion + /* Apparently NT accepts NT responses in the LM field + - I think this is related to Win9X pass-though authentication */ - DEBUG(4,("sam_password_ok: Checking NT MD4 password in LM feild\n")); + DEBUG(4,("sam_password_ok: Checking NT MD4 password in LM field\n")); if (smb_pwd_check_ntlmv1(user_info->lm_resp, nt_pw, auth_context->challenge, user_sess_key)) { return NT_STATUS_OK; } else { - DEBUG(3,("sam_password_ok: NT MD4 password in LM feild failed for user %s\n",pdb_get_username(sampass))); + DEBUG(3,("sam_password_ok: NT MD4 password in LM field failed for user %s\n",pdb_get_username(sampass))); return NT_STATUS_WRONG_PASSWORD; } } @@ -403,9 +406,9 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context, return nt_status; } - if (!make_server_info_sam(server_info, sampass)) { - DEBUG(0,("failed to malloc memory for server_info\n")); - return NT_STATUS_NO_MEMORY; + if (!NT_STATUS_IS_OK(nt_status = make_server_info_sam(server_info, sampass))) { + DEBUG(0,("check_sam_security: make_server_info_sam() failed with '%s'\n", nt_errstr(nt_status))); + return nt_status; } lm_hash = pdb_get_lanman_passwd((*server_info)->sam_account); diff --git a/source3/auth/auth_server.c b/source3/auth/auth_server.c index 23faedc0bac..0ed905e79c8 100644 --- a/source3/auth/auth_server.c +++ b/source3/auth/auth_server.c @@ -285,7 +285,7 @@ static NTSTATUS check_smbserver_security(const struct auth_context *auth_context * need to detect this as some versions of NT4.x are broken. JRA. */ - /* I sure as hell hope that there arn't servers out there that take + /* I sure as hell hope that there aren't servers out there that take * NTLMv2 and have this bug, as we don't test for that... * - abartlet@samba.org */ @@ -375,9 +375,7 @@ use this machine as the password server.\n")); if NT_STATUS_IS_OK(nt_status) { struct passwd *pass = Get_Pwnam(user_info->internal_username.str); if (pass) { - if (!make_server_info_pw(server_info, pass)) { - nt_status = NT_STATUS_NO_MEMORY; - } + nt_status = make_server_info_pw(server_info, pass); } else { nt_status = NT_STATUS_NO_SUCH_USER; } diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index f914d918715..ce5fd32337b 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -4,6 +4,7 @@ Copyright (C) Andrew Tridgell 1992-1998 Copyright (C) Andrew Bartlett 2001 Copyright (C) Jeremy Allison 2000-2001 + Copyright (C) Rafal Szczesniak 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,6 +27,11 @@ #define DBGC_CLASS DBGC_AUTH extern pstring global_myname; +extern DOM_SID global_sid_World; +extern DOM_SID global_sid_Network; +extern DOM_SID global_sid_Builtin_Guests; +extern DOM_SID global_sid_Authenticated_Users; + /**************************************************************************** Create a UNIX user on demand. @@ -51,7 +57,7 @@ static int smb_create_user(const char *unix_user, const char *homedir) Add and Delete UNIX users on demand, based on NTSTATUS codes. ****************************************************************************/ -void smb_user_control(const auth_usersupplied_info *user_info, auth_serversupplied_info *server_info, NTSTATUS nt_status) +void smb_user_control(const auth_usersupplied_info *user_info, auth_serversupplied_info *server_info, NTSTATUS nt_status) { struct passwd *pwd=NULL; @@ -76,15 +82,15 @@ void smb_user_control(const auth_usersupplied_info *user_info, auth_serversuppli Create an auth_usersupplied_data structure ****************************************************************************/ -static BOOL make_user_info(auth_usersupplied_info **user_info, - const char *smb_name, - const char *internal_username, - const char *client_domain, - const char *domain, - const char *wksta_name, - DATA_BLOB lm_pwd, DATA_BLOB nt_pwd, - DATA_BLOB plaintext, - uint32 auth_flags, BOOL encrypted) +static NTSTATUS make_user_info(auth_usersupplied_info **user_info, + const char *smb_name, + const char *internal_username, + const char *client_domain, + const char *domain, + const char *wksta_name, + DATA_BLOB lm_pwd, DATA_BLOB nt_pwd, + DATA_BLOB plaintext, + uint32 auth_flags, BOOL encrypted) { DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name)); @@ -92,7 +98,7 @@ static BOOL make_user_info(auth_usersupplied_info **user_info, *user_info = malloc(sizeof(**user_info)); if (!user_info) { DEBUG(0,("malloc failed for user_info (size %d)\n", sizeof(*user_info))); - return False; + return NT_STATUS_NO_MEMORY; } ZERO_STRUCTP(*user_info); @@ -104,7 +110,7 @@ static BOOL make_user_info(auth_usersupplied_info **user_info, (*user_info)->smb_name.len = strlen(smb_name); } else { free_user_info(user_info); - return False; + return NT_STATUS_NO_MEMORY; } (*user_info)->internal_username.str = strdup(internal_username); @@ -112,7 +118,7 @@ static BOOL make_user_info(auth_usersupplied_info **user_info, (*user_info)->internal_username.len = strlen(internal_username); } else { free_user_info(user_info); - return False; + return NT_STATUS_NO_MEMORY; } (*user_info)->domain.str = strdup(domain); @@ -120,7 +126,7 @@ static BOOL make_user_info(auth_usersupplied_info **user_info, (*user_info)->domain.len = strlen(domain); } else { free_user_info(user_info); - return False; + return NT_STATUS_NO_MEMORY; } (*user_info)->client_domain.str = strdup(client_domain); @@ -128,7 +134,7 @@ static BOOL make_user_info(auth_usersupplied_info **user_info, (*user_info)->client_domain.len = strlen(client_domain); } else { free_user_info(user_info); - return False; + return NT_STATUS_NO_MEMORY; } (*user_info)->wksta_name.str = strdup(wksta_name); @@ -136,7 +142,7 @@ static BOOL make_user_info(auth_usersupplied_info **user_info, (*user_info)->wksta_name.len = strlen(wksta_name); } else { free_user_info(user_info); - return False; + return NT_STATUS_NO_MEMORY; } DEBUG(5,("making blobs for %s's user_info struct\n", internal_username)); @@ -150,26 +156,26 @@ static BOOL make_user_info(auth_usersupplied_info **user_info, DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name)); - return True; + return NT_STATUS_OK; } /**************************************************************************** Create an auth_usersupplied_data structure after appropriate mapping. ****************************************************************************/ -BOOL make_user_info_map(auth_usersupplied_info **user_info, - const char *smb_name, - const char *client_domain, - const char *wksta_name, - DATA_BLOB lm_pwd, DATA_BLOB nt_pwd, - DATA_BLOB plaintext, - uint32 ntlmssp_flags, BOOL encrypted) +NTSTATUS make_user_info_map(auth_usersupplied_info **user_info, + const char *smb_name, + const char *client_domain, + const char *wksta_name, + DATA_BLOB lm_pwd, DATA_BLOB nt_pwd, + DATA_BLOB plaintext, + uint32 ntlmssp_flags, BOOL encrypted) { const char *domain; fstring internal_username; fstrcpy(internal_username, smb_name); map_username(internal_username); - + DEBUG(5, ("make_user_info_map: Mapping user [%s]\\[%s] from workstation [%s]\n", client_domain, smb_name, wksta_name)); @@ -198,7 +204,7 @@ BOOL make_user_info_map(auth_usersupplied_info **user_info, client_domain, lp_winbind_separator(), smb_name) < 0) { DEBUG(0, ("make_user_info_map: asprintf() failed!\n")); - return False; + return NT_STATUS_NO_MEMORY; } DEBUG(5, ("make_user_info_map: testing for user %s\n", user)); @@ -240,6 +246,7 @@ BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info, const uchar *nt_network_pwd, int nt_pwd_len) { BOOL ret; + NTSTATUS nt_status; DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len); DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len); DATA_BLOB plaintext_blob = data_blob(NULL, 0); @@ -253,12 +260,14 @@ BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info, auth_flags |= AUTH_FLAG_NTLMv2_RESP; } - ret = make_user_info_map(user_info, - smb_name, client_domain, - wksta_name, - lm_blob, nt_blob, - plaintext_blob, - auth_flags, True); + nt_status = make_user_info_map(user_info, + smb_name, client_domain, + wksta_name, + lm_blob, nt_blob, + plaintext_blob, + auth_flags, True); + + ret = NT_STATUS_IS_OK(nt_status) ? True : False; data_blob_free(&lm_blob); data_blob_free(&nt_blob); @@ -324,6 +333,7 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info, { BOOL ret; + NTSTATUS nt_status; DATA_BLOB local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response)); DATA_BLOB local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response)); DATA_BLOB plaintext_blob = data_blob(NULL, 0); @@ -333,14 +343,15 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info, if (nt_interactive_pwd) auth_flags |= AUTH_FLAG_NTLM_RESP; - ret = make_user_info_map(user_info, - smb_name, client_domain, - wksta_name, - local_lm_blob, - local_nt_blob, - plaintext_blob, - auth_flags, True); + nt_status = make_user_info_map(user_info, + smb_name, client_domain, + wksta_name, + local_lm_blob, + local_nt_blob, + plaintext_blob, + auth_flags, True); + ret = NT_STATUS_IS_OK(nt_status) ? True : False; data_blob_free(&local_lm_blob); data_blob_free(&local_nt_blob); return ret; @@ -361,7 +372,7 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info, DATA_BLOB local_lm_blob; DATA_BLOB local_nt_blob; - BOOL ret = False; + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; uint32 auth_flags = AUTH_FLAG_NONE; /* @@ -392,25 +403,25 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info, } ret = make_user_info_map(user_info, smb_name, - client_domain, - get_remote_machine_name(), - local_lm_blob, - local_nt_blob, - plaintext_password, - auth_flags, False); + client_domain, + get_remote_machine_name(), + local_lm_blob, + local_nt_blob, + plaintext_password, + auth_flags, False); data_blob_free(&local_lm_blob); - return ret; + return NT_STATUS_IS_OK(ret) ? True : False; } /**************************************************************************** Create an auth_usersupplied_data structure ****************************************************************************/ -BOOL make_user_info_for_reply_enc(auth_usersupplied_info **user_info, - const char *smb_name, - const char *client_domain, - DATA_BLOB lm_resp, DATA_BLOB nt_resp) +NTSTATUS make_user_info_for_reply_enc(auth_usersupplied_info **user_info, + const char *smb_name, + const char *client_domain, + DATA_BLOB lm_resp, DATA_BLOB nt_resp) { uint32 auth_flags = AUTH_FLAG_NONE; @@ -445,47 +456,338 @@ BOOL make_user_info_guest(auth_usersupplied_info **user_info) DATA_BLOB nt_blob = data_blob(NULL, 0); DATA_BLOB plaintext_blob = data_blob(NULL, 0); uint32 auth_flags = AUTH_FLAG_NONE; + NTSTATUS nt_status; - return make_user_info(user_info, + nt_status = make_user_info(user_info, "","", "","", "", nt_blob, lm_blob, plaintext_blob, auth_flags, True); + + return NT_STATUS_IS_OK(nt_status) ? True : False; +} + +/**************************************************************************** + prints a NT_USER_TOKEN to debug output. +****************************************************************************/ + +void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token) +{ + fstring sid_str; + int i; + + if (!token) { + DEBUGC(dbg_class, dbg_lev, ("NT user token: (NULL)\n")); + return; + } + + DEBUGC(dbg_class, dbg_lev, ("NT user token of user %s\n", + sid_to_string(sid_str, &token->user_sids[0]) )); + DEBUGADDC(dbg_class, dbg_lev, ("contains %i SIDs\n", token->num_sids)); + for (i = 0; i < token->num_sids; i++) + DEBUGADDC(dbg_class, dbg_lev, ("SID[%3i]: %s\n", i, + sid_to_string(sid_str, &token->user_sids[i]))); +} + +/**************************************************************************** + prints a UNIX 'token' to debug output. +****************************************************************************/ + +void debug_unix_user_token(int dbg_class, int dbg_lev, uid_t uid, gid_t gid, int n_groups, gid_t *groups) +{ + int i; + DEBUGC(dbg_class, dbg_lev, ("UNIX token of user %ld\n", (long int)uid)); + + DEBUGADDC(dbg_class, dbg_lev, ("Primary group is %ld and contains %i supplementary groups\n", (long int)gid, n_groups)); + for (i = 0; i < n_groups; i++) + DEBUGADDC(dbg_class, dbg_lev, ("Group[%3i]: %ld\n", i, + (long int)groups[i])); +} + +/**************************************************************************** + Create the SID list for this user. +****************************************************************************/ + +static NTSTATUS create_nt_user_token(const DOM_SID *user_sid, const DOM_SID *group_sid, + int n_groupSIDs, DOM_SID *groupSIDs, + BOOL is_guest, NT_USER_TOKEN **token) +{ + NTSTATUS nt_status = NT_STATUS_OK; + NT_USER_TOKEN *ptoken; + int i; + int sid_ndx; + + if ((ptoken = malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) { + DEBUG(0, ("create_nt_token: Out of memory allocating token\n")); + nt_status = NT_STATUS_NO_MEMORY; + return nt_status; + } + + ZERO_STRUCTP(ptoken); + + ptoken->num_sids = n_groupSIDs + 5; + + if ((ptoken->user_sids = (DOM_SID *)malloc( sizeof(DOM_SID) * ptoken->num_sids )) == NULL) { + DEBUG(0, ("create_nt_token: Out of memory allocating SIDs\n")); + nt_status = NT_STATUS_NO_MEMORY; + return nt_status; + } + + memset((char*)ptoken->user_sids,0,sizeof(DOM_SID) * ptoken->num_sids); + + /* + * Note - user SID *MUST* be first in token ! + * se_access_check depends on this. + * + * Primary group SID is second in token. Convention. + */ + + sid_copy(&ptoken->user_sids[PRIMARY_USER_SID_INDEX], user_sid); + if (group_sid) + sid_copy(&ptoken->user_sids[PRIMARY_GROUP_SID_INDEX], group_sid); + + /* + * Finally add the "standard" SIDs. + * The only difference between guest and "anonymous" (which we + * don't really support) is the addition of Authenticated_Users. + */ + + sid_copy(&ptoken->user_sids[2], &global_sid_World); + sid_copy(&ptoken->user_sids[3], &global_sid_Network); + + if (is_guest) + sid_copy(&ptoken->user_sids[4], &global_sid_Builtin_Guests); + else + sid_copy(&ptoken->user_sids[4], &global_sid_Authenticated_Users); + + sid_ndx = 5; /* next available spot */ + + for (i = 0; i < n_groupSIDs; i++) { + int check_sid_idx; + for (check_sid_idx = 1; check_sid_idx < ptoken->num_sids; check_sid_idx++) { + if (sid_equal(&ptoken->user_sids[check_sid_idx], + &groupSIDs[i])) { + break; + } + } + + if (check_sid_idx >= ptoken->num_sids) /* Not found already */ { + sid_copy(&ptoken->user_sids[sid_ndx++], &groupSIDs[i]); + } else { + ptoken->num_sids--; + } + } + + debug_nt_user_token(DBGC_AUTH, 10, ptoken); + + *token = ptoken; + + return nt_status; +} + +/**************************************************************************** + Create the SID list for this user. +****************************************************************************/ + +NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, BOOL is_guest) +{ + DOM_SID user_sid; + DOM_SID group_sid; + DOM_SID *group_sids; + NT_USER_TOKEN *token; + int i; + + if (!uid_to_sid(&user_sid, uid)) { + return NULL; + } + if (!gid_to_sid(&group_sid, gid)) { + return NULL; + } + + group_sids = malloc(sizeof(DOM_SID) * ngroups); + if (!group_sids) { + DEBUG(0, ("create_nt_token: malloc() failed for DOM_SID list!\n")); + return NULL; + } + + for (i = 0; i < ngroups; i++) { + if (!gid_to_sid(&(group_sids)[i], (groups)[i])) { + DEBUG(1, ("create_nt_token: failed to convert gid %ld to a sid!\n", (long int)groups[i])); + SAFE_FREE(group_sids); + return NULL; + } + } + + if (!NT_STATUS_IS_OK(create_nt_user_token(&user_sid, &group_sid, + ngroups, group_sids, is_guest, &token))) { + SAFE_FREE(group_sids); + return NULL; + } + + SAFE_FREE(group_sids); + + return token; +} + +/****************************************************************************** + * this function returns the groups (SIDs) of the local SAM the user is in. + * If this samba server is a DC of the domain the user belongs to, it returns + * both domain groups and local / builtin groups. If the user is in a trusted + * domain, or samba is a member server of a domain, then this function returns + * local and builtin groups the user is a member of. + * + * currently this is a hack, as there is no sam implementation that is capable + * of groups. + ******************************************************************************/ + +static NTSTATUS get_user_groups_from_local_sam(const DOM_SID *user_sid, + int *n_groups, DOM_SID **groups, gid_t **unix_groups) +{ + uid_t uid; + enum SID_NAME_USE snu; + fstring str; + int n_unix_groups; + int i; + struct passwd *usr; + + *n_groups = 0; + *groups = NULL; + + if (!sid_to_uid(user_sid, &uid, &snu)) { + DEBUG(2, ("get_user_groups_from_local_sam: Failed to convert user SID %s to a uid!\n", + sid_to_string(str, user_sid))); + /* This might be a non-unix account */ + return NT_STATUS_OK; + } + + /* + * This is _essential_ to prevent occasional segfaults when + * winbind can't find uid -> username mapping + */ + if (!(usr = getpwuid_alloc(uid))) { + DEBUG(0, ("Couldn't find passdb structure for UID = %d ! Aborting.\n", uid)); + return NT_STATUS_NO_SUCH_USER; + }; + + n_unix_groups = groups_max(); + if ((*unix_groups = malloc( sizeof(gid_t) * groups_max() ) ) == NULL) { + DEBUG(0, ("get_user_groups_from_local_sam: Out of memory allocating unix group list\n")); + passwd_free(&usr); + return NT_STATUS_NO_MEMORY; + } + + if (sys_getgrouplist(usr->pw_name, usr->pw_gid, *unix_groups, &n_unix_groups) == -1) { + *unix_groups = Realloc(unix_groups, sizeof(gid_t) * n_unix_groups); + if (sys_getgrouplist(usr->pw_name, usr->pw_gid, *unix_groups, &n_unix_groups) == -1) { + DEBUG(0, ("get_user_groups_from_local_sam: failed to get the unix group list\n")); + SAFE_FREE(unix_groups); + passwd_free(&usr); + return NT_STATUS_NO_SUCH_USER; /* what should this return value be? */ + } + } + + debug_unix_user_token(DBGC_CLASS, 5, usr->pw_uid, usr->pw_gid, n_unix_groups, *unix_groups); + + passwd_free(&usr); + + if (n_unix_groups > 0) { + *groups = malloc(sizeof(DOM_SID) * n_unix_groups); + if (!*groups) { + DEBUG(0, ("get_user_group_from_local_sam: malloc() failed for DOM_SID list!\n")); + SAFE_FREE(unix_groups); + return NT_STATUS_NO_MEMORY; + } + } + + *n_groups = n_unix_groups; + + for (i = 0; i < *n_groups; i++) { + if (!gid_to_sid(&(*groups)[i], (*unix_groups)[i])) { + DEBUG(1, ("get_user_groups_from_local_sam: failed to convert gid %ld to a sid!\n", (long int)unix_groups[i+1])); + SAFE_FREE(groups); + SAFE_FREE(unix_groups); + return NT_STATUS_NO_SUCH_USER; + } + } + + return NT_STATUS_OK; } /*************************************************************************** Make a user_info struct ***************************************************************************/ -static BOOL make_server_info(auth_serversupplied_info **server_info) +static NTSTATUS make_server_info(auth_serversupplied_info **server_info, SAM_ACCOUNT *sampass) { *server_info = malloc(sizeof(**server_info)); if (!*server_info) { DEBUG(0,("make_server_info: malloc failed!\n")); - return False; + return NT_STATUS_NO_MEMORY; } ZERO_STRUCTP(*server_info); - return True; + + (*server_info)->sam_fill_level = SAM_FILL_ALL; + (*server_info)->sam_account = sampass; + + return NT_STATUS_OK; } /*************************************************************************** Make (and fill) a user_info struct from a SAM_ACCOUNT ***************************************************************************/ -BOOL make_server_info_sam(auth_serversupplied_info **server_info, SAM_ACCOUNT *sampass) +NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info, + SAM_ACCOUNT *sampass) { - if (!make_server_info(server_info)) { - return False; + NTSTATUS nt_status = NT_STATUS_OK; + const DOM_SID *user_sid = pdb_get_user_sid(sampass); + const DOM_SID *group_sid = pdb_get_group_sid(sampass); + int n_groupSIDs = 0; + DOM_SID *groupSIDs = NULL; + gid_t *unix_groups = NULL; + NT_USER_TOKEN *token; + BOOL is_guest; + uint32 rid; + + if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info, sampass))) { + return nt_status; } + + if (!NT_STATUS_IS_OK(nt_status + = get_user_groups_from_local_sam(pdb_get_user_sid(sampass), + &n_groupSIDs, &groupSIDs, &unix_groups))) + { + DEBUG(4,("get_user_groups_from_local_sam failed\n")); + free_server_info(server_info); + return nt_status; + } + + is_guest = (sid_peek_rid(user_sid, &rid) && rid == DOMAIN_USER_RID_GUEST); - (*server_info)->sam_fill_level = SAM_FILL_ALL; - (*server_info)->sam_account = sampass; + if (!NT_STATUS_IS_OK(nt_status = create_nt_user_token(user_sid, group_sid, + n_groupSIDs, groupSIDs, is_guest, + &token))) + { + DEBUG(4,("create_nt_user_token failed\n")); + SAFE_FREE(groupSIDs); + SAFE_FREE(unix_groups); + free_server_info(server_info); + return nt_status; + } + + SAFE_FREE(groupSIDs); + (*server_info)->n_groups = n_groupSIDs; + (*server_info)->groups = unix_groups; + + (*server_info)->ptok = token; + DEBUG(5,("make_server_info_sam: made server info for user %s\n", pdb_get_username((*server_info)->sam_account))); - return True; + + return nt_status; } /*************************************************************************** @@ -493,75 +795,42 @@ BOOL make_server_info_sam(auth_serversupplied_info **server_info, SAM_ACCOUNT *s to a SAM_ACCOUNT ***************************************************************************/ -BOOL make_server_info_pw(auth_serversupplied_info **server_info, const struct passwd *pwd) +NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, const struct passwd *pwd) { + NTSTATUS nt_status; SAM_ACCOUNT *sampass = NULL; - if (!NT_STATUS_IS_OK(pdb_init_sam_pw(&sampass, pwd))) { - return False; + if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sampass, pwd))) { + return nt_status; } return make_server_info_sam(server_info, sampass); } /*************************************************************************** - Free a user_info struct + Make (and fill) a user_info struct for a guest login. ***************************************************************************/ -void free_user_info(auth_usersupplied_info **user_info) +NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info) { - DEBUG(5,("attempting to free (and zero) a user_info structure\n")); - if (*user_info != NULL) { - if ((*user_info)->smb_name.str) { - DEBUG(10,("structure was created for %s\n", (*user_info)->smb_name.str)); - } - SAFE_FREE((*user_info)->smb_name.str); - SAFE_FREE((*user_info)->internal_username.str); - SAFE_FREE((*user_info)->client_domain.str); - SAFE_FREE((*user_info)->domain.str); - SAFE_FREE((*user_info)->wksta_name.str); - data_blob_free(&(*user_info)->lm_resp); - data_blob_free(&(*user_info)->nt_resp); - SAFE_FREE((*user_info)->interactive_password); - data_blob_clear_free(&(*user_info)->plaintext_password); - ZERO_STRUCT(**user_info); + NTSTATUS nt_status; + SAM_ACCOUNT *sampass = NULL; + DOM_SID guest_sid; + + if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sampass))) { + return nt_status; } - SAFE_FREE(*user_info); -} -/*************************************************************************** - Clear out a server_info struct that has been allocated -***************************************************************************/ + sid_copy(&guest_sid, get_global_sam_sid()); + sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST); -void free_server_info(auth_serversupplied_info **server_info) -{ - if (*server_info != NULL) { - pdb_free_sam(&(*server_info)->sam_account); - - /* call pam_end here, unless we know we are keeping it */ - delete_nt_token( &(*server_info)->ptok ); - ZERO_STRUCT(**server_info); + if (!pdb_getsampwsid(sampass, &guest_sid)) { + return NT_STATUS_NO_SUCH_USER; } - SAFE_FREE(*server_info); -} -/*************************************************************************** - Make a server_info struct for a guest user -***************************************************************************/ + nt_status = make_server_info_sam(server_info, sampass); -BOOL make_server_info_guest(auth_serversupplied_info **server_info) -{ - struct passwd *pass = getpwnam_alloc(lp_guestaccount()); - - if (pass) { - if (!make_server_info_pw(server_info, pass)) { - passwd_free(&pass); - return False; - } - (*server_info)->guest = True; - passwd_free(&pass); - return True; - } - DEBUG(0,("make_server_info_guest: getpwnam_alloc() failed on guest account!\n")); - return False; + (*server_info)->guest = True; + + return nt_status; } /*************************************************************************** @@ -589,6 +858,15 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, uid_t uid; gid_t gid; + int n_lgroupSIDs; + DOM_SID *lgroupSIDs = NULL; + + gid_t *unix_groups = NULL; + NT_USER_TOKEN *token; + + DOM_SID *all_group_SIDs; + int i; + /* Here is where we should check the list of trusted domains, and verify that the SID @@ -698,49 +976,128 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } - if (!make_server_info_sam(server_info, sam_account)) { - DEBUG(0, ("make_server_info_info3: make_server_info_sam failed!\n")); + if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info, sam_account))) { + DEBUG(4, ("make_server_info failed!\n")); pdb_free_sam(&sam_account); - return NT_STATUS_NO_MEMORY; + return nt_status; } /* Store the user group information in the server_info returned to the caller. */ - if (info3->num_groups2 != 0) { - int i; - NT_USER_TOKEN *ptok; - auth_serversupplied_info *pserver_info = *server_info; - - if ((pserver_info->ptok = malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) { - DEBUG(0, ("domain_client_validate: out of memory allocating rid group membership\n")); - nt_status = NT_STATUS_NO_MEMORY; - free_server_info(server_info); - return nt_status; - } - - ptok = pserver_info->ptok; - ptok->num_sids = (size_t)info3->num_groups2; - - if ((ptok->user_sids = (DOM_SID *)malloc( sizeof(DOM_SID) * ptok->num_sids )) == NULL) { - DEBUG(0, ("domain_client_validate: Out of memory allocating group SIDS\n")); - nt_status = NT_STATUS_NO_MEMORY; - free_server_info(server_info); + if (!NT_STATUS_IS_OK(nt_status + = get_user_groups_from_local_sam(&user_sid, + &n_lgroupSIDs, + &lgroupSIDs, + &unix_groups))) + { + DEBUG(4,("get_user_groups_from_local_sam failed\n")); + return nt_status; + } + + (*server_info)->groups = unix_groups; + (*server_info)->n_groups = n_lgroupSIDs; + + /* Create a 'combined' list of all SIDs we might want in the SD */ + all_group_SIDs = malloc(sizeof(DOM_SID) * + (n_lgroupSIDs + info3->num_groups2 + + info3->num_other_sids)); + if (!all_group_SIDs) { + DEBUG(0, ("create_nt_token_info3: malloc() failed for DOM_SID list!\n")); + SAFE_FREE(lgroupSIDs); + return NT_STATUS_NO_MEMORY; + } + + /* Copy the 'local' sids */ + memcpy(all_group_SIDs, lgroupSIDs, sizeof(DOM_SID) * n_lgroupSIDs); + SAFE_FREE(lgroupSIDs); + + /* and create (by appending rids) the 'domain' sids */ + for (i = 0; i < info3->num_groups2; i++) { + sid_copy(&all_group_SIDs[i+n_lgroupSIDs], &(info3->dom_sid.sid)); + if (!sid_append_rid(&all_group_SIDs[i+n_lgroupSIDs], info3->gids[i].g_rid)) { + nt_status = NT_STATUS_INVALID_PARAMETER; + DEBUG(3,("create_nt_token_info3: could not append additional group rid 0x%x\n", + info3->gids[i].g_rid)); + SAFE_FREE(lgroupSIDs); return nt_status; } - - for (i = 0; i < ptok->num_sids; i++) { - sid_copy(&ptok->user_sids[i], &(info3->dom_sid.sid)); - if (!sid_append_rid(&ptok->user_sids[i], info3->gids[i].g_rid)) { - nt_status = NT_STATUS_INVALID_PARAMETER; - free_server_info(server_info); - return nt_status; - } - } } + + /* Copy 'other' sids. We need to do sid filtering here to + prevent possible elevation of privileges. See: + + http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp + */ + + for (i = 0; i < info3->num_other_sids; i++) + sid_copy(&all_group_SIDs[ + n_lgroupSIDs + info3->num_groups2 + i], + &info3->other_sids[i].sid); + + /* Where are the 'global' sids... */ + + /* can the user be guest? if yes, where is it stored? */ + if (!NT_STATUS_IS_OK( + nt_status = create_nt_user_token( + &user_sid, &group_sid, + n_lgroupSIDs + info3->num_groups2 + info3->num_other_sids, + all_group_SIDs, False, &token))) { + DEBUG(4,("create_nt_user_token failed\n")); + SAFE_FREE(all_group_SIDs); + return nt_status; + } + + (*server_info)->ptok = token; + + SAFE_FREE(all_group_SIDs); + return NT_STATUS_OK; } +/*************************************************************************** + Free a user_info struct +***************************************************************************/ + +void free_user_info(auth_usersupplied_info **user_info) +{ + DEBUG(5,("attempting to free (and zero) a user_info structure\n")); + if (*user_info != NULL) { + if ((*user_info)->smb_name.str) { + DEBUG(10,("structure was created for %s\n", (*user_info)->smb_name.str)); + } + SAFE_FREE((*user_info)->smb_name.str); + SAFE_FREE((*user_info)->internal_username.str); + SAFE_FREE((*user_info)->client_domain.str); + SAFE_FREE((*user_info)->domain.str); + SAFE_FREE((*user_info)->wksta_name.str); + data_blob_free(&(*user_info)->lm_resp); + data_blob_free(&(*user_info)->nt_resp); + SAFE_FREE((*user_info)->interactive_password); + data_blob_clear_free(&(*user_info)->plaintext_password); + ZERO_STRUCT(**user_info); + } + SAFE_FREE(*user_info); +} + +/*************************************************************************** + Clear out a server_info struct that has been allocated +***************************************************************************/ + +void free_server_info(auth_serversupplied_info **server_info) +{ + DEBUG(5,("attempting to free (and zero) a server_info structure\n")); + if (*server_info != NULL) { + pdb_free_sam(&(*server_info)->sam_account); + + /* call pam_end here, unless we know we are keeping it */ + delete_nt_token( &(*server_info)->ptok ); + SAFE_FREE((*server_info)->groups); + ZERO_STRUCT(**server_info); + } + SAFE_FREE(*server_info); +} + /*************************************************************************** Make an auth_methods struct ***************************************************************************/ diff --git a/source3/auth/auth_winbind.c b/source3/auth/auth_winbind.c index 5bdccd39f3e..10788721fde 100644 --- a/source3/auth/auth_winbind.c +++ b/source3/auth/auth_winbind.c @@ -4,7 +4,7 @@ Winbind authentication mechnism Copyright (C) Tim Potter 2000 - Copyright (C) Andrew Bartlett 2001 + Copyright (C) Andrew Bartlett 2001 - 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/source3/client/client.c b/source3/client/client.c index a421f36d809..eb6b5727608 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. SMB client Copyright (C) Andrew Tridgell 1994-1998 - Copyright (C) Simo Sorce 2001 + Copyright (C) Simo Sorce 2001-2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -307,7 +307,7 @@ static BOOL do_this_one(file_info *finfo) if (*fileselection && !mask_match(finfo->name,fileselection,False)) { - DEBUG(3,("match_match %s failed\n", finfo->name)); + DEBUG(3,("mask_match %s failed\n", finfo->name)); return False; } @@ -649,15 +649,16 @@ static int cmd_du(void) /**************************************************************************** get a file from rname to lname ****************************************************************************/ -static int do_get(char *rname,char *lname) +static int do_get(char *rname, char *lname, BOOL reget) { - int handle=0,fnum; + int handle = 0, fnum; BOOL newhandle = False; char *data; struct timeval tp_start; int read_size = io_bufsize; uint16 attr; size_t size; + off_t start = 0; off_t nread = 0; int rc = 0; @@ -677,7 +678,18 @@ static int do_get(char *rname,char *lname) if(!strcmp(lname,"-")) { handle = fileno(stdout); } else { - handle = sys_open(lname,O_WRONLY|O_CREAT|O_TRUNC,0644); + if (reget) { + handle = sys_open(lname, O_WRONLY|O_CREAT, 0644); + if (handle >= 0) { + start = sys_lseek(handle, 0, SEEK_END); + if (start == -1) { + d_printf("Error seeking local file\n"); + return 1; + } + } + } else { + handle = sys_open(lname, O_WRONLY|O_CREAT|O_TRUNC, 0644); + } newhandle = True; } if (handle < 0) { @@ -695,7 +707,7 @@ static int do_get(char *rname,char *lname) } DEBUG(2,("getting file %s of size %.0f as %s ", - lname, (double)size, lname)); + rname, (double)size, lname)); if(!(data = (char *)malloc(read_size))) { d_printf("malloc fail for size %d\n", read_size); @@ -704,7 +716,7 @@ static int do_get(char *rname,char *lname) } while (1) { - int n = cli_read(cli, fnum, data, nread, read_size); + int n = cli_read(cli, fnum, data, nread + start, read_size); if (n <= 0) break; @@ -717,7 +729,7 @@ static int do_get(char *rname,char *lname) nread += n; } - if (nread < size) { + if (nread + start < size) { DEBUG (0, ("Short read when getting file %s. Only got %ld bytes.\n", rname, (long)nread)); @@ -782,7 +794,7 @@ static int cmd_get(void) next_token_nr(NULL,lname,NULL,sizeof(lname)); - return do_get(rname, lname); + return do_get(rname, lname, False); } @@ -816,7 +828,7 @@ static void do_mget(file_info *finfo) if (!(finfo->mode & aDIR)) { pstrcpy(rname,cur_dir); pstrcat(rname,finfo->name); - do_get(rname,finfo->name); + do_get(rname, finfo->name, False); return; } @@ -880,7 +892,7 @@ static int cmd_more(void) } dos_clean_name(rname); - rc = do_get(rname,lname); + rc = do_get(rname, lname, False); pager=getenv("PAGER"); @@ -1046,19 +1058,31 @@ static int cmd_altname(void) /**************************************************************************** put a single file ****************************************************************************/ -static int do_put(char *rname,char *lname) +static int do_put(char *rname, char *lname, BOOL reput) { int fnum; XFILE *f; - int nread=0; - char *buf=NULL; - int maxwrite=io_bufsize; + int start = 0; + int nread = 0; + char *buf = NULL; + int maxwrite = io_bufsize; int rc = 0; struct timeval tp_start; GetTimeOfDay(&tp_start); - fnum = cli_open(cli, rname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE); + if (reput) { + fnum = cli_open(cli, rname, O_RDWR|O_CREAT, DENY_NONE); + if (fnum >= 0) { + if (!cli_qfileinfo(cli, fnum, NULL, &start, NULL, NULL, NULL, NULL, NULL) && + !cli_getattrE(cli, fnum, NULL, &start, NULL, NULL, NULL)) { + d_printf("getattrib: %s\n",cli_errstr(cli)); + return 1; + } + } + } else { + fnum = cli_open(cli, rname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE); + } if (fnum == -1) { d_printf("%s opening remote file %s\n",cli_errstr(cli),rname); @@ -1075,6 +1099,12 @@ static int do_put(char *rname,char *lname) /* size of file is not known */ } else { f = x_fopen(lname,O_RDONLY, 0); + if (f && reput) { + if (x_tseek(f, start, SEEK_SET) == -1) { + d_printf("Error seeking local file\n"); + return 1; + } + } } if (!f) { @@ -1104,7 +1134,7 @@ static int do_put(char *rname,char *lname) break; } - ret = cli_write(cli, fnum, 0, buf, nread, n); + ret = cli_write(cli, fnum, 0, buf, nread + start, n); if (n != ret) { d_printf("Error writing file: %s\n", cli_errstr(cli)); @@ -1192,7 +1222,7 @@ static int cmd_put(void) } } - return do_put(rname,lname); + return do_put(rname, lname, False); } /************************************* @@ -1384,7 +1414,7 @@ static int cmd_mput(void) dos_format(rname); - do_put(rname, lname); + do_put(rname, lname, False); } free_file_list(file_list); SAFE_FREE(quest); @@ -1456,7 +1486,7 @@ static int cmd_print(void) slprintf(rname, sizeof(rname)-1, "stdin-%d", (int)sys_getpid()); } - return do_put(rname, lname); + return do_put(rname, lname, False); } @@ -1866,8 +1896,8 @@ static int cmd_printmode(void) } /**************************************************************************** -do the lcd command -****************************************************************************/ + do the lcd command + ****************************************************************************/ static int cmd_lcd(void) { fstring buf; @@ -1881,8 +1911,70 @@ static int cmd_lcd(void) } /**************************************************************************** -list a share name -****************************************************************************/ + get a file restarting at end of local file + ****************************************************************************/ +static int cmd_reget(void) +{ + pstring local_name; + pstring remote_name; + char *p; + + pstrcpy(remote_name, cur_dir); + pstrcat(remote_name, "\\"); + + p = remote_name + strlen(remote_name); + + if (!next_token_nr(NULL, p, NULL, sizeof(remote_name) - strlen(remote_name))) { + d_printf("reget \n"); + return 1; + } + pstrcpy(local_name, p); + dos_clean_name(remote_name); + + next_token_nr(NULL, local_name, NULL, sizeof(local_name)); + + return do_get(remote_name, local_name, True); +} + +/**************************************************************************** + put a file restarting at end of local file + ****************************************************************************/ +static int cmd_reput(void) +{ + pstring local_name; + pstring remote_name; + fstring buf; + char *p = buf; + SMB_STRUCT_STAT st; + + pstrcpy(remote_name, cur_dir); + pstrcat(remote_name, "\\"); + + if (!next_token_nr(NULL, p, NULL, sizeof(buf))) { + d_printf("reput \n"); + return 1; + } + pstrcpy(local_name, p); + + if (!file_exist(local_name, &st)) { + d_printf("%s does not exist\n", local_name); + return 1; + } + + if (next_token_nr(NULL, p, NULL, sizeof(buf))) + pstrcat(remote_name, p); + else + pstrcat(remote_name, local_name); + + dos_clean_name(remote_name); + + return do_put(remote_name, local_name, True); +} + + +/**************************************************************************** + list a share name + ****************************************************************************/ static void browse_fn(const char *name, uint32 m, const char *comment, void *state) { @@ -2009,7 +2101,9 @@ static struct {"quit",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}}, {"rd",cmd_rmdir," remove a directory",{COMPL_NONE,COMPL_NONE}}, {"recurse",cmd_recurse,"toggle directory recursion for mget and mput",{COMPL_NONE,COMPL_NONE}}, + {"reget",cmd_reget," [local name] get a file restarting at end of local file",{COMPL_REMOTE,COMPL_LOCAL}}, {"rename",cmd_rename," rename some files",{COMPL_REMOTE,COMPL_REMOTE}}, + {"reput",cmd_reput," [remote name] put a file restarting at end of remote file",{COMPL_LOCAL,COMPL_REMOTE}}, {"rm",cmd_del," delete all matching files",{COMPL_REMOTE,COMPL_NONE}}, {"rmdir",cmd_rmdir," remove a directory",{COMPL_NONE,COMPL_NONE}}, {"setmode",cmd_setmode,"filename change modes of file",{COMPL_REMOTE,COMPL_NONE}}, @@ -2524,16 +2618,21 @@ static int do_message_op(void) { struct in_addr ip; struct nmb_name called, calling; - - zero_ip(&ip); + fstring server_name; + char name_type_hex[10]; make_nmb_name(&calling, global_myname, 0x0); make_nmb_name(&called , desthost, name_type); + safe_strcpy(server_name, desthost, sizeof(server_name)); + snprintf(name_type_hex, sizeof(name_type_hex), "#%X", name_type); + safe_strcat(server_name, name_type_hex, sizeof(server_name)); + zero_ip(&ip); if (have_ip) ip = dest_ip; - if (!(cli=cli_initialise(NULL)) || (cli_set_port(cli, port) != port) || !cli_connect(cli, desthost, &ip)) { + if (!(cli=cli_initialise(NULL)) || (cli_set_port(cli, port) != port) || + !cli_connect(cli, server_name, &ip)) { d_printf("Connection to %s failed\n", desthost); return 1; } @@ -2659,7 +2758,6 @@ static void remember_query_host(const char *arg, got_pass = True; memset(strchr_m(getenv("USER"),'%')+1,'X',strlen(password)); } - strupper(username); } /* modification to support PASSWD environmental var @@ -2676,7 +2774,6 @@ static void remember_query_host(const char *arg, if (*username == 0 && getenv("LOGNAME")) { pstrcpy(username,getenv("LOGNAME")); - strupper(username); } if (*username == 0) { diff --git a/source3/client/smbmnt.c b/source3/client/smbmnt.c index ba2b1e9435d..ce406179cfd 100644 --- a/source3/client/smbmnt.c +++ b/source3/client/smbmnt.c @@ -148,8 +148,8 @@ do_mount(char *share_name, unsigned int flags, struct smb_mount_data *data) uname(&uts); release = uts.release; - major = strsep(&release, "."); - minor = strsep(&release, "."); + major = strtok(release, "."); + minor = strtok(NULL, "."); if (major && minor && atoi(major) == 2 && atoi(minor) < 4) { /* < 2.4, assume struct */ data1 = (char *) data; diff --git a/source3/configure b/source3/configure index 06694c8e64a..538f44621c8 100755 --- a/source3/configure +++ b/source3/configure @@ -46,8 +46,12 @@ ac_help="$ac_help --with-afs Include AFS clear-text auth support (default=no) " ac_help="$ac_help --with-dce-dfs Include DCE/DFS clear-text auth support (default=no)" +ac_help="$ac_help + --with-ads Active Directory support (default yes)" ac_help="$ac_help --with-krb5=base-dir Locate Kerberos 5 support (default=/usr)" +ac_help="$ac_help + --with-ldap LDAP support (default yes)" ac_help="$ac_help --with-automount Include AUTOMOUNT support (default=no)" ac_help="$ac_help @@ -56,6 +60,8 @@ ac_help="$ac_help --with-pam Include PAM support (default=no)" ac_help="$ac_help --with-pam_smbpass Build a PAM module to allow other applications to use our smbpasswd file (default=no)" +ac_help="$ac_help + --with-sam Build new (experimental) SAM database (default=no)" ac_help="$ac_help --with-tdbsam Include experimental TDB SAM support (default=no)" ac_help="$ac_help @@ -78,10 +84,14 @@ ac_help="$ac_help --with-spinlocks Use spin locks instead of fcntl locks (default=no) " ac_help="$ac_help --with-acl-support Include ACL support (default=no)" +ac_help="$ac_help + --with-sendfile-support Include sendfile support (default=no)" ac_help="$ac_help --with-winbind Build winbind (default, if supported by OS)" ac_help="$ac_help --with-included-popt use bundled popt library, not from system" +ac_help="$ac_help + --with-python=PYTHONNAME build Python libraries" # Initialize some variables set by options. # The variables have the same names as the options, with @@ -758,6 +768,7 @@ fi + # compile with optimization and without debugging by default @@ -813,7 +824,7 @@ fi # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:817: checking for $ac_word" >&5 +echo "configure:828: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -843,7 +854,7 @@ if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:847: checking for $ac_word" >&5 +echo "configure:858: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -894,7 +905,7 @@ fi # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:898: checking for $ac_word" >&5 +echo "configure:909: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -926,7 +937,7 @@ fi fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:930: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:941: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. @@ -937,12 +948,12 @@ cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF -#line 941 "configure" +#line 952 "configure" #include "confdefs.h" main(){return(0);} EOF -if { (eval echo configure:946: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:957: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -968,12 +979,12 @@ if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:972: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:983: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:977: checking whether we are using GNU C" >&5 +echo "configure:988: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -982,7 +993,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:986: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:997: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -1001,7 +1012,7 @@ ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:1005: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:1016: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1063,7 +1074,7 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:1067: checking for a BSD compatible install" >&5 +echo "configure:1078: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1120,7 +1131,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1124: checking for $ac_word" >&5 +echo "configure:1135: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1152,7 +1163,7 @@ done LD=ld echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6 -echo "configure:1156: checking if the linker ($LD) is GNU ld" >&5 +echo "configure:1167: checking if the linker ($LD) is GNU ld" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1168,7 +1179,7 @@ echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6 echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6 -echo "configure:1172: checking for POSIXized ISC" >&5 +echo "configure:1183: checking for POSIXized ISC" >&5 if test -d /etc/conf/kconfig.d && grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1 then @@ -1191,10 +1202,10 @@ fi if test "x$CC" != xcc; then echo $ac_n "checking whether $CC and cc understand -c and -o together""... $ac_c" 1>&6 -echo "configure:1195: checking whether $CC and cc understand -c and -o together" >&5 +echo "configure:1206: checking whether $CC and cc understand -c and -o together" >&5 else echo $ac_n "checking whether cc understands -c and -o together""... $ac_c" 1>&6 -echo "configure:1198: checking whether cc understands -c and -o together" >&5 +echo "configure:1209: checking whether cc understands -c and -o together" >&5 fi set dummy $CC; ac_cc="`echo $2 | sed -e 's/[^a-zA-Z0-9_]/_/g' -e 's/^[0-9]/_/'`" @@ -1206,16 +1217,16 @@ else # We do the test twice because some compilers refuse to overwrite an # existing .o file with -o, though they will create one. ac_try='${CC-cc} -c conftest.c -o conftest.o 1>&5' -if { (eval echo configure:1210: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } && - test -f conftest.o && { (eval echo configure:1211: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; +if { (eval echo configure:1221: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } && + test -f conftest.o && { (eval echo configure:1222: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; then eval ac_cv_prog_cc_${ac_cc}_c_o=yes if test "x$CC" != xcc; then # Test first that cc exists at all. - if { ac_try='cc -c conftest.c 1>&5'; { (eval echo configure:1216: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then + if { ac_try='cc -c conftest.c 1>&5'; { (eval echo configure:1227: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then ac_try='cc -c conftest.c -o conftest.o 1>&5' - if { (eval echo configure:1218: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } && - test -f conftest.o && { (eval echo configure:1219: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; + if { (eval echo configure:1229: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } && + test -f conftest.o && { (eval echo configure:1230: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; then # cc works too. : @@ -1249,20 +1260,20 @@ fi echo $ac_n "checking that the C compiler understands volatile""... $ac_c" 1>&6 -echo "configure:1253: checking that the C compiler understands volatile" >&5 +echo "configure:1264: checking that the C compiler understands volatile" >&5 if eval "test \"`echo '$''{'samba_cv_volatile'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { volatile int i = 0 ; return 0; } EOF -if { (eval echo configure:1266: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1277: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_volatile=yes else @@ -1311,7 +1322,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:1315: checking host system type" >&5 +echo "configure:1326: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -1332,7 +1343,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$host" 1>&6 echo $ac_n "checking target system type""... $ac_c" 1>&6 -echo "configure:1336: checking target system type" >&5 +echo "configure:1347: checking target system type" >&5 target_alias=$target case "$target_alias" in @@ -1350,7 +1361,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$target" 1>&6 echo $ac_n "checking build system type""... $ac_c" 1>&6 -echo "configure:1354: checking build system type" >&5 +echo "configure:1365: checking build system type" >&5 build_alias=$build case "$build_alias" in @@ -1384,7 +1395,7 @@ esac echo $ac_n "checking config.cache system type""... $ac_c" 1>&6 -echo "configure:1388: checking config.cache system type" >&5 +echo "configure:1399: checking config.cache system type" >&5 if { test x"${ac_cv_host_system_type+set}" = x"set" && test x"$ac_cv_host_system_type" != x"$host"; } || { test x"${ac_cv_build_system_type+set}" = x"set" && @@ -1412,7 +1423,7 @@ case "$host_os" in *hpux*) echo $ac_n "checking whether ${CC-cc} accepts -Ae""... $ac_c" 1>&6 -echo "configure:1416: checking whether ${CC-cc} accepts -Ae" >&5 +echo "configure:1427: checking whether ${CC-cc} accepts -Ae" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_Ae'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1573,14 +1584,14 @@ EOF *sysv4*) if test $host = mips-sni-sysv4 ; then echo $ac_n "checking for LFS support""... $ac_c" 1>&6 -echo "configure:1577: checking for LFS support" >&5 +echo "configure:1588: checking for LFS support" >&5 old_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-D_LARGEFILE64_SOURCE $CPPFLAGS" if test "$cross_compiling" = yes; then SINIX_LFS_SUPPORT=cross else cat > conftest.$ac_ext < @@ -1592,7 +1603,7 @@ exit(1); #endif } EOF -if { (eval echo configure:1596: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:1607: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then SINIX_LFS_SUPPORT=yes else @@ -1623,14 +1634,14 @@ EOF # *linux*) echo $ac_n "checking for LFS support""... $ac_c" 1>&6 -echo "configure:1627: checking for LFS support" >&5 +echo "configure:1638: checking for LFS support" >&5 old_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $CPPFLAGS" if test "$cross_compiling" = yes; then LINUX_LFS_SUPPORT=cross else cat > conftest.$ac_ext < @@ -1668,7 +1679,7 @@ main() { } EOF -if { (eval echo configure:1672: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:1683: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then LINUX_LFS_SUPPORT=yes else @@ -1701,14 +1712,14 @@ EOF *hurd*) echo $ac_n "checking for LFS support""... $ac_c" 1>&6 -echo "configure:1705: checking for LFS support" >&5 +echo "configure:1716: checking for LFS support" >&5 old_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-D_LARGEFILE64_SOURCE -D_GNU_SOURCE $CPPFLAGS" if test "$cross_compiling" = yes; then GLIBC_LFS_SUPPORT=cross else cat > conftest.$ac_ext < @@ -1720,7 +1731,7 @@ exit(1); #endif } EOF -if { (eval echo configure:1724: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:1735: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then GLIBC_LFS_SUPPORT=yes else @@ -1750,21 +1761,21 @@ EOF esac echo $ac_n "checking for inline""... $ac_c" 1>&6 -echo "configure:1754: checking for inline" >&5 +echo "configure:1765: checking for inline" >&5 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1779: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_inline=$ac_kw; break else @@ -1790,7 +1801,7 @@ EOF esac echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:1794: checking how to run the C preprocessor" >&5 +echo "configure:1805: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -1805,13 +1816,13 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1815: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1826: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1822,13 +1833,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1832: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1843: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1839,13 +1850,13 @@ else rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1849: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1860: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1870,12 +1881,12 @@ fi echo "$ac_t""$CPP" 1>&6 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:1874: checking for ANSI C header files" >&5 +echo "configure:1885: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -1883,7 +1894,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1887: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1898: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -1900,7 +1911,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -1918,7 +1929,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -1939,7 +1950,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -1950,7 +1961,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:1954: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:1965: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -1978,12 +1989,12 @@ for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6 -echo "configure:1982: checking for $ac_hdr that defines DIR" >&5 +echo "configure:1993: checking for $ac_hdr that defines DIR" >&5 if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include <$ac_hdr> @@ -1991,7 +2002,7 @@ int main() { DIR *dirp = 0; ; return 0; } EOF -if { (eval echo configure:1995: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2006: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* eval "ac_cv_header_dirent_$ac_safe=yes" else @@ -2016,7 +2027,7 @@ done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6 -echo "configure:2020: checking for opendir in -ldir" >&5 +echo "configure:2031: checking for opendir in -ldir" >&5 ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2024,7 +2035,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldir $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2050: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2057,7 +2068,7 @@ fi else echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6 -echo "configure:2061: checking for opendir in -lx" >&5 +echo "configure:2072: checking for opendir in -lx" >&5 ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2065,7 +2076,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lx $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2091: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2099,12 +2110,12 @@ fi fi echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 -echo "configure:2103: checking whether time.h and sys/time.h may both be included" >&5 +echo "configure:2114: checking whether time.h and sys/time.h may both be included" >&5 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -2113,7 +2124,7 @@ int main() { struct tm *tp; ; return 0; } EOF -if { (eval echo configure:2117: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2128: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_time=yes else @@ -2134,12 +2145,12 @@ EOF fi echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6 -echo "configure:2138: checking for sys/wait.h that is POSIX.1 compatible" >&5 +echo "configure:2149: checking for sys/wait.h that is POSIX.1 compatible" >&5 if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -2155,7 +2166,7 @@ wait (&s); s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; ; return 0; } EOF -if { (eval echo configure:2159: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2170: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_sys_wait_h=yes else @@ -2179,17 +2190,17 @@ for ac_hdr in arpa/inet.h sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2183: checking for $ac_hdr" >&5 +echo "configure:2194: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2193: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2204: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2219,17 +2230,17 @@ for ac_hdr in unistd.h utime.h grp.h sys/id.h limits.h memory.h net/if.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2223: checking for $ac_hdr" >&5 +echo "configure:2234: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2233: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2244: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2259,17 +2270,17 @@ for ac_hdr in compat.h rpc/rpc.h rpcsvc/nis.h rpcsvc/yp_prot.h rpcsvc/ypclnt.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2263: checking for $ac_hdr" >&5 +echo "configure:2274: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2273: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2284: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2299,17 +2310,17 @@ for ac_hdr in sys/param.h ctype.h sys/wait.h sys/resource.h sys/ioctl.h sys/ipc. do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2303: checking for $ac_hdr" >&5 +echo "configure:2314: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2313: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2324: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2339,17 +2350,17 @@ for ac_hdr in sys/mman.h sys/filio.h sys/priv.h sys/shm.h string.h strings.h std do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2343: checking for $ac_hdr" >&5 +echo "configure:2354: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2353: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2364: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2379,17 +2390,17 @@ for ac_hdr in sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h term do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2383: checking for $ac_hdr" >&5 +echo "configure:2394: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2393: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2404: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2419,17 +2430,17 @@ for ac_hdr in sys/termio.h sys/statfs.h sys/dustat.h sys/statvfs.h stdarg.h sys/ do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2423: checking for $ac_hdr" >&5 +echo "configure:2434: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2433: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2444: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2459,17 +2470,57 @@ for ac_hdr in security/pam_modules.h security/_pam_macros.h ldap.h lber.h dlfcn. do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2463: checking for $ac_hdr" >&5 +echo "configure:2474: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2473: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2484: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + +for ac_hdr in sys/syslog.h syslog.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2514: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2524: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2503,14 +2554,14 @@ done case "$host_os" in *hpux*) cat > conftest.$ac_ext < int main() { struct spwd testme ; return 0; } EOF -if { (eval echo configure:2514: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2565: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_shadow_h=yes else @@ -2532,17 +2583,17 @@ for ac_hdr in shadow.h netinet/ip.h netinet/tcp.h netinet/in_systm.h netinet/in_ do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2536: checking for $ac_hdr" >&5 +echo "configure:2587: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2546: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2597: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2572,17 +2623,17 @@ for ac_hdr in nss.h nss_common.h ns_api.h sys/security.h security/pam_appl.h sec do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2576: checking for $ac_hdr" >&5 +echo "configure:2627: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2586: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2637: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2612,17 +2663,17 @@ for ac_hdr in stropts.h poll.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2616: checking for $ac_hdr" >&5 +echo "configure:2667: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2626: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2677: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2652,17 +2703,17 @@ for ac_hdr in sys/capability.h syscall.h sys/syscall.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2656: checking for $ac_hdr" >&5 +echo "configure:2707: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2666: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2717: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2692,17 +2743,17 @@ for ac_hdr in sys/acl.h sys/cdefs.h glob.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2696: checking for $ac_hdr" >&5 +echo "configure:2747: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2706: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2757: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2734,17 +2785,17 @@ for ac_hdr in utmp.h utmpx.h lastlog.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2738: checking for $ac_hdr" >&5 +echo "configure:2789: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2748: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2799: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2776,17 +2827,17 @@ for ac_hdr in sys/fs/vx_quota.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2780: checking for $ac_hdr" >&5 +echo "configure:2831: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2790: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2841: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2818,17 +2869,17 @@ for ac_hdr in linux/xqm.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2822: checking for $ac_hdr" >&5 +echo "configure:2873: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2832: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2883: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2856,7 +2907,7 @@ done echo $ac_n "checking size of int""... $ac_c" 1>&6 -echo "configure:2860: checking size of int" >&5 +echo "configure:2911: checking size of int" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2864,7 +2915,7 @@ else ac_cv_sizeof_int=cross else cat > conftest.$ac_ext < int main() @@ -2875,7 +2926,7 @@ int main() return(0); } EOF -if { (eval echo configure:2879: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2930: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_int=`cat conftestval` else @@ -2895,7 +2946,7 @@ EOF echo $ac_n "checking size of long""... $ac_c" 1>&6 -echo "configure:2899: checking size of long" >&5 +echo "configure:2950: checking size of long" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2903,7 +2954,7 @@ else ac_cv_sizeof_long=cross else cat > conftest.$ac_ext < int main() @@ -2914,7 +2965,7 @@ int main() return(0); } EOF -if { (eval echo configure:2918: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2969: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long=`cat conftestval` else @@ -2934,7 +2985,7 @@ EOF echo $ac_n "checking size of short""... $ac_c" 1>&6 -echo "configure:2938: checking size of short" >&5 +echo "configure:2989: checking size of short" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2942,7 +2993,7 @@ else ac_cv_sizeof_short=cross else cat > conftest.$ac_ext < int main() @@ -2953,7 +3004,7 @@ int main() return(0); } EOF -if { (eval echo configure:2957: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:3008: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_short=`cat conftestval` else @@ -2974,12 +3025,12 @@ EOF echo $ac_n "checking for working const""... $ac_c" 1>&6 -echo "configure:2978: checking for working const" >&5 +echo "configure:3029: checking for working const" >&5 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3083: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else @@ -3049,21 +3100,21 @@ EOF fi echo $ac_n "checking for inline""... $ac_c" 1>&6 -echo "configure:3053: checking for inline" >&5 +echo "configure:3104: checking for inline" >&5 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3118: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_inline=$ac_kw; break else @@ -3089,14 +3140,14 @@ EOF esac echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6 -echo "configure:3093: checking whether byte ordering is bigendian" >&5 +echo "configure:3144: checking whether byte ordering is bigendian" >&5 if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_bigendian=unknown # See if sys/param.h defines the BYTE_ORDER macro. cat > conftest.$ac_ext < #include @@ -3107,11 +3158,11 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:3111: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3162: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* # It does; now see whether it defined to BIG_ENDIAN or not. cat > conftest.$ac_ext < #include @@ -3122,7 +3173,7 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:3126: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3177: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_bigendian=yes else @@ -3142,7 +3193,7 @@ if test "$cross_compiling" = yes; then { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:3210: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_bigendian=no else @@ -3179,14 +3230,14 @@ EOF fi echo $ac_n "checking whether char is unsigned""... $ac_c" 1>&6 -echo "configure:3183: checking whether char is unsigned" >&5 +echo "configure:3234: checking whether char is unsigned" >&5 if eval "test \"`echo '$''{'ac_cv_c_char_unsigned'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$GCC" = yes; then # GCC predefines this symbol on systems where it applies. cat > conftest.$ac_ext <&2; exit 1; } else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:3273: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_char_unsigned=yes else @@ -3243,12 +3294,12 @@ fi echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 -echo "configure:3247: checking return type of signal handlers" >&5 +echo "configure:3298: checking return type of signal handlers" >&5 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -3265,7 +3316,7 @@ int main() { int i; ; return 0; } EOF -if { (eval echo configure:3269: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3320: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_signal=void else @@ -3284,12 +3335,12 @@ EOF echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6 -echo "configure:3288: checking for uid_t in sys/types.h" >&5 +echo "configure:3339: checking for uid_t in sys/types.h" >&5 if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF @@ -3318,12 +3369,12 @@ EOF fi echo $ac_n "checking for mode_t""... $ac_c" 1>&6 -echo "configure:3322: checking for mode_t" >&5 +echo "configure:3373: checking for mode_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -3351,12 +3402,12 @@ EOF fi echo $ac_n "checking for off_t""... $ac_c" 1>&6 -echo "configure:3355: checking for off_t" >&5 +echo "configure:3406: checking for off_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -3384,12 +3435,12 @@ EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 -echo "configure:3388: checking for size_t" >&5 +echo "configure:3439: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -3417,12 +3468,12 @@ EOF fi echo $ac_n "checking for pid_t""... $ac_c" 1>&6 -echo "configure:3421: checking for pid_t" >&5 +echo "configure:3472: checking for pid_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -3450,12 +3501,12 @@ EOF fi echo $ac_n "checking for st_rdev in struct stat""... $ac_c" 1>&6 -echo "configure:3454: checking for st_rdev in struct stat" >&5 +echo "configure:3505: checking for st_rdev in struct stat" >&5 if eval "test \"`echo '$''{'ac_cv_struct_st_rdev'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -3463,7 +3514,7 @@ int main() { struct stat s; s.st_rdev; ; return 0; } EOF -if { (eval echo configure:3467: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3518: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_st_rdev=yes else @@ -3484,12 +3535,12 @@ EOF fi echo $ac_n "checking for d_off in dirent""... $ac_c" 1>&6 -echo "configure:3488: checking for d_off in dirent" >&5 +echo "configure:3539: checking for d_off in dirent" >&5 if eval "test \"`echo '$''{'ac_cv_dirent_d_off'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -3499,7 +3550,7 @@ int main() { struct dirent d; d.d_off; ; return 0; } EOF -if { (eval echo configure:3503: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3554: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_dirent_d_off=yes else @@ -3520,12 +3571,12 @@ EOF fi echo $ac_n "checking for ino_t""... $ac_c" 1>&6 -echo "configure:3524: checking for ino_t" >&5 +echo "configure:3575: checking for ino_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_ino_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -3553,12 +3604,12 @@ EOF fi echo $ac_n "checking for loff_t""... $ac_c" 1>&6 -echo "configure:3557: checking for loff_t" >&5 +echo "configure:3608: checking for loff_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_loff_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -3586,12 +3637,12 @@ EOF fi echo $ac_n "checking for offset_t""... $ac_c" 1>&6 -echo "configure:3590: checking for offset_t" >&5 +echo "configure:3641: checking for offset_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_offset_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -3619,12 +3670,12 @@ EOF fi echo $ac_n "checking for ssize_t""... $ac_c" 1>&6 -echo "configure:3623: checking for ssize_t" >&5 +echo "configure:3674: checking for ssize_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_ssize_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -3652,12 +3703,12 @@ EOF fi echo $ac_n "checking for wchar_t""... $ac_c" 1>&6 -echo "configure:3656: checking for wchar_t" >&5 +echo "configure:3707: checking for wchar_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_wchar_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -3699,7 +3750,7 @@ if test x$enable_cups != xno; then # Extract the first word of "cups-config", so it can be a program name with args. set dummy cups-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3703: checking for $ac_word" >&5 +echo "configure:3754: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_CUPS_CONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3739,7 +3790,7 @@ EOF CFLAGS="$CFLAGS `$CUPS_CONFIG --cflags`" LDFLAGS="$LDFLAGS `$CUPS_CONFIG --ldflags`" - LIBS="$LIBS `$CUPS_CONFIG --libs`" + PRINTLIBS="$PRINTLIBS `$CUPS_CONFIG --libs`" fi fi @@ -3748,12 +3799,12 @@ fi for ac_func in dlopen do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3752: checking for $ac_func" >&5 +echo "configure:3803: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3831: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -3802,7 +3853,7 @@ done if test x"$ac_cv_func_dlopen" = x"no"; then echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 -echo "configure:3806: checking for dlopen in -ldl" >&5 +echo "configure:3857: checking for dlopen in -ldl" >&5 ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -3810,7 +3861,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3876: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -3851,13 +3902,13 @@ fi ############################################ # check if the compiler can do immediate structures echo $ac_n "checking for immediate structures""... $ac_c" 1>&6 -echo "configure:3855: checking for immediate structures" >&5 +echo "configure:3906: checking for immediate structures" >&5 if eval "test \"`echo '$''{'samba_cv_immediate_structures'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -3875,7 +3926,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:3879: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3930: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_immediate_structures=yes else @@ -3898,13 +3949,13 @@ fi ############################################ # check for unix domain sockets echo $ac_n "checking for unix domain sockets""... $ac_c" 1>&6 -echo "configure:3902: checking for unix domain sockets" >&5 +echo "configure:3953: checking for unix domain sockets" >&5 if eval "test \"`echo '$''{'samba_cv_unixsocket'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -3919,7 +3970,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:3923: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3974: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_unixsocket=yes else @@ -3941,13 +3992,13 @@ fi echo $ac_n "checking for socklen_t type""... $ac_c" 1>&6 -echo "configure:3945: checking for socklen_t type" >&5 +echo "configure:3996: checking for socklen_t type" >&5 if eval "test \"`echo '$''{'samba_cv_socklen_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -3960,7 +4011,7 @@ int main() { socklen_t i = 0 ; return 0; } EOF -if { (eval echo configure:3964: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4015: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_socklen_t=yes else @@ -3981,13 +4032,13 @@ EOF fi echo $ac_n "checking for sig_atomic_t type""... $ac_c" 1>&6 -echo "configure:3985: checking for sig_atomic_t type" >&5 +echo "configure:4036: checking for sig_atomic_t type" >&5 if eval "test \"`echo '$''{'samba_cv_sig_atomic_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -4000,7 +4051,7 @@ int main() { sig_atomic_t i = 0 ; return 0; } EOF -if { (eval echo configure:4004: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4055: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_sig_atomic_t=yes else @@ -4023,20 +4074,20 @@ fi # stupid headers have the functions but no declaration. grrrr. echo $ac_n "checking for errno declaration""... $ac_c" 1>&6 -echo "configure:4027: checking for errno declaration" >&5 +echo "configure:4078: checking for errno declaration" >&5 if eval "test \"`echo '$''{'ac_cv_have_errno_decl'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { int i = (int)errno ; return 0; } EOF -if { (eval echo configure:4040: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4091: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_have_errno_decl=yes else @@ -4058,20 +4109,20 @@ EOF echo $ac_n "checking for setresuid declaration""... $ac_c" 1>&6 -echo "configure:4062: checking for setresuid declaration" >&5 +echo "configure:4113: checking for setresuid declaration" >&5 if eval "test \"`echo '$''{'ac_cv_have_setresuid_decl'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { int i = (int)setresuid ; return 0; } EOF -if { (eval echo configure:4075: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4126: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_have_setresuid_decl=yes else @@ -4093,20 +4144,20 @@ EOF echo $ac_n "checking for setresgid declaration""... $ac_c" 1>&6 -echo "configure:4097: checking for setresgid declaration" >&5 +echo "configure:4148: checking for setresgid declaration" >&5 if eval "test \"`echo '$''{'ac_cv_have_setresgid_decl'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { int i = (int)setresgid ; return 0; } EOF -if { (eval echo configure:4110: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4161: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_have_setresgid_decl=yes else @@ -4128,20 +4179,20 @@ EOF echo $ac_n "checking for asprintf declaration""... $ac_c" 1>&6 -echo "configure:4132: checking for asprintf declaration" >&5 +echo "configure:4183: checking for asprintf declaration" >&5 if eval "test \"`echo '$''{'ac_cv_have_asprintf_decl'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { int i = (int)asprintf ; return 0; } EOF -if { (eval echo configure:4145: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4196: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_have_asprintf_decl=yes else @@ -4163,20 +4214,20 @@ EOF echo $ac_n "checking for vasprintf declaration""... $ac_c" 1>&6 -echo "configure:4167: checking for vasprintf declaration" >&5 +echo "configure:4218: checking for vasprintf declaration" >&5 if eval "test \"`echo '$''{'ac_cv_have_vasprintf_decl'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { int i = (int)vasprintf ; return 0; } EOF -if { (eval echo configure:4180: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4231: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_have_vasprintf_decl=yes else @@ -4198,20 +4249,20 @@ EOF echo $ac_n "checking for vsnprintf declaration""... $ac_c" 1>&6 -echo "configure:4202: checking for vsnprintf declaration" >&5 +echo "configure:4253: checking for vsnprintf declaration" >&5 if eval "test \"`echo '$''{'ac_cv_have_vsnprintf_decl'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { int i = (int)vsnprintf ; return 0; } EOF -if { (eval echo configure:4215: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4266: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_have_vsnprintf_decl=yes else @@ -4233,20 +4284,20 @@ EOF echo $ac_n "checking for snprintf declaration""... $ac_c" 1>&6 -echo "configure:4237: checking for snprintf declaration" >&5 +echo "configure:4288: checking for snprintf declaration" >&5 if eval "test \"`echo '$''{'ac_cv_have_snprintf_decl'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { int i = (int)snprintf ; return 0; } EOF -if { (eval echo configure:4250: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4301: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_have_snprintf_decl=yes else @@ -4270,7 +4321,7 @@ EOF # and glibc has setresuid under linux but the function does # nothing until kernel 2.1.44! very dumb. echo $ac_n "checking for real setresuid""... $ac_c" 1>&6 -echo "configure:4274: checking for real setresuid" >&5 +echo "configure:4325: checking for real setresuid" >&5 if eval "test \"`echo '$''{'samba_cv_have_setresuid'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4279,12 +4330,12 @@ else samba_cv_have_setresuid=cross else cat > conftest.$ac_ext < main() { setresuid(1,1,1); setresuid(2,2,2); exit(errno==EPERM?0:1);} EOF -if { (eval echo configure:4288: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:4339: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_have_setresuid=yes else @@ -4309,7 +4360,7 @@ fi # Do the same check for setresguid... # echo $ac_n "checking for real setresgid""... $ac_c" 1>&6 -echo "configure:4313: checking for real setresgid" >&5 +echo "configure:4364: checking for real setresgid" >&5 if eval "test \"`echo '$''{'samba_cv_have_setresgid'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4318,13 +4369,13 @@ else samba_cv_have_setresgid=cross else cat > conftest.$ac_ext < #include main() { errno = 0; setresgid(1,1,1); exit(errno != 0 ? (errno==EPERM ? 0 : 1) : 0);} EOF -if { (eval echo configure:4328: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:4379: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_have_setresgid=yes else @@ -4347,7 +4398,7 @@ EOF fi echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6 -echo "configure:4351: checking for 8-bit clean memcmp" >&5 +echo "configure:4402: checking for 8-bit clean memcmp" >&5 if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4355,7 +4406,7 @@ else ac_cv_func_memcmp_clean=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:4420: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_memcmp_clean=yes else @@ -4388,12 +4439,12 @@ test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.${ac_objext}" for ac_func in crypt do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4392: checking for $ac_func" >&5 +echo "configure:4443: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4471: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -4442,7 +4493,7 @@ done if test x"$ac_cv_func_crypt" = x"no"; then echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6 -echo "configure:4446: checking for crypt in -lcrypt" >&5 +echo "configure:4497: checking for crypt in -lcrypt" >&5 ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4450,7 +4501,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcrypt $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4516: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4494,7 +4545,7 @@ test "${with_readline+set}" != "set" && with_readline=yes # test for where we get readline() from echo $ac_n "checking whether to use readline""... $ac_c" 1>&6 -echo "configure:4498: checking whether to use readline" >&5 +echo "configure:4549: checking whether to use readline" >&5 # Check whether --with-readline or --without-readline was given. if test "${with_readline+set}" = set; then withval="$with_readline" @@ -4506,17 +4557,17 @@ if test "${with_readline+set}" = set; then do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4510: checking for $ac_hdr" >&5 +echo "configure:4561: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4520: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4571: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4546,17 +4597,17 @@ done do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4550: checking for $ac_hdr" >&5 +echo "configure:4601: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4560: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4611: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4587,17 +4638,17 @@ done do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4591: checking for $ac_hdr" >&5 +echo "configure:4642: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4601: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4652: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4620,7 +4671,7 @@ EOF for termlib in ncurses curses termcap terminfo termlib; do echo $ac_n "checking for tgetent in -l${termlib}""... $ac_c" 1>&6 -echo "configure:4624: checking for tgetent in -l${termlib}" >&5 +echo "configure:4675: checking for tgetent in -l${termlib}" >&5 ac_lib_var=`echo ${termlib}'_'tgetent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4628,7 +4679,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l${termlib} $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4694: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4661,7 +4712,7 @@ fi done echo $ac_n "checking for rl_callback_handler_install in -lreadline""... $ac_c" 1>&6 -echo "configure:4665: checking for rl_callback_handler_install in -lreadline" >&5 +echo "configure:4716: checking for rl_callback_handler_install in -lreadline" >&5 ac_lib_var=`echo readline'_'rl_callback_handler_install | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4669,7 +4720,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lreadline $TERMLIBS $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4735: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4731,17 +4782,17 @@ done do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4735: checking for $ac_hdr" >&5 +echo "configure:4786: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4745: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4796: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4771,17 +4822,17 @@ done do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4775: checking for $ac_hdr" >&5 +echo "configure:4826: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4785: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4836: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4812,17 +4863,17 @@ done do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4816: checking for $ac_hdr" >&5 +echo "configure:4867: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4826: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4877: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4845,7 +4896,7 @@ EOF for termlib in ncurses curses termcap terminfo termlib; do echo $ac_n "checking for tgetent in -l${termlib}""... $ac_c" 1>&6 -echo "configure:4849: checking for tgetent in -l${termlib}" >&5 +echo "configure:4900: checking for tgetent in -l${termlib}" >&5 ac_lib_var=`echo ${termlib}'_'tgetent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4853,7 +4904,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l${termlib} $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4919: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4886,7 +4937,7 @@ fi done echo $ac_n "checking for rl_callback_handler_install in -lreadline""... $ac_c" 1>&6 -echo "configure:4890: checking for rl_callback_handler_install in -lreadline" >&5 +echo "configure:4941: checking for rl_callback_handler_install in -lreadline" >&5 ac_lib_var=`echo readline'_'rl_callback_handler_install | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4894,7 +4945,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lreadline $TERMLIBS $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4960: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4955,7 +5006,7 @@ fi # code will generate warnings on one of them unless we have a few # special cases. echo $ac_n "checking for rl_completion_matches in -lreadline""... $ac_c" 1>&6 -echo "configure:4959: checking for rl_completion_matches in -lreadline" >&5 +echo "configure:5010: checking for rl_completion_matches in -lreadline" >&5 ac_lib_var=`echo readline'_'rl_completion_matches | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4963,7 +5014,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lreadline $TERMLIBS $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5029: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5007,12 +5058,12 @@ fi for ac_func in connect do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5011: checking for $ac_func" >&5 +echo "configure:5062: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5090: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5063,7 +5114,7 @@ if test x"$ac_cv_func_connect" = x"no"; then case "$LIBS" in *-lnsl*) ;; *) echo $ac_n "checking for printf in -lnsl_s""... $ac_c" 1>&6 -echo "configure:5067: checking for printf in -lnsl_s" >&5 +echo "configure:5118: checking for printf in -lnsl_s" >&5 ac_lib_var=`echo nsl_s'_'printf | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5071,7 +5122,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lnsl_s $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5137: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5113,7 +5164,7 @@ fi case "$LIBS" in *-lnsl*) ;; *) echo $ac_n "checking for printf in -lnsl""... $ac_c" 1>&6 -echo "configure:5117: checking for printf in -lnsl" >&5 +echo "configure:5168: checking for printf in -lnsl" >&5 ac_lib_var=`echo nsl'_'printf | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5121,7 +5172,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5187: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5163,7 +5214,7 @@ fi case "$LIBS" in *-lsocket*) ;; *) echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6 -echo "configure:5167: checking for connect in -lsocket" >&5 +echo "configure:5218: checking for connect in -lsocket" >&5 ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5171,7 +5222,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5237: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5213,7 +5264,7 @@ fi case "$LIBS" in *-linet*) ;; *) echo $ac_n "checking for connect in -linet""... $ac_c" 1>&6 -echo "configure:5217: checking for connect in -linet" >&5 +echo "configure:5268: checking for connect in -linet" >&5 ac_lib_var=`echo inet'_'connect | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5221,7 +5272,7 @@ else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5287: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5276,12 +5327,12 @@ fi for ac_func in yp_get_default_domain do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5280: checking for $ac_func" >&5 +echo "configure:5331: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5359: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5330,7 +5381,7 @@ done if test x"$ac_cv_func_yp_get_default_domain" = x"no"; then echo $ac_n "checking for yp_get_default_domain in -lnsl""... $ac_c" 1>&6 -echo "configure:5334: checking for yp_get_default_domain in -lnsl" >&5 +echo "configure:5385: checking for yp_get_default_domain in -lnsl" >&5 ac_lib_var=`echo nsl'_'yp_get_default_domain | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5338,7 +5389,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5404: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5379,12 +5430,12 @@ fi for ac_func in execl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5383: checking for $ac_func" >&5 +echo "configure:5434: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5462: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5440,12 +5491,12 @@ fi for ac_func in dlopen dlclose dlsym dlerror waitpid getcwd strdup strndup strnlen strtoul strerror chown fchown chmod fchmod chroot link mknod mknod64 do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5444: checking for $ac_func" >&5 +echo "configure:5495: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5523: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5495,12 +5546,12 @@ done for ac_func in fstat strchr utime utimes getrlimit fsync bzero memset strlcpy strlcat setpgid do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5499: checking for $ac_func" >&5 +echo "configure:5550: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5578: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5550,12 +5601,12 @@ done for ac_func in memmove vsnprintf snprintf asprintf vasprintf setsid glob strpbrk pipe crypt16 getauthuid do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5554: checking for $ac_func" >&5 +echo "configure:5605: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5633: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5605,12 +5656,12 @@ done for ac_func in strftime sigprocmask sigblock sigaction sigset innetgr setnetgrent getnetgrent endnetgrent do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5609: checking for $ac_func" >&5 +echo "configure:5660: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5688: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5660,12 +5711,12 @@ done for ac_func in initgroups select poll rdchk getgrnam getgrent pathconf realpath do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5664: checking for $ac_func" >&5 +echo "configure:5715: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5743: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5715,12 +5766,12 @@ done for ac_func in setpriv setgidx setuidx setgroups sysconf mktime rename ftruncate stat64 fstat64 do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5719: checking for $ac_func" >&5 +echo "configure:5770: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5798: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5770,12 +5821,12 @@ done for ac_func in lstat64 fopen64 atexit grantpt dup2 lseek64 ftruncate64 readdir64 do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5774: checking for $ac_func" >&5 +echo "configure:5825: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5853: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5825,12 +5876,12 @@ done for ac_func in fseek64 fseeko64 ftell64 ftello64 setluid getpwanam setlinebuf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5829: checking for $ac_func" >&5 +echo "configure:5880: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5908: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5880,12 +5931,12 @@ done for ac_func in srandom random srand rand setenv usleep strcasecmp fcvt fcvtl symlink readlink do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5884: checking for $ac_func" >&5 +echo "configure:5935: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5963: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5935,12 +5986,12 @@ done for ac_func in syslog vsyslog getgrouplist do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5939: checking for $ac_func" >&5 +echo "configure:5990: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6018: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5991,12 +6042,12 @@ done for ac_func in setbuffer do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5995: checking for $ac_func" >&5 +echo "configure:6046: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6074: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6048,12 +6099,12 @@ done for ac_func in syscall do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6052: checking for $ac_func" >&5 +echo "configure:6103: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6131: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6104,12 +6155,12 @@ done for ac_func in _dup _dup2 _opendir _readdir _seekdir _telldir _closedir do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6108: checking for $ac_func" >&5 +echo "configure:6159: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6187: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6159,12 +6210,12 @@ done for ac_func in __dup __dup2 __opendir __readdir __seekdir __telldir __closedir do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6163: checking for $ac_func" >&5 +echo "configure:6214: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6242: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6214,12 +6265,12 @@ done for ac_func in __getcwd _getcwd do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6218: checking for $ac_func" >&5 +echo "configure:6269: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6297: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6269,12 +6320,12 @@ done for ac_func in __xstat __fxstat __lxstat do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6273: checking for $ac_func" >&5 +echo "configure:6324: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6352: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6324,12 +6375,12 @@ done for ac_func in _stat _lstat _fstat __stat __lstat __fstat do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6328: checking for $ac_func" >&5 +echo "configure:6379: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6407: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6379,12 +6430,12 @@ done for ac_func in _acl __acl _facl __facl _open __open _chdir __chdir do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6383: checking for $ac_func" >&5 +echo "configure:6434: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6462: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6434,12 +6485,12 @@ done for ac_func in _close __close _fchdir __fchdir _fcntl __fcntl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6438: checking for $ac_func" >&5 +echo "configure:6489: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6517: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6489,12 +6540,12 @@ done for ac_func in getdents _getdents __getdents _lseek __lseek _read __read do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6493: checking for $ac_func" >&5 +echo "configure:6544: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6572: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6544,12 +6595,12 @@ done for ac_func in _write __write _fork __fork do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6548: checking for $ac_func" >&5 +echo "configure:6599: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6627: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6599,12 +6650,12 @@ done for ac_func in _stat64 __stat64 _fstat64 __fstat64 _lstat64 __lstat64 do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6603: checking for $ac_func" >&5 +echo "configure:6654: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6682: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6654,12 +6705,12 @@ done for ac_func in __sys_llseek llseek _llseek __llseek readdir64 _readdir64 __readdir64 do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6658: checking for $ac_func" >&5 +echo "configure:6709: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6737: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6709,12 +6760,12 @@ done for ac_func in pread _pread __pread pread64 _pread64 __pread64 do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6713: checking for $ac_func" >&5 +echo "configure:6764: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6792: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6764,12 +6815,12 @@ done for ac_func in pwrite _pwrite __pwrite pwrite64 _pwrite64 __pwrite64 do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6768: checking for $ac_func" >&5 +echo "configure:6819: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6847: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6819,12 +6870,12 @@ done for ac_func in open64 _open64 __open64 creat64 do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6823: checking for $ac_func" >&5 +echo "configure:6874: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6902: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6878,9 +6929,9 @@ done if test x$ac_cv_func_stat64 = xno ; then echo $ac_n "checking for stat64 in ""... $ac_c" 1>&6 -echo "configure:6882: checking for stat64 in " >&5 +echo "configure:6933: checking for stat64 in " >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6947: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_stat64=yes else @@ -6911,9 +6962,9 @@ fi if test x$ac_cv_func_lstat64 = xno ; then echo $ac_n "checking for lstat64 in ""... $ac_c" 1>&6 -echo "configure:6915: checking for lstat64 in " >&5 +echo "configure:6966: checking for lstat64 in " >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6980: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_lstat64=yes else @@ -6944,9 +6995,9 @@ fi if test x$ac_cv_func_fstat64 = xno ; then echo $ac_n "checking for fstat64 in ""... $ac_c" 1>&6 -echo "configure:6948: checking for fstat64 in " >&5 +echo "configure:6999: checking for fstat64 in " >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7013: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_fstat64=yes else @@ -6978,7 +7029,7 @@ fi ##################################### # we might need the resolv library on some systems echo $ac_n "checking for dn_expand in -lresolv""... $ac_c" 1>&6 -echo "configure:6982: checking for dn_expand in -lresolv" >&5 +echo "configure:7033: checking for dn_expand in -lresolv" >&5 ac_lib_var=`echo resolv'_'dn_expand | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6986,7 +7037,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lresolv $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7052: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7035,12 +7086,12 @@ case "$LIBS" in *-lsecurity*) for ac_func in putprpwnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7039: checking for $ac_func" >&5 +echo "configure:7090: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7118: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7088,7 +7139,7 @@ fi done ;; *) echo $ac_n "checking for putprpwnam in -lsecurity""... $ac_c" 1>&6 -echo "configure:7092: checking for putprpwnam in -lsecurity" >&5 +echo "configure:7143: checking for putprpwnam in -lsecurity" >&5 ac_lib_var=`echo security'_'putprpwnam | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7096,7 +7147,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsecurity $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7162: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7137,12 +7188,12 @@ fi for ac_func in putprpwnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7141: checking for $ac_func" >&5 +echo "configure:7192: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7220: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7196,12 +7247,12 @@ case "$LIBS" in *-lsec*) for ac_func in putprpwnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7200: checking for $ac_func" >&5 +echo "configure:7251: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7279: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7249,7 +7300,7 @@ fi done ;; *) echo $ac_n "checking for putprpwnam in -lsec""... $ac_c" 1>&6 -echo "configure:7253: checking for putprpwnam in -lsec" >&5 +echo "configure:7304: checking for putprpwnam in -lsec" >&5 ac_lib_var=`echo sec'_'putprpwnam | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7257,7 +7308,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsec $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7323: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7298,12 +7349,12 @@ fi for ac_func in putprpwnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7302: checking for $ac_func" >&5 +echo "configure:7353: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7381: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7358,12 +7409,12 @@ case "$LIBS" in *-lsecurity*) for ac_func in set_auth_parameters do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7362: checking for $ac_func" >&5 +echo "configure:7413: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7441: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7411,7 +7462,7 @@ fi done ;; *) echo $ac_n "checking for set_auth_parameters in -lsecurity""... $ac_c" 1>&6 -echo "configure:7415: checking for set_auth_parameters in -lsecurity" >&5 +echo "configure:7466: checking for set_auth_parameters in -lsecurity" >&5 ac_lib_var=`echo security'_'set_auth_parameters | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7419,7 +7470,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsecurity $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7485: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7460,12 +7511,12 @@ fi for ac_func in set_auth_parameters do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7464: checking for $ac_func" >&5 +echo "configure:7515: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7543: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7519,12 +7570,12 @@ case "$LIBS" in *-lsec*) for ac_func in set_auth_parameters do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7523: checking for $ac_func" >&5 +echo "configure:7574: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7602: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7572,7 +7623,7 @@ fi done ;; *) echo $ac_n "checking for set_auth_parameters in -lsec""... $ac_c" 1>&6 -echo "configure:7576: checking for set_auth_parameters in -lsec" >&5 +echo "configure:7627: checking for set_auth_parameters in -lsec" >&5 ac_lib_var=`echo sec'_'set_auth_parameters | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7580,7 +7631,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsec $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7646: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7621,12 +7672,12 @@ fi for ac_func in set_auth_parameters do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7625: checking for $ac_func" >&5 +echo "configure:7676: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7704: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7682,12 +7733,12 @@ case "$LIBS" in *-lgen*) for ac_func in getspnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7686: checking for $ac_func" >&5 +echo "configure:7737: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7765: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7735,7 +7786,7 @@ fi done ;; *) echo $ac_n "checking for getspnam in -lgen""... $ac_c" 1>&6 -echo "configure:7739: checking for getspnam in -lgen" >&5 +echo "configure:7790: checking for getspnam in -lgen" >&5 ac_lib_var=`echo gen'_'getspnam | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7743,7 +7794,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgen $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7809: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7784,12 +7835,12 @@ fi for ac_func in getspnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7788: checking for $ac_func" >&5 +echo "configure:7839: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7867: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7844,12 +7895,12 @@ case "$LIBS" in *-lsecurity*) for ac_func in getspnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7848: checking for $ac_func" >&5 +echo "configure:7899: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7927: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7897,7 +7948,7 @@ fi done ;; *) echo $ac_n "checking for getspnam in -lsecurity""... $ac_c" 1>&6 -echo "configure:7901: checking for getspnam in -lsecurity" >&5 +echo "configure:7952: checking for getspnam in -lsecurity" >&5 ac_lib_var=`echo security'_'getspnam | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7905,7 +7956,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsecurity $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7971: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7946,12 +7997,12 @@ fi for ac_func in getspnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7950: checking for $ac_func" >&5 +echo "configure:8001: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8029: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8005,12 +8056,12 @@ case "$LIBS" in *-lsec*) for ac_func in getspnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8009: checking for $ac_func" >&5 +echo "configure:8060: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8088: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8058,7 +8109,7 @@ fi done ;; *) echo $ac_n "checking for getspnam in -lsec""... $ac_c" 1>&6 -echo "configure:8062: checking for getspnam in -lsec" >&5 +echo "configure:8113: checking for getspnam in -lsec" >&5 ac_lib_var=`echo sec'_'getspnam | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8066,7 +8117,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsec $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8132: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8107,12 +8158,12 @@ fi for ac_func in getspnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8111: checking for $ac_func" >&5 +echo "configure:8162: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8190: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8167,12 +8218,12 @@ case "$LIBS" in *-lsecurity*) for ac_func in bigcrypt do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8171: checking for $ac_func" >&5 +echo "configure:8222: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8250: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8220,7 +8271,7 @@ fi done ;; *) echo $ac_n "checking for bigcrypt in -lsecurity""... $ac_c" 1>&6 -echo "configure:8224: checking for bigcrypt in -lsecurity" >&5 +echo "configure:8275: checking for bigcrypt in -lsecurity" >&5 ac_lib_var=`echo security'_'bigcrypt | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8228,7 +8279,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsecurity $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8294: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8269,12 +8320,12 @@ fi for ac_func in bigcrypt do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8273: checking for $ac_func" >&5 +echo "configure:8324: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8352: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8328,12 +8379,12 @@ case "$LIBS" in *-lsec*) for ac_func in bigcrypt do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8332: checking for $ac_func" >&5 +echo "configure:8383: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8411: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8381,7 +8432,7 @@ fi done ;; *) echo $ac_n "checking for bigcrypt in -lsec""... $ac_c" 1>&6 -echo "configure:8385: checking for bigcrypt in -lsec" >&5 +echo "configure:8436: checking for bigcrypt in -lsec" >&5 ac_lib_var=`echo sec'_'bigcrypt | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8389,7 +8440,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsec $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8455: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8430,12 +8481,12 @@ fi for ac_func in bigcrypt do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8434: checking for $ac_func" >&5 +echo "configure:8485: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8513: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8490,12 +8541,12 @@ case "$LIBS" in *-lsecurity*) for ac_func in getprpwnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8494: checking for $ac_func" >&5 +echo "configure:8545: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8573: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8543,7 +8594,7 @@ fi done ;; *) echo $ac_n "checking for getprpwnam in -lsecurity""... $ac_c" 1>&6 -echo "configure:8547: checking for getprpwnam in -lsecurity" >&5 +echo "configure:8598: checking for getprpwnam in -lsecurity" >&5 ac_lib_var=`echo security'_'getprpwnam | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8551,7 +8602,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsecurity $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8617: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8592,12 +8643,12 @@ fi for ac_func in getprpwnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8596: checking for $ac_func" >&5 +echo "configure:8647: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8675: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8651,12 +8702,12 @@ case "$LIBS" in *-lsec*) for ac_func in getprpwnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8655: checking for $ac_func" >&5 +echo "configure:8706: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8734: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8704,7 +8755,7 @@ fi done ;; *) echo $ac_n "checking for getprpwnam in -lsec""... $ac_c" 1>&6 -echo "configure:8708: checking for getprpwnam in -lsec" >&5 +echo "configure:8759: checking for getprpwnam in -lsec" >&5 ac_lib_var=`echo sec'_'getprpwnam | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8712,7 +8763,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsec $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8778: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8753,12 +8804,12 @@ fi for ac_func in getprpwnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8757: checking for $ac_func" >&5 +echo "configure:8808: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8836: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8825,7 +8876,7 @@ SHLIBEXT="so" # Assume non-shared by default and override below BLDSHARED="false" echo $ac_n "checking ability to build shared libraries""... $ac_c" 1>&6 -echo "configure:8829: checking ability to build shared libraries" >&5 +echo "configure:8880: checking ability to build shared libraries" >&5 # and these are for particular systems case "$host_os" in @@ -8877,7 +8928,17 @@ EOF SONAMEFLAG="-Wl,-h," PICFLAG="-KPIC" # Is this correct for SunOS ;; - *bsd*) BLDSHARED="true" + *freebsd*) BLDSHARED="true" + LDSHFLAGS="-shared" + DYNEXP="-Wl,--export-dynamic" + SONAMEFLAG="-Wl,-soname," + PICFLAG="-fPIC -DPIC" + cat >> confdefs.h <<\EOF +#define STAT_ST_BLOCKSIZE 512 +EOF + + ;; + *openbsd*) BLDSHARED="true" LDSHFLAGS="-shared" DYNEXP="-Wl,-Bdynamic" SONAMEFLAG="-Wl,-soname," @@ -8920,12 +8981,10 @@ EOF BLDSHARED="true" LDSHFLAGS="-Wl,-bexpall,-bM:SRE,-bnoentry" DYNEXP="-Wl,-brtl,-bexpall" - if test "${GCC}" = "yes"; then - PICFLAG="-O2" - else - PICFLAG="-O2 -qmaxmem=6000" + PICFLAG="-O2" + if test "${GCC}" != "yes"; then ## for funky AIX compiler using strncpy() - CFLAGS="$CFLAGS -D_LINUX_SOURCE_COMPAT" + CFLAGS="$CFLAGS -D_LINUX_SOURCE_COMPAT -qmaxmem=32000" fi cat >> confdefs.h <<\EOF @@ -8985,7 +9044,7 @@ EOF *dgux*) # Extract the first word of "groff", so it can be a program name with args. set dummy groff; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:8989: checking for $ac_word" >&5 +echo "configure:9048: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_ROFF'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9042,17 +9101,17 @@ esac echo "$ac_t""$BLDSHARED" 1>&6 echo $ac_n "checking linker flags for shared libraries""... $ac_c" 1>&6 -echo "configure:9046: checking linker flags for shared libraries" >&5 +echo "configure:9105: checking linker flags for shared libraries" >&5 echo "$ac_t""$LDSHFLAGS" 1>&6 echo $ac_n "checking compiler flags for position-independent code""... $ac_c" 1>&6 -echo "configure:9049: checking compiler flags for position-independent code" >&5 +echo "configure:9108: checking compiler flags for position-independent code" >&5 echo "$ac_t""$PICFLAGS" 1>&6 ####################################################### # test whether building a shared library actually works if test $BLDSHARED = true; then echo $ac_n "checking whether building shared libraries actually works""... $ac_c" 1>&6 -echo "configure:9056: checking whether building shared libraries actually works" >&5 +echo "configure:9115: checking whether building shared libraries actually works" >&5 if eval "test \"`echo '$''{'ac_cv_shlib_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9083,7 +9142,7 @@ fi ################ echo $ac_n "checking for long long""... $ac_c" 1>&6 -echo "configure:9087: checking for long long" >&5 +echo "configure:9146: checking for long long" >&5 if eval "test \"`echo '$''{'samba_cv_have_longlong'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9092,12 +9151,12 @@ if test "$cross_compiling" = yes; then samba_cv_have_longlong=cross else cat > conftest.$ac_ext < main() { long long x = 1000000; x *= x; exit(((x/1000000) == 1000000)? 0: 1); } EOF -if { (eval echo configure:9101: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9160: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_have_longlong=yes else @@ -9124,20 +9183,20 @@ fi # AIX needs this. echo $ac_n "checking for LL suffix on long long integers""... $ac_c" 1>&6 -echo "configure:9128: checking for LL suffix on long long integers" >&5 +echo "configure:9187: checking for LL suffix on long long integers" >&5 if eval "test \"`echo '$''{'samba_cv_compiler_supports_ll'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { long long i = 0x8000000000LL ; return 0; } EOF -if { (eval echo configure:9141: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9200: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_compiler_supports_ll=yes else @@ -9159,7 +9218,7 @@ fi echo $ac_n "checking for 64 bit off_t""... $ac_c" 1>&6 -echo "configure:9163: checking for 64 bit off_t" >&5 +echo "configure:9222: checking for 64 bit off_t" >&5 if eval "test \"`echo '$''{'samba_cv_SIZEOF_OFF_T'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9168,13 +9227,13 @@ if test "$cross_compiling" = yes; then samba_cv_SIZEOF_OFF_T=cross else cat > conftest.$ac_ext < #include main() { exit((sizeof(off_t) == 8) ? 0 : 1); } EOF -if { (eval echo configure:9178: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9237: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_SIZEOF_OFF_T=yes else @@ -9197,7 +9256,7 @@ EOF fi echo $ac_n "checking for off64_t""... $ac_c" 1>&6 -echo "configure:9201: checking for off64_t" >&5 +echo "configure:9260: checking for off64_t" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_OFF64_T'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9206,7 +9265,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_OFF64_T=cross else cat > conftest.$ac_ext < main() { struct stat64 st; off64_t s; if (sizeof(off_t) == sizeof(off64_t)) exit(1); exit((lstat64("/dev/null", &st)==0)?0:1); } EOF -if { (eval echo configure:9220: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9279: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_OFF64_T=yes else @@ -9239,7 +9298,7 @@ EOF fi echo $ac_n "checking for 64 bit ino_t""... $ac_c" 1>&6 -echo "configure:9243: checking for 64 bit ino_t" >&5 +echo "configure:9302: checking for 64 bit ino_t" >&5 if eval "test \"`echo '$''{'samba_cv_SIZEOF_INO_T'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9248,13 +9307,13 @@ if test "$cross_compiling" = yes; then samba_cv_SIZEOF_INO_T=cross else cat > conftest.$ac_ext < #include main() { exit((sizeof(ino_t) == 8) ? 0 : 1); } EOF -if { (eval echo configure:9258: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9317: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_SIZEOF_INO_T=yes else @@ -9277,7 +9336,7 @@ EOF fi echo $ac_n "checking for ino64_t""... $ac_c" 1>&6 -echo "configure:9281: checking for ino64_t" >&5 +echo "configure:9340: checking for ino64_t" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_INO64_T'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9286,7 +9345,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_INO64_T=cross else cat > conftest.$ac_ext < main() { struct stat64 st; ino64_t s; if (sizeof(ino_t) == sizeof(ino64_t)) exit(1); exit((lstat64("/dev/null", &st)==0)?0:1); } EOF -if { (eval echo configure:9300: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9359: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_INO64_T=yes else @@ -9319,7 +9378,7 @@ EOF fi echo $ac_n "checking for dev64_t""... $ac_c" 1>&6 -echo "configure:9323: checking for dev64_t" >&5 +echo "configure:9382: checking for dev64_t" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_DEV64_T'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9328,7 +9387,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_DEV64_T=cross else cat > conftest.$ac_ext < main() { struct stat64 st; dev64_t s; if (sizeof(dev_t) == sizeof(dev64_t)) exit(1); exit((lstat64("/dev/null", &st)==0)?0:1); } EOF -if { (eval echo configure:9342: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9401: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_DEV64_T=yes else @@ -9361,13 +9420,13 @@ EOF fi echo $ac_n "checking for struct dirent64""... $ac_c" 1>&6 -echo "configure:9365: checking for struct dirent64" >&5 +echo "configure:9424: checking for struct dirent64" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_STRUCT_DIRENT64'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9442: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_STRUCT_DIRENT64=yes else @@ -9400,7 +9459,7 @@ EOF fi echo $ac_n "checking for major macro""... $ac_c" 1>&6 -echo "configure:9404: checking for major macro" >&5 +echo "configure:9463: checking for major macro" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_DEVICE_MAJOR_FN'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9409,7 +9468,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_DEVICE_MAJOR_FN=cross else cat > conftest.$ac_ext < main() { dev_t dev; int i = major(dev); return 0; } EOF -if { (eval echo configure:9422: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9481: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_DEVICE_MAJOR_FN=yes else @@ -9441,7 +9500,7 @@ EOF fi echo $ac_n "checking for minor macro""... $ac_c" 1>&6 -echo "configure:9445: checking for minor macro" >&5 +echo "configure:9504: checking for minor macro" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_DEVICE_MINOR_FN'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9450,7 +9509,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_DEVICE_MINOR_FN=cross else cat > conftest.$ac_ext < main() { dev_t dev; int i = minor(dev); return 0; } EOF -if { (eval echo configure:9463: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9522: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_DEVICE_MINOR_FN=yes else @@ -9482,7 +9541,7 @@ EOF fi echo $ac_n "checking for unsigned char""... $ac_c" 1>&6 -echo "configure:9486: checking for unsigned char" >&5 +echo "configure:9545: checking for unsigned char" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UNSIGNED_CHAR'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9491,12 +9550,12 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_UNSIGNED_CHAR=cross else cat > conftest.$ac_ext < main() { char c; c=250; exit((c > 0)?0:1); } EOF -if { (eval echo configure:9500: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9559: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_UNSIGNED_CHAR=yes else @@ -9519,13 +9578,13 @@ EOF fi echo $ac_n "checking for sin_len in sock""... $ac_c" 1>&6 -echo "configure:9523: checking for sin_len in sock" >&5 +echo "configure:9582: checking for sin_len in sock" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_SOCK_SIN_LEN'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -9534,7 +9593,7 @@ int main() { struct sockaddr_in sock; sock.sin_len = sizeof(sock); ; return 0; } EOF -if { (eval echo configure:9538: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9597: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_SOCK_SIN_LEN=yes else @@ -9555,13 +9614,13 @@ EOF fi echo $ac_n "checking whether seekdir returns void""... $ac_c" 1>&6 -echo "configure:9559: checking whether seekdir returns void" >&5 +echo "configure:9618: checking whether seekdir returns void" >&5 if eval "test \"`echo '$''{'samba_cv_SEEKDIR_RETURNS_VOID'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -9570,7 +9629,7 @@ int main() { return 0; ; return 0; } EOF -if { (eval echo configure:9574: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9633: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_SEEKDIR_RETURNS_VOID=yes else @@ -9591,20 +9650,20 @@ EOF fi echo $ac_n "checking for __FILE__ macro""... $ac_c" 1>&6 -echo "configure:9595: checking for __FILE__ macro" >&5 +echo "configure:9654: checking for __FILE__ macro" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_FILE_MACRO'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { printf("%s\n", __FILE__); ; return 0; } EOF -if { (eval echo configure:9608: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9667: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_FILE_MACRO=yes else @@ -9625,20 +9684,20 @@ EOF fi echo $ac_n "checking for __FUNCTION__ macro""... $ac_c" 1>&6 -echo "configure:9629: checking for __FUNCTION__ macro" >&5 +echo "configure:9688: checking for __FUNCTION__ macro" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_FUNCTION_MACRO'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { printf("%s\n", __FUNCTION__); ; return 0; } EOF -if { (eval echo configure:9642: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9701: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_FUNCTION_MACRO=yes else @@ -9659,7 +9718,7 @@ EOF fi echo $ac_n "checking if gettimeofday takes tz argument""... $ac_c" 1>&6 -echo "configure:9663: checking if gettimeofday takes tz argument" >&5 +echo "configure:9722: checking if gettimeofday takes tz argument" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_GETTIMEOFDAY_TZ'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9668,14 +9727,14 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_GETTIMEOFDAY_TZ=cross else cat > conftest.$ac_ext < #include main() { struct timeval tv; exit(gettimeofday(&tv, NULL));} EOF -if { (eval echo configure:9679: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9738: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_GETTIMEOFDAY_TZ=yes else @@ -9698,13 +9757,13 @@ EOF fi echo $ac_n "checking for __va_copy""... $ac_c" 1>&6 -echo "configure:9702: checking for __va_copy" >&5 +echo "configure:9761: checking for __va_copy" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_VA_COPY'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < va_list ap1,ap2; @@ -9712,7 +9771,7 @@ int main() { __va_copy(ap1,ap2); ; return 0; } EOF -if { (eval echo configure:9716: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:9775: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* samba_cv_HAVE_VA_COPY=yes else @@ -9733,7 +9792,7 @@ EOF fi echo $ac_n "checking for C99 vsnprintf""... $ac_c" 1>&6 -echo "configure:9737: checking for C99 vsnprintf" >&5 +echo "configure:9796: checking for C99 vsnprintf" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_C99_VSNPRINTF'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9742,7 +9801,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_C99_VSNPRINTF=cross else cat > conftest.$ac_ext < @@ -9769,7 +9828,7 @@ void foo(const char *format, ...) { main() { foo("hello"); } EOF -if { (eval echo configure:9773: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9832: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_C99_VSNPRINTF=yes else @@ -9792,7 +9851,7 @@ EOF fi echo $ac_n "checking for broken readdir""... $ac_c" 1>&6 -echo "configure:9796: checking for broken readdir" >&5 +echo "configure:9855: checking for broken readdir" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_BROKEN_READDIR'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9801,7 +9860,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_BROKEN_READDIR=cross else cat > conftest.$ac_ext < #include @@ -9809,7 +9868,7 @@ main() { struct dirent *di; DIR *d = opendir("."); di = readdir(d); if (di && di->d_name[-2] == '.' && di->d_name[-1] == 0 && di->d_name[0] == 0) exit(0); exit(1);} EOF -if { (eval echo configure:9813: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9872: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_BROKEN_READDIR=yes else @@ -9832,13 +9891,13 @@ EOF fi echo $ac_n "checking for utimbuf""... $ac_c" 1>&6 -echo "configure:9836: checking for utimbuf" >&5 +echo "configure:9895: checking for utimbuf" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UTIMBUF'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -9846,7 +9905,7 @@ int main() { struct utimbuf tbuf; tbuf.actime = 0; tbuf.modtime = 1; exit(utime("foo.c",&tbuf)); ; return 0; } EOF -if { (eval echo configure:9850: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9909: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UTIMBUF=yes else @@ -9870,12 +9929,12 @@ fi for ac_func in pututline pututxline updwtmp updwtmpx getutmpx do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:9874: checking for $ac_func" >&5 +echo "configure:9933: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:9961: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -9924,13 +9983,13 @@ done echo $ac_n "checking for ut_name in utmp""... $ac_c" 1>&6 -echo "configure:9928: checking for ut_name in utmp" >&5 +echo "configure:9987: checking for ut_name in utmp" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UT_UT_NAME'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -9938,7 +9997,7 @@ int main() { struct utmp ut; ut.ut_name[0] = 'a'; ; return 0; } EOF -if { (eval echo configure:9942: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10001: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UT_UT_NAME=yes else @@ -9959,13 +10018,13 @@ EOF fi echo $ac_n "checking for ut_user in utmp""... $ac_c" 1>&6 -echo "configure:9963: checking for ut_user in utmp" >&5 +echo "configure:10022: checking for ut_user in utmp" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UT_UT_USER'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -9973,7 +10032,7 @@ int main() { struct utmp ut; ut.ut_user[0] = 'a'; ; return 0; } EOF -if { (eval echo configure:9977: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10036: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UT_UT_USER=yes else @@ -9994,13 +10053,13 @@ EOF fi echo $ac_n "checking for ut_id in utmp""... $ac_c" 1>&6 -echo "configure:9998: checking for ut_id in utmp" >&5 +echo "configure:10057: checking for ut_id in utmp" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UT_UT_ID'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -10008,7 +10067,7 @@ int main() { struct utmp ut; ut.ut_id[0] = 'a'; ; return 0; } EOF -if { (eval echo configure:10012: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10071: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UT_UT_ID=yes else @@ -10029,13 +10088,13 @@ EOF fi echo $ac_n "checking for ut_host in utmp""... $ac_c" 1>&6 -echo "configure:10033: checking for ut_host in utmp" >&5 +echo "configure:10092: checking for ut_host in utmp" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UT_UT_HOST'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -10043,7 +10102,7 @@ int main() { struct utmp ut; ut.ut_host[0] = 'a'; ; return 0; } EOF -if { (eval echo configure:10047: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10106: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UT_UT_HOST=yes else @@ -10064,13 +10123,13 @@ EOF fi echo $ac_n "checking for ut_time in utmp""... $ac_c" 1>&6 -echo "configure:10068: checking for ut_time in utmp" >&5 +echo "configure:10127: checking for ut_time in utmp" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UT_UT_TIME'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -10078,7 +10137,7 @@ int main() { struct utmp ut; time_t t; ut.ut_time = t; ; return 0; } EOF -if { (eval echo configure:10082: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10141: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UT_UT_TIME=yes else @@ -10099,13 +10158,13 @@ EOF fi echo $ac_n "checking for ut_tv in utmp""... $ac_c" 1>&6 -echo "configure:10103: checking for ut_tv in utmp" >&5 +echo "configure:10162: checking for ut_tv in utmp" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UT_UT_TV'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -10113,7 +10172,7 @@ int main() { struct utmp ut; struct timeval tv; ut.ut_tv = tv; ; return 0; } EOF -if { (eval echo configure:10117: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10176: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UT_UT_TV=yes else @@ -10134,13 +10193,13 @@ EOF fi echo $ac_n "checking for ut_type in utmp""... $ac_c" 1>&6 -echo "configure:10138: checking for ut_type in utmp" >&5 +echo "configure:10197: checking for ut_type in utmp" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UT_UT_TYPE'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -10148,7 +10207,7 @@ int main() { struct utmp ut; ut.ut_type = 0; ; return 0; } EOF -if { (eval echo configure:10152: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10211: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UT_UT_TYPE=yes else @@ -10169,13 +10228,13 @@ EOF fi echo $ac_n "checking for ut_pid in utmp""... $ac_c" 1>&6 -echo "configure:10173: checking for ut_pid in utmp" >&5 +echo "configure:10232: checking for ut_pid in utmp" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UT_UT_PID'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -10183,7 +10242,7 @@ int main() { struct utmp ut; ut.ut_pid = 0; ; return 0; } EOF -if { (eval echo configure:10187: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10246: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UT_UT_PID=yes else @@ -10204,13 +10263,13 @@ EOF fi echo $ac_n "checking for ut_exit in utmp""... $ac_c" 1>&6 -echo "configure:10208: checking for ut_exit in utmp" >&5 +echo "configure:10267: checking for ut_exit in utmp" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UT_UT_EXIT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -10218,7 +10277,7 @@ int main() { struct utmp ut; ut.ut_exit.e_exit = 0; ; return 0; } EOF -if { (eval echo configure:10222: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10281: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UT_UT_EXIT=yes else @@ -10239,13 +10298,13 @@ EOF fi echo $ac_n "checking for ut_addr in utmp""... $ac_c" 1>&6 -echo "configure:10243: checking for ut_addr in utmp" >&5 +echo "configure:10302: checking for ut_addr in utmp" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UT_UT_ADDR'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -10253,7 +10312,7 @@ int main() { struct utmp ut; ut.ut_addr = 0; ; return 0; } EOF -if { (eval echo configure:10257: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10316: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UT_UT_ADDR=yes else @@ -10275,13 +10334,13 @@ fi if test x$ac_cv_func_pututline = xyes ; then echo $ac_n "checking whether pututline returns pointer""... $ac_c" 1>&6 -echo "configure:10279: checking whether pututline returns pointer" >&5 +echo "configure:10338: checking whether pututline returns pointer" >&5 if eval "test \"`echo '$''{'samba_cv_PUTUTLINE_RETURNS_UTMP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -10289,7 +10348,7 @@ int main() { struct utmp utarg; struct utmp *utreturn; utreturn = pututline(&utarg); ; return 0; } EOF -if { (eval echo configure:10293: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10352: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_PUTUTLINE_RETURNS_UTMP=yes else @@ -10311,13 +10370,13 @@ EOF fi echo $ac_n "checking for ut_syslen in utmpx""... $ac_c" 1>&6 -echo "configure:10315: checking for ut_syslen in utmpx" >&5 +echo "configure:10374: checking for ut_syslen in utmpx" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UX_UT_SYSLEN'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -10325,7 +10384,7 @@ int main() { struct utmpx ux; ux.ut_syslen = 0; ; return 0; } EOF -if { (eval echo configure:10329: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10388: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UX_UT_SYSLEN=yes else @@ -10349,7 +10408,7 @@ fi ################################################# # check for libiconv support echo $ac_n "checking whether to use libiconv""... $ac_c" 1>&6 -echo "configure:10353: checking whether to use libiconv" >&5 +echo "configure:10412: checking whether to use libiconv" >&5 # Check whether --with-libiconv or --without-libiconv was given. if test "${with_libiconv+set}" = set; then withval="$with_libiconv" @@ -10362,7 +10421,7 @@ if test "${with_libiconv+set}" = set; then CFLAGS="$CFLAGS -I$withval/include" LDFLAGS="$LDFLAGS -L$withval/lib" echo $ac_n "checking for iconv_open in -liconv""... $ac_c" 1>&6 -echo "configure:10366: checking for iconv_open in -liconv" >&5 +echo "configure:10425: checking for iconv_open in -liconv" >&5 ac_lib_var=`echo iconv'_'iconv_open | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -10370,7 +10429,7 @@ else ac_save_LIBS="$LIBS" LIBS="-liconv $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:10444: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -10424,7 +10483,7 @@ fi ############ # check for iconv in libc echo $ac_n "checking for working iconv""... $ac_c" 1>&6 -echo "configure:10428: checking for working iconv" >&5 +echo "configure:10487: checking for working iconv" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_NATIVE_ICONV'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10433,7 +10492,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_NATIVE_ICONV=cross else cat > conftest.$ac_ext < @@ -10444,7 +10503,7 @@ main() { } EOF -if { (eval echo configure:10448: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10507: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_NATIVE_ICONV=yes else @@ -10468,7 +10527,7 @@ fi echo $ac_n "checking for Linux kernel oplocks""... $ac_c" 1>&6 -echo "configure:10472: checking for Linux kernel oplocks" >&5 +echo "configure:10531: checking for Linux kernel oplocks" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_KERNEL_OPLOCKS_LINUX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10477,7 +10536,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_KERNEL_OPLOCKS_LINUX=cross else cat > conftest.$ac_ext < @@ -10491,7 +10550,7 @@ main() { } EOF -if { (eval echo configure:10495: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10554: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_KERNEL_OPLOCKS_LINUX=yes else @@ -10514,7 +10573,7 @@ EOF fi echo $ac_n "checking for kernel change notify support""... $ac_c" 1>&6 -echo "configure:10518: checking for kernel change notify support" >&5 +echo "configure:10577: checking for kernel change notify support" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_KERNEL_CHANGE_NOTIFY'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10523,7 +10582,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_KERNEL_CHANGE_NOTIFY=cross else cat > conftest.$ac_ext < @@ -10537,7 +10596,7 @@ main() { } EOF -if { (eval echo configure:10541: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10600: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_KERNEL_CHANGE_NOTIFY=yes else @@ -10560,7 +10619,7 @@ EOF fi echo $ac_n "checking for kernel share modes""... $ac_c" 1>&6 -echo "configure:10564: checking for kernel share modes" >&5 +echo "configure:10623: checking for kernel share modes" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_KERNEL_SHARE_MODES'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10569,7 +10628,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_KERNEL_SHARE_MODES=cross else cat > conftest.$ac_ext < @@ -10585,7 +10644,7 @@ main() { } EOF -if { (eval echo configure:10589: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10648: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_KERNEL_SHARE_MODES=yes else @@ -10611,13 +10670,13 @@ fi echo $ac_n "checking for IRIX kernel oplock type definitions""... $ac_c" 1>&6 -echo "configure:10615: checking for IRIX kernel oplock type definitions" >&5 +echo "configure:10674: checking for IRIX kernel oplock type definitions" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_KERNEL_OPLOCKS_IRIX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -10625,7 +10684,7 @@ int main() { oplock_stat_t t; t.os_state = OP_REVOKE; t.os_dev = 1; t.os_ino = 1; ; return 0; } EOF -if { (eval echo configure:10629: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10688: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_KERNEL_OPLOCKS_IRIX=yes else @@ -10646,7 +10705,7 @@ EOF fi echo $ac_n "checking for irix specific capabilities""... $ac_c" 1>&6 -echo "configure:10650: checking for irix specific capabilities" >&5 +echo "configure:10709: checking for irix specific capabilities" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_IRIX_SPECIFIC_CAPABILITIES'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10655,7 +10714,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_IRIX_SPECIFIC_CAPABILITIES=cross else cat > conftest.$ac_ext < #include @@ -10670,7 +10729,7 @@ main() { } EOF -if { (eval echo configure:10674: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10733: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_IRIX_SPECIFIC_CAPABILITIES=yes else @@ -10698,13 +10757,13 @@ fi # echo $ac_n "checking for int16 typedef included by rpc/rpc.h""... $ac_c" 1>&6 -echo "configure:10702: checking for int16 typedef included by rpc/rpc.h" >&5 +echo "configure:10761: checking for int16 typedef included by rpc/rpc.h" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_INT16_FROM_RPC_RPC_H'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if defined(HAVE_RPC_RPC_H) @@ -10714,7 +10773,7 @@ int main() { int16 testvar; ; return 0; } EOF -if { (eval echo configure:10718: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10777: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_INT16_FROM_RPC_RPC_H=yes else @@ -10735,13 +10794,13 @@ EOF fi echo $ac_n "checking for uint16 typedef included by rpc/rpc.h""... $ac_c" 1>&6 -echo "configure:10739: checking for uint16 typedef included by rpc/rpc.h" >&5 +echo "configure:10798: checking for uint16 typedef included by rpc/rpc.h" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UINT16_FROM_RPC_RPC_H'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if defined(HAVE_RPC_RPC_H) @@ -10751,7 +10810,7 @@ int main() { uint16 testvar; ; return 0; } EOF -if { (eval echo configure:10755: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10814: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UINT16_FROM_RPC_RPC_H=yes else @@ -10772,13 +10831,13 @@ EOF fi echo $ac_n "checking for int32 typedef included by rpc/rpc.h""... $ac_c" 1>&6 -echo "configure:10776: checking for int32 typedef included by rpc/rpc.h" >&5 +echo "configure:10835: checking for int32 typedef included by rpc/rpc.h" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_INT32_FROM_RPC_RPC_H'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if defined(HAVE_RPC_RPC_H) @@ -10788,7 +10847,7 @@ int main() { int32 testvar; ; return 0; } EOF -if { (eval echo configure:10792: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10851: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_INT32_FROM_RPC_RPC_H=yes else @@ -10809,13 +10868,13 @@ EOF fi echo $ac_n "checking for uint32 typedef included by rpc/rpc.h""... $ac_c" 1>&6 -echo "configure:10813: checking for uint32 typedef included by rpc/rpc.h" >&5 +echo "configure:10872: checking for uint32 typedef included by rpc/rpc.h" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UINT32_FROM_RPC_RPC_H'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if defined(HAVE_RPC_RPC_H) @@ -10825,7 +10884,7 @@ int main() { uint32 testvar; ; return 0; } EOF -if { (eval echo configure:10829: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10888: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UINT32_FROM_RPC_RPC_H=yes else @@ -10847,13 +10906,13 @@ fi echo $ac_n "checking for conflicting AUTH_ERROR define in rpc/rpc.h""... $ac_c" 1>&6 -echo "configure:10851: checking for conflicting AUTH_ERROR define in rpc/rpc.h" >&5 +echo "configure:10910: checking for conflicting AUTH_ERROR define in rpc/rpc.h" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #ifdef HAVE_SYS_SECURITY_H @@ -10867,7 +10926,7 @@ int main() { int testvar; ; return 0; } EOF -if { (eval echo configure:10871: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10930: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT=no else @@ -10888,16 +10947,16 @@ EOF fi echo $ac_n "checking for test routines""... $ac_c" 1>&6 -echo "configure:10892: checking for test routines" >&5 +echo "configure:10951: checking for test routines" >&5 if test "$cross_compiling" = yes; then echo "configure: warning: cannot run when cross-compiling" 1>&2 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10960: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then echo "$ac_t""yes" 1>&6 else @@ -10911,7 +10970,7 @@ fi echo $ac_n "checking for ftruncate extend""... $ac_c" 1>&6 -echo "configure:10915: checking for ftruncate extend" >&5 +echo "configure:10974: checking for ftruncate extend" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_FTRUNCATE_EXTEND'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10920,11 +10979,11 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_FTRUNCATE_EXTEND=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10987: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_FTRUNCATE_EXTEND=yes else @@ -10947,7 +11006,7 @@ EOF fi echo $ac_n "checking for AF_LOCAL socket support""... $ac_c" 1>&6 -echo "configure:10951: checking for AF_LOCAL socket support" >&5 +echo "configure:11010: checking for AF_LOCAL socket support" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_WORKING_AF_LOCAL'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10956,11 +11015,11 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_WORKING_AF_LOCAL=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:11023: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_WORKING_AF_LOCAL=yes else @@ -10984,7 +11043,7 @@ EOF fi echo $ac_n "checking for broken getgroups""... $ac_c" 1>&6 -echo "configure:10988: checking for broken getgroups" >&5 +echo "configure:11047: checking for broken getgroups" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_BROKEN_GETGROUPS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10993,11 +11052,11 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_BROKEN_GETGROUPS=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:11060: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_BROKEN_GETGROUPS=yes else @@ -11020,7 +11079,7 @@ EOF fi echo $ac_n "checking whether getpass should be replaced""... $ac_c" 1>&6 -echo "configure:11024: checking whether getpass should be replaced" >&5 +echo "configure:11083: checking whether getpass should be replaced" >&5 if eval "test \"`echo '$''{'samba_cv_REPLACE_GETPASS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11028,7 +11087,7 @@ else SAVE_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/popt -I${srcdir-.}/smbwrapper" cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:11104: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_REPLACE_GETPASS=yes else @@ -11064,7 +11123,7 @@ EOF fi echo $ac_n "checking for broken inet_ntoa""... $ac_c" 1>&6 -echo "configure:11068: checking for broken inet_ntoa" >&5 +echo "configure:11127: checking for broken inet_ntoa" >&5 if eval "test \"`echo '$''{'samba_cv_REPLACE_INET_NTOA'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11073,7 +11132,7 @@ if test "$cross_compiling" = yes; then samba_cv_REPLACE_INET_NTOA=cross else cat > conftest.$ac_ext < @@ -11087,7 +11146,7 @@ if (strcmp(inet_ntoa(ip),"18.52.86.120") && strcmp(inet_ntoa(ip),"120.86.52.18")) { exit(0); } exit(1);} EOF -if { (eval echo configure:11091: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:11150: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_REPLACE_INET_NTOA=yes else @@ -11110,7 +11169,7 @@ EOF fi echo $ac_n "checking for secure mkstemp""... $ac_c" 1>&6 -echo "configure:11114: checking for secure mkstemp" >&5 +echo "configure:11173: checking for secure mkstemp" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_SECURE_MKSTEMP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11119,7 +11178,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_SECURE_MKSTEMP=cross else cat > conftest.$ac_ext < #include @@ -11136,7 +11195,7 @@ main() { exit(0); } EOF -if { (eval echo configure:11140: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:11199: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_SECURE_MKSTEMP=yes else @@ -11159,7 +11218,7 @@ EOF fi echo $ac_n "checking for sysconf(_SC_NGROUPS_MAX)""... $ac_c" 1>&6 -echo "configure:11163: checking for sysconf(_SC_NGROUPS_MAX)" >&5 +echo "configure:11222: checking for sysconf(_SC_NGROUPS_MAX)" >&5 if eval "test \"`echo '$''{'samba_cv_SYSCONF_SC_NGROUPS_MAX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11168,12 +11227,12 @@ if test "$cross_compiling" = yes; then samba_cv_SYSCONF_SC_NGROUPS_MAX=cross else cat > conftest.$ac_ext < main() { exit(sysconf(_SC_NGROUPS_MAX) == -1 ? 1 : 0); } EOF -if { (eval echo configure:11177: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:11236: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_SYSCONF_SC_NGROUPS_MAX=yes else @@ -11196,7 +11255,7 @@ EOF fi echo $ac_n "checking for root""... $ac_c" 1>&6 -echo "configure:11200: checking for root" >&5 +echo "configure:11259: checking for root" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_ROOT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11205,11 +11264,11 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_ROOT=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:11272: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_ROOT=yes else @@ -11237,7 +11296,7 @@ fi # look for a method of finding the list of network interfaces iface=no; echo $ac_n "checking for iface AIX""... $ac_c" 1>&6 -echo "configure:11241: checking for iface AIX" >&5 +echo "configure:11300: checking for iface AIX" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_IFACE_AIX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11246,7 +11305,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_IFACE_AIX=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:11317: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_IFACE_AIX=yes else @@ -11278,7 +11337,7 @@ fi if test $iface = no; then echo $ac_n "checking for iface ifconf""... $ac_c" 1>&6 -echo "configure:11282: checking for iface ifconf" >&5 +echo "configure:11341: checking for iface ifconf" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_IFACE_IFCONF'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11287,7 +11346,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_IFACE_IFCONF=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:11358: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_IFACE_IFCONF=yes else @@ -11320,7 +11379,7 @@ fi if test $iface = no; then echo $ac_n "checking for iface ifreq""... $ac_c" 1>&6 -echo "configure:11324: checking for iface ifreq" >&5 +echo "configure:11383: checking for iface ifreq" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_IFACE_IFREQ'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11329,7 +11388,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_IFACE_IFREQ=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:11400: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_IFACE_IFREQ=yes else @@ -11366,7 +11425,7 @@ fi seteuid=no; if test $seteuid = no; then echo $ac_n "checking for setresuid""... $ac_c" 1>&6 -echo "configure:11370: checking for setresuid" >&5 +echo "configure:11429: checking for setresuid" >&5 if eval "test \"`echo '$''{'samba_cv_USE_SETRESUID'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11375,7 +11434,7 @@ if test "$cross_compiling" = yes; then samba_cv_USE_SETRESUID=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:11446: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_USE_SETRESUID=yes else @@ -11409,7 +11468,7 @@ fi if test $seteuid = no; then echo $ac_n "checking for setreuid""... $ac_c" 1>&6 -echo "configure:11413: checking for setreuid" >&5 +echo "configure:11472: checking for setreuid" >&5 if eval "test \"`echo '$''{'samba_cv_USE_SETREUID'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11418,7 +11477,7 @@ if test "$cross_compiling" = yes; then samba_cv_USE_SETREUID=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:11489: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_USE_SETREUID=yes else @@ -11451,7 +11510,7 @@ fi if test $seteuid = no; then echo $ac_n "checking for seteuid""... $ac_c" 1>&6 -echo "configure:11455: checking for seteuid" >&5 +echo "configure:11514: checking for seteuid" >&5 if eval "test \"`echo '$''{'samba_cv_USE_SETEUID'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11460,7 +11519,7 @@ if test "$cross_compiling" = yes; then samba_cv_USE_SETEUID=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:11531: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_USE_SETEUID=yes else @@ -11493,7 +11552,7 @@ fi if test $seteuid = no; then echo $ac_n "checking for setuidx""... $ac_c" 1>&6 -echo "configure:11497: checking for setuidx" >&5 +echo "configure:11556: checking for setuidx" >&5 if eval "test \"`echo '$''{'samba_cv_USE_SETUIDX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11502,7 +11561,7 @@ if test "$cross_compiling" = yes; then samba_cv_USE_SETUIDX=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:11573: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_USE_SETUIDX=yes else @@ -11535,7 +11594,7 @@ fi echo $ac_n "checking for working mmap""... $ac_c" 1>&6 -echo "configure:11539: checking for working mmap" >&5 +echo "configure:11598: checking for working mmap" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_MMAP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11544,11 +11603,11 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_MMAP=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:11611: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_MMAP=yes else @@ -11571,7 +11630,7 @@ EOF fi echo $ac_n "checking for ftruncate needs root""... $ac_c" 1>&6 -echo "configure:11575: checking for ftruncate needs root" >&5 +echo "configure:11634: checking for ftruncate needs root" >&5 if eval "test \"`echo '$''{'samba_cv_FTRUNCATE_NEEDS_ROOT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11580,11 +11639,11 @@ if test "$cross_compiling" = yes; then samba_cv_FTRUNCATE_NEEDS_ROOT=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:11647: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_FTRUNCATE_NEEDS_ROOT=yes else @@ -11607,7 +11666,7 @@ EOF fi echo $ac_n "checking for fcntl locking""... $ac_c" 1>&6 -echo "configure:11611: checking for fcntl locking" >&5 +echo "configure:11670: checking for fcntl locking" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_FCNTL_LOCK'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11616,11 +11675,11 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_FCNTL_LOCK=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:11683: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_FCNTL_LOCK=yes else @@ -11643,7 +11702,7 @@ EOF fi echo $ac_n "checking for broken (glibc2.1/x86) 64 bit fcntl locking""... $ac_c" 1>&6 -echo "configure:11647: checking for broken (glibc2.1/x86) 64 bit fcntl locking" >&5 +echo "configure:11706: checking for broken (glibc2.1/x86) 64 bit fcntl locking" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_BROKEN_FCNTL64_LOCKS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11652,11 +11711,11 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_BROKEN_FCNTL64_LOCKS=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:11719: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_BROKEN_FCNTL64_LOCKS=yes else @@ -11681,7 +11740,7 @@ else echo $ac_n "checking for 64 bit fcntl locking""... $ac_c" 1>&6 -echo "configure:11685: checking for 64 bit fcntl locking" >&5 +echo "configure:11744: checking for 64 bit fcntl locking" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_STRUCT_FLOCK64'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11690,7 +11749,7 @@ else samba_cv_HAVE_STRUCT_FLOCK64=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:11777: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_STRUCT_FLOCK64=yes else @@ -11739,13 +11798,13 @@ EOF fi echo $ac_n "checking for st_blocks in struct stat""... $ac_c" 1>&6 -echo "configure:11743: checking for st_blocks in struct stat" >&5 +echo "configure:11802: checking for st_blocks in struct stat" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_STAT_ST_BLOCKS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -11754,7 +11813,7 @@ int main() { struct stat st; st.st_blocks = 0; ; return 0; } EOF -if { (eval echo configure:11758: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:11817: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_STAT_ST_BLOCKS=yes else @@ -11774,16 +11833,52 @@ EOF fi +echo $ac_n "checking for st_blksize in struct stat""... $ac_c" 1>&6 +echo "configure:11838: checking for st_blksize in struct stat" >&5 +if eval "test \"`echo '$''{'samba_cv_HAVE_STAT_ST_BLKSIZE'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + +cat > conftest.$ac_ext < +#include +#include +int main() { +struct stat st; st.st_blksize = 0; +; return 0; } +EOF +if { (eval echo configure:11853: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + samba_cv_HAVE_STAT_ST_BLKSIZE=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + samba_cv_HAVE_STAT_ST_BLKSIZE=no +fi +rm -f conftest* +fi + +echo "$ac_t""$samba_cv_HAVE_STAT_ST_BLKSIZE" 1>&6 +if test x"$samba_cv_HAVE_STAT_ST_BLKSIZE" = x"yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_STAT_ST_BLKSIZE 1 +EOF + +fi + case "$host_os" in *linux*) echo $ac_n "checking for broken RedHat 7.2 system header files""... $ac_c" 1>&6 -echo "configure:11781: checking for broken RedHat 7.2 system header files" >&5 +echo "configure:11876: checking for broken RedHat 7.2 system header files" >&5 if eval "test \"`echo '$''{'samba_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:11896: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS=no else @@ -11820,13 +11915,13 @@ fi esac echo $ac_n "checking for broken nisplus include files""... $ac_c" 1>&6 -echo "configure:11824: checking for broken nisplus include files" >&5 +echo "configure:11919: checking for broken nisplus include files" >&5 if eval "test \"`echo '$''{'samba_cv_BROKEN_NISPLUS_INCLUDE_FILES'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if defined(HAVE_RPCSVC_NIS_H) @@ -11836,7 +11931,7 @@ int main() { int i; ; return 0; } EOF -if { (eval echo configure:11840: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:11935: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_BROKEN_NISPLUS_INCLUDE_FILES=no else @@ -11860,7 +11955,7 @@ fi ################################################# # check for smbwrapper support echo $ac_n "checking whether to use smbwrapper""... $ac_c" 1>&6 -echo "configure:11864: checking whether to use smbwrapper" >&5 +echo "configure:11959: checking whether to use smbwrapper" >&5 # Check whether --with-smbwrapper or --without-smbwrapper was given. if test "${with_smbwrapper+set}" = set; then withval="$with_smbwrapper" @@ -11907,7 +12002,7 @@ fi ################################################# # check for AFS clear-text auth support echo $ac_n "checking whether to use AFS clear-text auth""... $ac_c" 1>&6 -echo "configure:11911: checking whether to use AFS clear-text auth" >&5 +echo "configure:12006: checking whether to use AFS clear-text auth" >&5 # Check whether --with-afs or --without-afs was given. if test "${with_afs+set}" = set; then withval="$with_afs" @@ -11933,7 +12028,7 @@ fi ################################################# # check for the DFS clear-text auth system echo $ac_n "checking whether to use DFS clear-text auth""... $ac_c" 1>&6 -echo "configure:11937: checking whether to use DFS clear-text auth" >&5 +echo "configure:12032: checking whether to use DFS clear-text auth" >&5 # Check whether --with-dfs or --without-dfs was given. if test "${with_dfs+set}" = set; then withval="$with_dfs" @@ -11955,11 +12050,68 @@ else fi +################################################# +# active directory support + +with_ads_support=yes +echo $ac_n "checking whether to use Active Directory""... $ac_c" 1>&6 +echo "configure:12059: checking whether to use Active Directory" >&5 + +# Check whether --with-ads or --without-ads was given. +if test "${with_ads+set}" = set; then + withval="$with_ads" + case "$withval" in + no) + with_ads_support=no + ;; + esac +fi + + +if test x"$with_ads_support" = x"yes"; then + cat >> confdefs.h <<\EOF +#define WITH_ADS 1 +EOF + +fi + +echo "$ac_t""$with_ads_support" 1>&6 + +FOUND_KRB5=no +if test x"$with_ads_support" = x"yes"; then + ################################################# + # check for location of Kerberos 5 install + echo $ac_n "checking for kerberos 5 install path""... $ac_c" 1>&6 +echo "configure:12087: checking for kerberos 5 install path" >&5 + # Check whether --with-krb5 or --without-krb5 was given. +if test "${with_krb5+set}" = set; then + withval="$with_krb5" + case "$withval" in + no) + echo "$ac_t""no" 1>&6 + ;; + *) + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lkrb5" + CFLAGS="$CFLAGS -I$withval/include" + CPPFLAGS="$CPPFLAGS -I$withval/include" + LDFLAGS="$LDFLAGS -L$withval/lib" + FOUND_KRB5=yes + ;; + esac +else + echo "$ac_t""no" 1>&6 + +fi + + + +if test x$FOUND_KRB5 = x"no"; then ################################################# # see if this box has the RedHat location for kerberos echo $ac_n "checking for /usr/kerberos""... $ac_c" 1>&6 -echo "configure:11963: checking for /usr/kerberos" >&5 +echo "configure:12115: checking for /usr/kerberos" >&5 if test -d /usr/kerberos; then LDFLAGS="$LDFLAGS -L/usr/kerberos/lib" CFLAGS="$CFLAGS -I/usr/kerberos/include" @@ -11968,50 +12120,27 @@ if test -d /usr/kerberos; then else echo "$ac_t""no" 1>&6 fi - -################################################# -# check for location of Kerberos 5 install -echo $ac_n "checking for kerberos 5 install path""... $ac_c" 1>&6 -echo "configure:11976: checking for kerberos 5 install path" >&5 -# Check whether --with-krb5 or --without-krb5 was given. -if test "${with_krb5+set}" = set; then - withval="$with_krb5" - case "$withval" in - no) - echo "$ac_t""no" 1>&6 - ;; - *) - echo "$ac_t""yes" 1>&6 - LIBS="$LIBS -lkrb5" - CFLAGS="$CFLAGS -I$withval/include" - CPPFLAGS="$CPPFLAGS -I$withval/include" - LDFLAGS="$LDFLAGS -L$withval/lib" - ;; - esac -else - echo "$ac_t""no" 1>&6 - fi -# now check for krb5.h. Some systems have the libraries without the headers! -# note that this check is done here to allow for different kerberos -# include paths -for ac_hdr in krb5.h + # now check for krb5.h. Some systems have the libraries without the headers! + # note that this check is done here to allow for different kerberos + # include paths + for ac_hdr in krb5.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:12005: checking for $ac_hdr" >&5 +echo "configure:12134: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:12015: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:12144: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -12038,23 +12167,23 @@ fi done -# now check for gssapi headers. This is also done here to allow for -# different kerberos include paths -for ac_hdr in gssapi/gssapi_generic.h gssapi/gssapi.h + # now check for gssapi headers. This is also done here to allow for + # different kerberos include paths + for ac_hdr in gssapi/gssapi_generic.h gssapi/gssapi.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:12048: checking for $ac_hdr" >&5 +echo "configure:12177: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:12058: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:12187: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -12081,10 +12210,10 @@ fi done -################################################################## -# we might need the k5crypto and com_err libraries on some systems -echo $ac_n "checking for _et_list in -lcom_err""... $ac_c" 1>&6 -echo "configure:12088: checking for _et_list in -lcom_err" >&5 + ################################################################## + # we might need the k5crypto and com_err libraries on some systems + echo $ac_n "checking for _et_list in -lcom_err""... $ac_c" 1>&6 +echo "configure:12217: checking for _et_list in -lcom_err" >&5 ac_lib_var=`echo com_err'_'_et_list | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -12092,7 +12221,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcom_err $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12236: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -12123,8 +12252,8 @@ else echo "$ac_t""no" 1>&6 fi -echo $ac_n "checking for krb5_encrypt_data in -lk5crypto""... $ac_c" 1>&6 -echo "configure:12128: checking for krb5_encrypt_data in -lk5crypto" >&5 + echo $ac_n "checking for krb5_encrypt_data in -lk5crypto""... $ac_c" 1>&6 +echo "configure:12257: checking for krb5_encrypt_data in -lk5crypto" >&5 ac_lib_var=`echo k5crypto'_'krb5_encrypt_data | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -12132,7 +12261,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lk5crypto $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12276: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -12164,11 +12293,11 @@ else fi -######################################################## -# now see if we can find the krb5 libs in standard paths -# or as specified above -echo $ac_n "checking for krb5_mk_req_extended in -lkrb5""... $ac_c" 1>&6 -echo "configure:12172: checking for krb5_mk_req_extended in -lkrb5" >&5 + ######################################################## + # now see if we can find the krb5 libs in standard paths + # or as specified above + echo $ac_n "checking for krb5_mk_req_extended in -lkrb5""... $ac_c" 1>&6 +echo "configure:12301: checking for krb5_mk_req_extended in -lkrb5" >&5 ac_lib_var=`echo krb5'_'krb5_mk_req_extended | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -12176,7 +12305,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lkrb5 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12320: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -12212,10 +12341,10 @@ else fi -######################################################## -# now see if we can find the gssapi libs in standard paths -echo $ac_n "checking for gss_display_status in -lgssapi_krb5""... $ac_c" 1>&6 -echo "configure:12219: checking for gss_display_status in -lgssapi_krb5" >&5 + ######################################################## + # now see if we can find the gssapi libs in standard paths + echo $ac_n "checking for gss_display_status in -lgssapi_krb5""... $ac_c" 1>&6 +echo "configure:12348: checking for gss_display_status in -lgssapi_krb5" >&5 ac_lib_var=`echo gssapi_krb5'_'gss_display_status | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -12223,7 +12352,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgssapi_krb5 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12367: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -12258,12 +12387,35 @@ else echo "$ac_t""no" 1>&6 fi +fi + +######################################################## +# Compile with LDAP support? + +with_ldap_support=yes +echo $ac_n "checking whether to use LDAP""... $ac_c" 1>&6 +echo "configure:12398: checking whether to use LDAP" >&5 -################################################################## -# we might need the lber lib on some systems. To avoid link errors -# this test must be before the libldap test -echo $ac_n "checking for ber_scanf in -llber""... $ac_c" 1>&6 -echo "configure:12267: checking for ber_scanf in -llber" >&5 +# Check whether --with-ldap or --without-ldap was given. +if test "${with_ldap+set}" = set; then + withval="$with_ldap" + case "$withval" in + no) + with_ldap_support=no + ;; + esac +fi + + +echo "$ac_t""$with_ldap_support" 1>&6 + +if test x"$with_ldap_support" = x"yes"; then + + ################################################################## + # we might need the lber lib on some systems. To avoid link errors + # this test must be before the libldap test + echo $ac_n "checking for ber_scanf in -llber""... $ac_c" 1>&6 +echo "configure:12419: checking for ber_scanf in -llber" >&5 ac_lib_var=`echo lber'_'ber_scanf | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -12271,7 +12423,7 @@ else ac_save_LIBS="$LIBS" LIBS="-llber $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12438: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -12303,11 +12455,11 @@ else fi -######################################################## -# now see if we can find the ldap libs in standard paths -if test x$have_ldap != xyes; then -echo $ac_n "checking for ldap_domain2hostlist in -lldap""... $ac_c" 1>&6 -echo "configure:12311: checking for ldap_domain2hostlist in -lldap" >&5 + ######################################################## + # now see if we can find the ldap libs in standard paths + if test x$have_ldap != xyes; then + echo $ac_n "checking for ldap_domain2hostlist in -lldap""... $ac_c" 1>&6 +echo "configure:12463: checking for ldap_domain2hostlist in -lldap" >&5 ac_lib_var=`echo ldap'_'ldap_domain2hostlist | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -12315,7 +12467,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lldap $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12482: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -12357,12 +12509,12 @@ fi for ac_func in ldap_set_rebind_proc do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:12361: checking for $ac_func" >&5 +echo "configure:12513: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12541: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -12410,13 +12562,13 @@ fi done echo $ac_n "checking whether ldap_set_rebind_proc takes 3 arguments""... $ac_c" 1>&6 -echo "configure:12414: checking whether ldap_set_rebind_proc takes 3 arguments" >&5 +echo "configure:12566: checking whether ldap_set_rebind_proc takes 3 arguments" >&5 if eval "test \"`echo '$''{'pam_ldap_cv_ldap_set_rebind_proc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -12425,7 +12577,7 @@ int main() { ldap_set_rebind_proc(0, 0, 0); ; return 0; } EOF -if { (eval echo configure:12429: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:12581: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* pam_ldap_cv_ldap_set_rebind_proc=3 else @@ -12442,12 +12594,13 @@ echo "$ac_t""$pam_ldap_cv_ldap_set_rebind_proc" 1>&6 #define LDAP_SET_REBIND_PROC_ARGS $pam_ldap_cv_ldap_set_rebind_proc EOF + fi fi ################################################# # check for automount support echo $ac_n "checking whether to use AUTOMOUNT""... $ac_c" 1>&6 -echo "configure:12451: checking whether to use AUTOMOUNT" >&5 +echo "configure:12604: checking whether to use AUTOMOUNT" >&5 # Check whether --with-automount or --without-automount was given. if test "${with_automount+set}" = set; then withval="$with_automount" @@ -12472,7 +12625,7 @@ fi ################################################# # check for smbmount support echo $ac_n "checking whether to use SMBMOUNT""... $ac_c" 1>&6 -echo "configure:12476: checking whether to use SMBMOUNT" >&5 +echo "configure:12629: checking whether to use SMBMOUNT" >&5 # Check whether --with-smbmount or --without-smbmount was given. if test "${with_smbmount+set}" = set; then withval="$with_smbmount" @@ -12509,7 +12662,7 @@ fi # check for a PAM clear-text auth, accounts, password and session support with_pam_for_crypt=no echo $ac_n "checking whether to use PAM""... $ac_c" 1>&6 -echo "configure:12513: checking whether to use PAM" >&5 +echo "configure:12666: checking whether to use PAM" >&5 # Check whether --with-pam or --without-pam was given. if test "${with_pam+set}" = set; then withval="$with_pam" @@ -12535,7 +12688,7 @@ fi # we can't build a pam module if we don't have pam. echo $ac_n "checking for pam_get_data in -lpam""... $ac_c" 1>&6 -echo "configure:12539: checking for pam_get_data in -lpam" >&5 +echo "configure:12692: checking for pam_get_data in -lpam" >&5 ac_lib_var=`echo pam'_'pam_get_data | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -12543,7 +12696,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpam $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12711: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -12581,7 +12734,7 @@ fi ################################################# # check for pam_smbpass support echo $ac_n "checking whether to use pam_smbpass""... $ac_c" 1>&6 -echo "configure:12585: checking whether to use pam_smbpass" >&5 +echo "configure:12738: checking whether to use pam_smbpass" >&5 # Check whether --with-pam_smbpass or --without-pam_smbpass was given. if test "${with_pam_smbpass+set}" = set; then withval="$with_pam_smbpass" @@ -12615,16 +12768,16 @@ fi ############################################### # test for where we get crypt() from, but only # if not using PAM -if test $with_pam_for_crypt = no; then +if test x"$with_pam_for_crypt" = x"no"; then for ac_func in crypt do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:12623: checking for $ac_func" >&5 +echo "configure:12776: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12804: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -12673,7 +12826,7 @@ done if test x"$ac_cv_func_crypt" = x"no"; then echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6 -echo "configure:12677: checking for crypt in -lcrypt" >&5 +echo "configure:12830: checking for crypt in -lcrypt" >&5 ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -12681,7 +12834,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcrypt $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12849: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -12727,7 +12880,7 @@ fi ## if test $with_pam_for_crypt = no; then echo $ac_n "checking for a crypt that needs truncated salt""... $ac_c" 1>&6 -echo "configure:12731: checking for a crypt that needs truncated salt" >&5 +echo "configure:12884: checking for a crypt that needs truncated salt" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_TRUNCATED_SALT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -12736,11 +12889,11 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_TRUNCATED_SALT=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:12897: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_TRUNCATED_SALT=no else @@ -12763,6 +12916,30 @@ EOF fi fi +# New experimental SAM system + +echo $ac_n "checking whether to build the new (experimental) SAM database""... $ac_c" 1>&6 +echo "configure:12923: checking whether to build the new (experimental) SAM database" >&5 +# Check whether --with-sam or --without-sam was given. +if test "${with_sam+set}" = set; then + withval="$with_sam" + case "$withval" in + yes) + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define WITH_SAM 1 +EOF + + ;; + *) + echo "$ac_t""no" 1>&6 + ;; + esac +else + echo "$ac_t""no" 1>&6 + +fi + ######################################################################################## @@ -12774,7 +12951,7 @@ fi ################################################# # check for a TDB password database echo $ac_n "checking whether to use TDB SAM database""... $ac_c" 1>&6 -echo "configure:12778: checking whether to use TDB SAM database" >&5 +echo "configure:12955: checking whether to use TDB SAM database" >&5 # Check whether --with-tdbsam or --without-tdbsam was given. if test "${with_tdbsam+set}" = set; then withval="$with_tdbsam" @@ -12799,7 +12976,7 @@ fi ################################################# # check for a NISPLUS password database echo $ac_n "checking whether to use NISPLUS SAM database""... $ac_c" 1>&6 -echo "configure:12803: checking whether to use NISPLUS SAM database" >&5 +echo "configure:12980: checking whether to use NISPLUS SAM database" >&5 # Check whether --with-nisplussam or --without-nisplussam was given. if test "${with_nisplussam+set}" = set; then withval="$with_nisplussam" @@ -12830,7 +13007,7 @@ fi ################################################# # check for a NISPLUS_HOME support echo $ac_n "checking whether to use NISPLUS_HOME""... $ac_c" 1>&6 -echo "configure:12834: checking whether to use NISPLUS_HOME" >&5 +echo "configure:13011: checking whether to use NISPLUS_HOME" >&5 # Check whether --with-nisplus-home or --without-nisplus-home was given. if test "${with_nisplus_home+set}" = set; then withval="$with_nisplus_home" @@ -12855,7 +13032,7 @@ fi ################################################# # check for syslog logging echo $ac_n "checking whether to use syslog logging""... $ac_c" 1>&6 -echo "configure:12859: checking whether to use syslog logging" >&5 +echo "configure:13036: checking whether to use syslog logging" >&5 # Check whether --with-syslog or --without-syslog was given. if test "${with_syslog+set}" = set; then withval="$with_syslog" @@ -12880,7 +13057,7 @@ fi ################################################# # check for a shared memory profiling support echo $ac_n "checking whether to use profiling""... $ac_c" 1>&6 -echo "configure:12884: checking whether to use profiling" >&5 +echo "configure:13061: checking whether to use profiling" >&5 # Check whether --with-profiling-data or --without-profiling-data was given. if test "${with_profiling_data+set}" = set; then withval="$with_profiling_data" @@ -12908,7 +13085,7 @@ fi QUOTAOBJS=smbd/noquotas.o echo $ac_n "checking whether to support disk-quotas""... $ac_c" 1>&6 -echo "configure:12912: checking whether to support disk-quotas" >&5 +echo "configure:13089: checking whether to support disk-quotas" >&5 # Check whether --with-quotas or --without-quotas was given. if test "${with_quotas+set}" = set; then withval="$with_quotas" @@ -12919,13 +13096,13 @@ if test "${with_quotas+set}" = set; then *linux*) # Check for kernel 2.4.x quota braindamage... echo $ac_n "checking for linux 2.4.x quota braindamage..""... $ac_c" 1>&6 -echo "configure:12923: checking for linux 2.4.x quota braindamage.." >&5 +echo "configure:13100: checking for linux 2.4.x quota braindamage.." >&5 if eval "test \"`echo '$''{'samba_cv_linux_2_4_quota_braindamage'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -12937,7 +13114,7 @@ int main() { struct mem_dqblk D; ; return 0; } EOF -if { (eval echo configure:12941: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:13118: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_linux_2_4_quota_braindamage=yes else @@ -12986,7 +13163,7 @@ fi # check for experimental utmp accounting echo $ac_n "checking whether to support utmp accounting""... $ac_c" 1>&6 -echo "configure:12990: checking whether to support utmp accounting" >&5 +echo "configure:13167: checking whether to support utmp accounting" >&5 # Check whether --with-utmp or --without-utmp was given. if test "${with_utmp+set}" = set; then withval="$with_utmp" @@ -13011,7 +13188,7 @@ fi ################################################# # choose native language(s) of man pages echo $ac_n "checking chosen man pages' language(s)""... $ac_c" 1>&6 -echo "configure:13015: checking chosen man pages' language(s)" >&5 +echo "configure:13192: checking chosen man pages' language(s)" >&5 # Check whether --with-manpages-langs or --without-manpages-langs was given. if test "${with_manpages_langs+set}" = set; then withval="$with_manpages_langs" @@ -13042,7 +13219,7 @@ fi LIBSMBCLIENT_SHARED= LIBSMBCLIENT= echo $ac_n "checking whether to build the libsmbclient shared library""... $ac_c" 1>&6 -echo "configure:13046: checking whether to build the libsmbclient shared library" >&5 +echo "configure:13223: checking whether to build the libsmbclient shared library" >&5 # Check whether --with-libsmbclient or --without-libsmbclient was given. if test "${with_libsmbclient+set}" = set; then withval="$with_libsmbclient" @@ -13070,14 +13247,14 @@ fi ################################################# # these tests are taken from the GNU fileutils package echo "checking how to get filesystem space usage" 1>&6 -echo "configure:13074: checking how to get filesystem space usage" >&5 +echo "configure:13251: checking how to get filesystem space usage" >&5 space=no # Test for statvfs64. if test $space = no; then # SVR4 echo $ac_n "checking statvfs64 function (SVR4)""... $ac_c" 1>&6 -echo "configure:13081: checking statvfs64 function (SVR4)" >&5 +echo "configure:13258: checking statvfs64 function (SVR4)" >&5 if eval "test \"`echo '$''{'fu_cv_sys_stat_statvfs64'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -13085,7 +13262,7 @@ else fu_cv_sys_stat_statvfs64=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:13280: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then fu_cv_sys_stat_statvfs64=yes else @@ -13132,12 +13309,12 @@ fi if test $space = no; then # SVR4 echo $ac_n "checking statvfs function (SVR4)""... $ac_c" 1>&6 -echo "configure:13136: checking statvfs function (SVR4)" >&5 +echo "configure:13313: checking statvfs function (SVR4)" >&5 if eval "test \"`echo '$''{'fu_cv_sys_stat_statvfs'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -13145,7 +13322,7 @@ int main() { struct statvfs fsd; statvfs (0, &fsd); ; return 0; } EOF -if { (eval echo configure:13149: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13326: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* fu_cv_sys_stat_statvfs=yes else @@ -13170,7 +13347,7 @@ fi if test $space = no; then # DEC Alpha running OSF/1 echo $ac_n "checking for 3-argument statfs function (DEC OSF/1)""... $ac_c" 1>&6 -echo "configure:13174: checking for 3-argument statfs function (DEC OSF/1)" >&5 +echo "configure:13351: checking for 3-argument statfs function (DEC OSF/1)" >&5 if eval "test \"`echo '$''{'fu_cv_sys_stat_statfs3_osf1'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -13178,7 +13355,7 @@ else fu_cv_sys_stat_statfs3_osf1=no else cat > conftest.$ac_ext < @@ -13191,7 +13368,7 @@ else exit (statfs (".", &fsd, sizeof (struct statfs))); } EOF -if { (eval echo configure:13195: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:13372: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then fu_cv_sys_stat_statfs3_osf1=yes else @@ -13218,7 +13395,7 @@ fi if test $space = no; then # AIX echo $ac_n "checking for two-argument statfs with statfs.bsize member (AIX, 4.3BSD)""... $ac_c" 1>&6 -echo "configure:13222: checking for two-argument statfs with statfs.bsize member (AIX, 4.3BSD)" >&5 +echo "configure:13399: checking for two-argument statfs with statfs.bsize member (AIX, 4.3BSD)" >&5 if eval "test \"`echo '$''{'fu_cv_sys_stat_statfs2_bsize'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -13226,7 +13403,7 @@ else fu_cv_sys_stat_statfs2_bsize=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:13426: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then fu_cv_sys_stat_statfs2_bsize=yes else @@ -13272,7 +13449,7 @@ fi if test $space = no; then # SVR3 echo $ac_n "checking for four-argument statfs (AIX-3.2.5, SVR3)""... $ac_c" 1>&6 -echo "configure:13276: checking for four-argument statfs (AIX-3.2.5, SVR3)" >&5 +echo "configure:13453: checking for four-argument statfs (AIX-3.2.5, SVR3)" >&5 if eval "test \"`echo '$''{'fu_cv_sys_stat_statfs4'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -13280,7 +13457,7 @@ else fu_cv_sys_stat_statfs4=no else cat > conftest.$ac_ext < #include @@ -13290,7 +13467,7 @@ else exit (statfs (".", &fsd, sizeof fsd, 0)); } EOF -if { (eval echo configure:13294: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:13471: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then fu_cv_sys_stat_statfs4=yes else @@ -13317,7 +13494,7 @@ fi if test $space = no; then # 4.4BSD and NetBSD echo $ac_n "checking for two-argument statfs with statfs.fsize member (4.4BSD and NetBSD)""... $ac_c" 1>&6 -echo "configure:13321: checking for two-argument statfs with statfs.fsize member (4.4BSD and NetBSD)" >&5 +echo "configure:13498: checking for two-argument statfs with statfs.fsize member (4.4BSD and NetBSD)" >&5 if eval "test \"`echo '$''{'fu_cv_sys_stat_statfs2_fsize'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -13325,7 +13502,7 @@ else fu_cv_sys_stat_statfs2_fsize=no else cat > conftest.$ac_ext < #ifdef HAVE_SYS_PARAM_H @@ -13341,7 +13518,7 @@ else exit (statfs (".", &fsd)); } EOF -if { (eval echo configure:13345: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:13522: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then fu_cv_sys_stat_statfs2_fsize=yes else @@ -13368,7 +13545,7 @@ fi if test $space = no; then # Ultrix echo $ac_n "checking for two-argument statfs with struct fs_data (Ultrix)""... $ac_c" 1>&6 -echo "configure:13372: checking for two-argument statfs with struct fs_data (Ultrix)" >&5 +echo "configure:13549: checking for two-argument statfs with struct fs_data (Ultrix)" >&5 if eval "test \"`echo '$''{'fu_cv_sys_stat_fs_data'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -13376,7 +13553,7 @@ else fu_cv_sys_stat_fs_data=no else cat > conftest.$ac_ext < #ifdef HAVE_SYS_PARAM_H @@ -13396,7 +13573,7 @@ else exit (statfs (".", &fsd) != 1); } EOF -if { (eval echo configure:13400: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:13577: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then fu_cv_sys_stat_fs_data=yes else @@ -13429,9 +13606,9 @@ fi # file support. # echo $ac_n "checking if large file support can be enabled""... $ac_c" 1>&6 -echo "configure:13433: checking if large file support can be enabled" >&5 +echo "configure:13610: checking if large file support can be enabled" >&5 cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:13625: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_EXPLICIT_LARGEFILE_SUPPORT=yes else @@ -13509,7 +13686,7 @@ fi # check for ACL support echo $ac_n "checking whether to support ACLs""... $ac_c" 1>&6 -echo "configure:13513: checking whether to support ACLs" >&5 +echo "configure:13690: checking whether to support ACLs" >&5 # Check whether --with-acl-support or --without-acl-support was given. if test "${with_acl_support+set}" = set; then withval="$with_acl_support" @@ -13562,7 +13739,7 @@ EOF ;; *) echo $ac_n "checking for acl_get_file in -lacl""... $ac_c" 1>&6 -echo "configure:13566: checking for acl_get_file in -lacl" >&5 +echo "configure:13743: checking for acl_get_file in -lacl" >&5 ac_lib_var=`echo acl'_'acl_get_file | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -13570,7 +13747,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lacl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13762: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -13609,13 +13786,13 @@ else fi echo $ac_n "checking for ACL support""... $ac_c" 1>&6 -echo "configure:13613: checking for ACL support" >&5 +echo "configure:13790: checking for ACL support" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_POSIX_ACLS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -13623,7 +13800,7 @@ int main() { acl_t acl; int entry_id; acl_entry_t *entry_p; return acl_get_entry( acl, entry_id, entry_p); ; return 0; } EOF -if { (eval echo configure:13627: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13804: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* samba_cv_HAVE_POSIX_ACLS=yes else @@ -13643,13 +13820,13 @@ echo "$ac_t""$samba_cv_HAVE_POSIX_ACLS" 1>&6 EOF echo $ac_n "checking for acl_get_perm_np""... $ac_c" 1>&6 -echo "configure:13647: checking for acl_get_perm_np" >&5 +echo "configure:13824: checking for acl_get_perm_np" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_ACL_GET_PERM_NP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -13657,7 +13834,7 @@ int main() { acl_permset_t permset_d; acl_perm_t perm; return acl_get_perm_np( permset_d, perm); ; return 0; } EOF -if { (eval echo configure:13661: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13838: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* samba_cv_HAVE_ACL_GET_PERM_NP=yes else @@ -13698,13 +13875,364 @@ EOF fi +################################################# +# check for sendfile support + +echo $ac_n "checking whether to support sendfile""... $ac_c" 1>&6 +echo "configure:13883: checking whether to support sendfile" >&5 +# Check whether --with-sendfile-support or --without-sendfile-support was given. +if test "${with_sendfile_support+set}" = set; then + withval="$with_sendfile_support" + case "$withval" in + yes) + + case "$host_os" in + *linux*) + echo $ac_n "checking for linux sendfile64 support""... $ac_c" 1>&6 +echo "configure:13893: checking for linux sendfile64 support" >&5 +if eval "test \"`echo '$''{'samba_cv_HAVE_SENDFILE64'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +int main() { +\ +int tofd, fromfd; +off64_t offset; +size_t total; +ssize_t nwritten = sendfile64(tofd, fromfd, &offset, total); + +; return 0; } +EOF +if { (eval echo configure:13911: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + samba_cv_HAVE_SENDFILE64=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + samba_cv_HAVE_SENDFILE64=no +fi +rm -f conftest* +fi + +echo "$ac_t""$samba_cv_HAVE_SENDFILE64" 1>&6 + + echo $ac_n "checking for linux sendfile support""... $ac_c" 1>&6 +echo "configure:13926: checking for linux sendfile support" >&5 +if eval "test \"`echo '$''{'samba_cv_HAVE_SENDFILE'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +int main() { +\ +int tofd, fromfd; +off_t offset; +size_t total; +ssize_t nwritten = sendfile(tofd, fromfd, &offset, total); + +; return 0; } +EOF +if { (eval echo configure:13944: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + samba_cv_HAVE_SENDFILE=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + samba_cv_HAVE_SENDFILE=no +fi +rm -f conftest* +fi + +echo "$ac_t""$samba_cv_HAVE_SENDFILE" 1>&6 + +# Try and cope with broken Linux sendfile.... + echo $ac_n "checking for broken linux sendfile support""... $ac_c" 1>&6 +echo "configure:13960: checking for broken linux sendfile support" >&5 +if eval "test \"`echo '$''{'samba_cv_HAVE_BROKEN_LINUX_SENDFILE'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +int main() { +\ +int tofd, fromfd; +off_t offset; +size_t total; +ssize_t nwritten = sendfile(tofd, fromfd, &offset, total); + +; return 0; } +EOF +if { (eval echo configure:13982: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + samba_cv_HAVE_BROKEN_LINUX_SENDFILE=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + samba_cv_HAVE_BROKEN_LINUX_SENDFILE=no +fi +rm -f conftest* +fi + +echo "$ac_t""$samba_cv_HAVE_BROKEN_LINUX_SENDFILE" 1>&6 + + if test x"$samba_cv_HAVE_SENDFILE64" = x"yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_SENDFILE64 1 +EOF + + cat >> confdefs.h <<\EOF +#define LINUX_SENDFILE_API 1 +EOF + + cat >> confdefs.h <<\EOF +#define WITH_SENDFILE 1 +EOF + + elif test x"$samba_cv_HAVE_SENDFILE" = x"yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_SENDFILE 1 +EOF + + cat >> confdefs.h <<\EOF +#define LINUX_SENDFILE_API 1 +EOF + + cat >> confdefs.h <<\EOF +#define WITH_SENDFILE 1 +EOF + + elif test x"$samba_cv_HAVE_BROKEN_LINUX_SENDFILE" = x"yes"; then + cat >> confdefs.h <<\EOF +#define LINUX_BROKEN_SENDFILE_API 1 +EOF + + cat >> confdefs.h <<\EOF +#define WITH_SENDFILE 1 +EOF + + else + echo "$ac_t""no" 1>&6; + fi + + ;; + *freebsd*) + echo $ac_n "checking for freebsd sendfile support""... $ac_c" 1>&6 +echo "configure:14038: checking for freebsd sendfile support" >&5 +if eval "test \"`echo '$''{'samba_cv_HAVE_SENDFILE'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include +#include +int main() { +\ + int fromfd, tofd; + off_t offset, nwritten; + struct sf_hdtr hdr; + struct iovec hdtrl; + hdr->headers = &hdtrl; + hdr->hdr_cnt = 1; + hdr->trailers = NULL; + hdr->trl_cnt = 0; + hdtrl.iov_base = NULL; + hdtrl.iov_len = 0; + int ret = sendfile(fromfd, tofd, offset, total, &hdr, &nwritten, 0); + +; return 0; } +EOF +if { (eval echo configure:14066: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + samba_cv_HAVE_SENDFILE=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + samba_cv_HAVE_SENDFILE=no +fi +rm -f conftest* +fi + +echo "$ac_t""$samba_cv_HAVE_SENDFILE" 1>&6 + + if test x"$samba_cv_HAVE_SENDFILE" = x"yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_SENDFILE 1 +EOF + + cat >> confdefs.h <<\EOF +#define FREEBSD_SENDFILE_API 1 +EOF + + cat >> confdefs.h <<\EOF +#define WITH_SENDFILE 1 +EOF + + else + echo "$ac_t""no" 1>&6; + fi + ;; + + *hpux*) + echo $ac_n "checking for hpux sendfile64 support""... $ac_c" 1>&6 +echo "configure:14100: checking for hpux sendfile64 support" >&5 +if eval "test \"`echo '$''{'samba_cv_HAVE_SENDFILE64'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include +int main() { +\ + int fromfd, tofd; + size_t total=0; + struct iovec hdtrl[2]; + ssize_t nwritten; + off64_t offset; + + hdtrl[0].iov_base = 0; + hdtrl[0].iov_len = 0; + + nwritten = sendfile64(tofd, fromfd, offset, total, &hdtrl[0], 0); + +; return 0; } +EOF +if { (eval echo configure:14126: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + samba_cv_HAVE_SENDFILE64=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + samba_cv_HAVE_SENDFILE64=no +fi +rm -f conftest* +fi + +echo "$ac_t""$samba_cv_HAVE_SENDFILE64" 1>&6 + if test x"$samba_cv_HAVE_SENDFILE64" = x"yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_SENDFILE64 1 +EOF + + cat >> confdefs.h <<\EOF +#define HPUX_SENDFILE_API 1 +EOF + + cat >> confdefs.h <<\EOF +#define WITH_SENDFILE 1 +EOF + + else + echo "$ac_t""no" 1>&6; + fi + + echo $ac_n "checking for hpux sendfile support""... $ac_c" 1>&6 +echo "configure:14157: checking for hpux sendfile support" >&5 +if eval "test \"`echo '$''{'samba_cv_HAVE_SENDFILE'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include +int main() { +\ + int fromfd, tofd; + size_t total=0; + struct iovec hdtrl[2]; + ssize_t nwritten; + off_t offset; + + hdtrl[0].iov_base = 0; + hdtrl[0].iov_len = 0; + + nwritten = sendfile(tofd, fromfd, offset, total, &hdtrl[0], 0); + +; return 0; } +EOF +if { (eval echo configure:14183: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + samba_cv_HAVE_SENDFILE=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + samba_cv_HAVE_SENDFILE=no +fi +rm -f conftest* +fi + +echo "$ac_t""$samba_cv_HAVE_SENDFILE" 1>&6 + if test x"$samba_cv_HAVE_SENDFILE" = x"yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_SENDFILE 1 +EOF + + cat >> confdefs.h <<\EOF +#define HPUX_SENDFILE_API 1 +EOF + + cat >> confdefs.h <<\EOF +#define WITH_SENDFILE 1 +EOF + + else + echo "$ac_t""no" 1>&6; + fi + + ;; + + *) + ;; + esac + ;; + *) + echo "$ac_t""no" 1>&6 + ;; + esac +else + echo "$ac_t""no" 1>&6 + +fi + + + ################################################# # Check whether winbind is supported on this platform. If so we need to # build and install client programs (WINBIND_TARGETS), sbin programs # (WINBIND_STARGETS) and shared libraries (WINBIND_LTARGETS). echo $ac_n "checking whether to build winbind""... $ac_c" 1>&6 -echo "configure:13708: checking whether to build winbind" >&5 +echo "configure:14236: checking whether to build winbind" >&5 # Initially, the value of $host_os decides whether winbind is supported @@ -13800,20 +14328,20 @@ fi # [#include ]) echo $ac_n "checking whether struct passwd has pw_comment""... $ac_c" 1>&6 -echo "configure:13804: checking whether struct passwd has pw_comment" >&5 +echo "configure:14332: checking whether struct passwd has pw_comment" >&5 if eval "test \"`echo '$''{'samba_cv_passwd_pw_comment'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { struct passwd p; p.pw_comment; ; return 0; } EOF -if { (eval echo configure:13817: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:14345: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_passwd_pw_comment=yes else @@ -13838,20 +14366,20 @@ fi # [#include ]) echo $ac_n "checking whether struct passwd has pw_age""... $ac_c" 1>&6 -echo "configure:13842: checking whether struct passwd has pw_age" >&5 +echo "configure:14370: checking whether struct passwd has pw_age" >&5 if eval "test \"`echo '$''{'samba_cv_passwd_pw_age'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { struct passwd p; p.pw_age; ; return 0; } EOF -if { (eval echo configure:13855: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:14383: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_passwd_pw_age=yes else @@ -13890,7 +14418,7 @@ fi if test x"$INCLUDED_POPT" != x"yes"; then echo $ac_n "checking for poptGetContext in -lpopt""... $ac_c" 1>&6 -echo "configure:13894: checking for poptGetContext in -lpopt" >&5 +echo "configure:14422: checking for poptGetContext in -lpopt" >&5 ac_lib_var=`echo popt'_'poptGetContext | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -13898,7 +14426,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpopt $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14441: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -13933,7 +14461,7 @@ fi fi echo $ac_n "checking whether to use included popt""... $ac_c" 1>&6 -echo "configure:13937: checking whether to use included popt" >&5 +echo "configure:14465: checking whether to use included popt" >&5 if test x"$INCLUDED_POPT" = x"yes"; then echo "$ac_t""yes" 1>&6 BUILD_POPT='$(POPT_OBJS)' @@ -13945,6 +14473,29 @@ fi +################################################# +# Check if the user wants Python + +# At the moment, you can use this to set which Python binary to link +# against. (Libraries built for Python2.2 can't be used by 2.1, +# though they can coexist in different directories.) In the future +# this might make the Python stuff be built by default. + +# Check whether --with-python or --without-python was given. +if test "${with_python+set}" = set; then + withval="$with_python" + case "${withval-python}" in + yes) + PYTHON=python + ;; + *) + PYTHON=${withval-python} + ;; + esac +fi + + + ################################################# # do extra things if we are running insure @@ -13956,16 +14507,16 @@ fi # final configure stuff echo $ac_n "checking configure summary""... $ac_c" 1>&6 -echo "configure:13960: checking configure summary" >&5 +echo "configure:14511: checking configure summary" >&5 if test "$cross_compiling" = yes; then echo "configure: warning: cannot run when cross-compiling" 1>&2 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:14520: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then echo "$ac_t""yes" 1>&6 else @@ -13981,6 +14532,9 @@ fi builddir=`pwd` +# I added make files that are outside /source directory. +# I know this is not a good solution, will work out a better +# solution soon. --simo trap '' 1 2 15 cat > confcache <<\EOF # This file is a shell script that caches the results of configure @@ -14082,7 +14636,7 @@ done ac_given_srcdir=$srcdir ac_given_INSTALL="$INSTALL" -trap 'rm -fr `echo "include/stamp-h Makefile script/findsmb ../examples/VFS/Makefile ../examples/VFS/block/Makefile include/config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +trap 'rm -fr `echo "include/stamp-h Makefile script/findsmb ../examples/VFS/Makefile ../examples/pdb/mysql/Makefile ../examples/pdb/xml/Makefile ../examples/sam/Makefile include/config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then diff --git a/source3/configure.in b/source3/configure.in index db34c266c58..5221b8ec2b4 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -147,6 +147,7 @@ AC_SUBST(POBAD_CC) AC_SUBST(SHLIBEXT) AC_SUBST(LIBSMBCLIENT_SHARED) AC_SUBST(LIBSMBCLIENT) +AC_SUBST(PRINTLIBS) # compile with optimization and without debugging by default CFLAGS="-O ${CFLAGS}" @@ -431,6 +432,7 @@ AC_CHECK_HEADERS(sys/mman.h sys/filio.h sys/priv.h sys/shm.h string.h strings.h AC_CHECK_HEADERS(sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h termio.h) AC_CHECK_HEADERS(sys/termio.h sys/statfs.h sys/dustat.h sys/statvfs.h stdarg.h sys/sockio.h) AC_CHECK_HEADERS(security/pam_modules.h security/_pam_macros.h ldap.h lber.h dlfcn.h) +AC_CHECK_HEADERS(sys/syslog.h syslog.h) # # HPUX has a bug in that including shadow.h causes a re-definition of MAXINT. @@ -496,7 +498,7 @@ if test x$enable_cups != xno; then AC_DEFINE(HAVE_CUPS) CFLAGS="$CFLAGS `$CUPS_CONFIG --cflags`" LDFLAGS="$LDFLAGS `$CUPS_CONFIG --ldflags`" - LIBS="$LIBS `$CUPS_CONFIG --libs`" + PRINTLIBS="$PRINTLIBS `$CUPS_CONFIG --libs`" fi fi @@ -894,7 +896,14 @@ case "$host_os" in SONAMEFLAG="-Wl,-h," PICFLAG="-KPIC" # Is this correct for SunOS ;; - *bsd*) BLDSHARED="true" + *freebsd*) BLDSHARED="true" + LDSHFLAGS="-shared" + DYNEXP="-Wl,--export-dynamic" + SONAMEFLAG="-Wl,-soname," + PICFLAG="-fPIC -DPIC" + AC_DEFINE(STAT_ST_BLOCKSIZE,512) + ;; + *openbsd*) BLDSHARED="true" LDSHFLAGS="-shared" DYNEXP="-Wl,-Bdynamic" SONAMEFLAG="-Wl,-soname," @@ -922,12 +931,10 @@ case "$host_os" in BLDSHARED="true" LDSHFLAGS="-Wl,-bexpall,-bM:SRE,-bnoentry" DYNEXP="-Wl,-brtl,-bexpall" - if test "${GCC}" = "yes"; then - PICFLAG="-O2" - else - PICFLAG="-O2 -qmaxmem=6000" + PICFLAG="-O2" + if test "${GCC}" != "yes"; then ## for funky AIX compiler using strncpy() - CFLAGS="$CFLAGS -D_LINUX_SOURCE_COMPAT" + CFLAGS="$CFLAGS -D_LINUX_SOURCE_COMPAT -qmaxmem=32000" fi AC_DEFINE(STAT_ST_BLOCKSIZE,DEV_BSIZE) @@ -1820,6 +1827,16 @@ if test x"$samba_cv_HAVE_STAT_ST_BLOCKS" = x"yes"; then AC_DEFINE(HAVE_STAT_ST_BLOCKS) fi +AC_CACHE_CHECK([for st_blksize in struct stat],samba_cv_HAVE_STAT_ST_BLKSIZE,[ +AC_TRY_COMPILE([#include +#include +#include ], +[struct stat st; st.st_blksize = 0;], +samba_cv_HAVE_STAT_ST_BLKSIZE=yes,samba_cv_HAVE_STAT_ST_BLKSIZE=no,samba_cv_HAVE_STAT_ST_BLKSIZE=cross)]) +if test x"$samba_cv_HAVE_STAT_ST_BLKSIZE" = x"yes"; then + AC_DEFINE(HAVE_STAT_ST_BLKSIZE) +fi + case "$host_os" in *linux*) AC_CACHE_CHECK([for broken RedHat 7.2 system header files],samba_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS,[ @@ -1924,7 +1941,52 @@ AC_ARG_WITH(dfs, AC_MSG_RESULT(no) ) +################################################# +# active directory support + +with_ads_support=yes +AC_MSG_CHECKING([whether to use Active Directory]) +AC_ARG_WITH(ads, +[ --with-ads Active Directory support (default yes)], +[ case "$withval" in + no) + with_ads_support=no + ;; + esac ]) + +if test x"$with_ads_support" = x"yes"; then + AC_DEFINE(WITH_ADS) +fi + +AC_MSG_RESULT($with_ads_support) + +FOUND_KRB5=no +if test x"$with_ads_support" = x"yes"; then + + ################################################# + # check for location of Kerberos 5 install + AC_MSG_CHECKING(for kerberos 5 install path) + AC_ARG_WITH(krb5, + [ --with-krb5=base-dir Locate Kerberos 5 support (default=/usr)], + [ case "$withval" in + no) + AC_MSG_RESULT(no) + ;; + *) + AC_MSG_RESULT(yes) + LIBS="$LIBS -lkrb5" + CFLAGS="$CFLAGS -I$withval/include" + CPPFLAGS="$CPPFLAGS -I$withval/include" + LDFLAGS="$LDFLAGS -L$withval/lib" + FOUND_KRB5=yes + ;; + esac ], + AC_MSG_RESULT(no) + ) + + +if test x$FOUND_KRB5 = x"no"; then ################################################# # see if this box has the RedHat location for kerberos AC_MSG_CHECKING(for /usr/kerberos) @@ -1936,61 +1998,62 @@ if test -d /usr/kerberos; then else AC_MSG_RESULT(no) fi +fi -################################################# -# check for location of Kerberos 5 install -AC_MSG_CHECKING(for kerberos 5 install path) -AC_ARG_WITH(krb5, -[ --with-krb5=base-dir Locate Kerberos 5 support (default=/usr)], -[ case "$withval" in - no) - AC_MSG_RESULT(no) - ;; - *) - AC_MSG_RESULT(yes) - LIBS="$LIBS -lkrb5" - CFLAGS="$CFLAGS -I$withval/include" - CPPFLAGS="$CPPFLAGS -I$withval/include" - LDFLAGS="$LDFLAGS -L$withval/lib" - ;; - esac ], - AC_MSG_RESULT(no) -) -# now check for krb5.h. Some systems have the libraries without the headers! -# note that this check is done here to allow for different kerberos -# include paths -AC_CHECK_HEADERS(krb5.h) + # now check for krb5.h. Some systems have the libraries without the headers! + # note that this check is done here to allow for different kerberos + # include paths + AC_CHECK_HEADERS(krb5.h) -# now check for gssapi headers. This is also done here to allow for -# different kerberos include paths -AC_CHECK_HEADERS(gssapi/gssapi_generic.h gssapi/gssapi.h) + # now check for gssapi headers. This is also done here to allow for + # different kerberos include paths + AC_CHECK_HEADERS(gssapi/gssapi_generic.h gssapi/gssapi.h) -################################################################## -# we might need the k5crypto and com_err libraries on some systems -AC_CHECK_LIB(com_err, _et_list, [LIBS="$LIBS -lcom_err"]) -AC_CHECK_LIB(k5crypto, krb5_encrypt_data, [LIBS="$LIBS -lk5crypto"]) + ################################################################## + # we might need the k5crypto and com_err libraries on some systems + AC_CHECK_LIB(com_err, _et_list, [LIBS="$LIBS -lcom_err"]) + AC_CHECK_LIB(k5crypto, krb5_encrypt_data, [LIBS="$LIBS -lk5crypto"]) -######################################################## -# now see if we can find the krb5 libs in standard paths -# or as specified above -AC_CHECK_LIB(krb5, krb5_mk_req_extended, [LIBS="$LIBS -lkrb5"; + ######################################################## + # now see if we can find the krb5 libs in standard paths + # or as specified above + AC_CHECK_LIB(krb5, krb5_mk_req_extended, [LIBS="$LIBS -lkrb5"; AC_DEFINE(HAVE_KRB5)]) -######################################################## -# now see if we can find the gssapi libs in standard paths -AC_CHECK_LIB(gssapi_krb5, gss_display_status, [LIBS="$LIBS -lgssapi_krb5"; + ######################################################## + # now see if we can find the gssapi libs in standard paths + AC_CHECK_LIB(gssapi_krb5, gss_display_status, [LIBS="$LIBS -lgssapi_krb5"; AC_DEFINE(HAVE_GSSAPI)]) - -################################################################## -# we might need the lber lib on some systems. To avoid link errors -# this test must be before the libldap test -AC_CHECK_LIB(lber, ber_scanf, [LIBS="$LIBS -llber"]) +fi ######################################################## -# now see if we can find the ldap libs in standard paths -if test x$have_ldap != xyes; then -AC_CHECK_LIB(ldap, ldap_domain2hostlist, [LIBS="$LIBS -lldap"; +# Compile with LDAP support? + +with_ldap_support=yes +AC_MSG_CHECKING([whether to use LDAP]) + +AC_ARG_WITH(ldap, +[ --with-ldap LDAP support (default yes)], +[ case "$withval" in + no) + with_ldap_support=no + ;; + esac ]) + +AC_MSG_RESULT($with_ldap_support) + +if test x"$with_ldap_support" = x"yes"; then + + ################################################################## + # we might need the lber lib on some systems. To avoid link errors + # this test must be before the libldap test + AC_CHECK_LIB(lber, ber_scanf, [LIBS="$LIBS -llber"]) + + ######################################################## + # now see if we can find the ldap libs in standard paths + if test x$have_ldap != xyes; then + AC_CHECK_LIB(ldap, ldap_domain2hostlist, [LIBS="$LIBS -lldap"; AC_DEFINE(HAVE_LDAP)]) ######################################################## @@ -2002,6 +2065,7 @@ AC_CHECK_LIB(ldap, ldap_domain2hostlist, [LIBS="$LIBS -lldap"; #include #include ], [ldap_set_rebind_proc(0, 0, 0);], [pam_ldap_cv_ldap_set_rebind_proc=3], [pam_ldap_cv_ldap_set_rebind_proc=2]) ]) AC_DEFINE_UNQUOTED(LDAP_SET_REBIND_PROC_ARGS, $pam_ldap_cv_ldap_set_rebind_proc) + fi fi ################################################# @@ -2104,7 +2168,7 @@ AC_ARG_WITH(pam_smbpass, ############################################### # test for where we get crypt() from, but only # if not using PAM -if test $with_pam_for_crypt = no; then +if test x"$with_pam_for_crypt" = x"no"; then AC_CHECK_FUNCS(crypt) if test x"$ac_cv_func_crypt" = x"no"; then AC_CHECK_LIB(crypt, crypt, [LIBS="$LIBS -lcrypt"; @@ -2127,6 +2191,22 @@ if test x"$samba_cv_HAVE_TRUNCATED_SALT" = x"yes"; then fi fi +# New experimental SAM system + +AC_MSG_CHECKING([whether to build the new (experimental) SAM database]) +AC_ARG_WITH(sam, +[ --with-sam Build new (experimental) SAM database (default=no)], +[ case "$withval" in + yes) + AC_MSG_RESULT(yes) + AC_DEFINE(WITH_SAM) + ;; + *) + AC_MSG_RESULT(no) + ;; + esac ], + AC_MSG_RESULT(no) +) ######################################################################################## @@ -2633,6 +2713,163 @@ samba_cv_HAVE_ACL_GET_PERM_NP=yes,samba_cv_HAVE_ACL_GET_PERM_NP=no)]) AC_MSG_RESULT(no) ) +################################################# +# check for sendfile support + +AC_MSG_CHECKING(whether to support sendfile) +AC_ARG_WITH(sendfile-support, +[ --with-sendfile-support Include sendfile support (default=no)], +[ case "$withval" in + yes) + + case "$host_os" in + *linux*) + AC_CACHE_CHECK([for linux sendfile64 support],samba_cv_HAVE_SENDFILE64,[ + AC_TRY_LINK([#include ], +[\ +int tofd, fromfd; +off64_t offset; +size_t total; +ssize_t nwritten = sendfile64(tofd, fromfd, &offset, total); +], +samba_cv_HAVE_SENDFILE64=yes,samba_cv_HAVE_SENDFILE64=no)]) + + AC_CACHE_CHECK([for linux sendfile support],samba_cv_HAVE_SENDFILE,[ + AC_TRY_LINK([#include ], +[\ +int tofd, fromfd; +off_t offset; +size_t total; +ssize_t nwritten = sendfile(tofd, fromfd, &offset, total); +], +samba_cv_HAVE_SENDFILE=yes,samba_cv_HAVE_SENDFILE=no)]) + +# Try and cope with broken Linux sendfile.... + AC_CACHE_CHECK([for broken linux sendfile support],samba_cv_HAVE_BROKEN_LINUX_SENDFILE,[ + AC_TRY_LINK([\ +#if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64) +#undef _FILE_OFFSET_BITS +#endif +#include ], +[\ +int tofd, fromfd; +off_t offset; +size_t total; +ssize_t nwritten = sendfile(tofd, fromfd, &offset, total); +], +samba_cv_HAVE_BROKEN_LINUX_SENDFILE=yes,samba_cv_HAVE_BROKEN_LINUX_SENDFILE=no)]) + + if test x"$samba_cv_HAVE_SENDFILE64" = x"yes"; then + AC_DEFINE(HAVE_SENDFILE64) + AC_DEFINE(LINUX_SENDFILE_API) + AC_DEFINE(WITH_SENDFILE) + elif test x"$samba_cv_HAVE_SENDFILE" = x"yes"; then + AC_DEFINE(HAVE_SENDFILE) + AC_DEFINE(LINUX_SENDFILE_API) + AC_DEFINE(WITH_SENDFILE) + elif test x"$samba_cv_HAVE_BROKEN_LINUX_SENDFILE" = x"yes"; then + AC_DEFINE(LINUX_BROKEN_SENDFILE_API) + AC_DEFINE(WITH_SENDFILE) + else + AC_MSG_RESULT(no); + fi + + ;; + *freebsd*) + AC_CACHE_CHECK([for freebsd sendfile support],samba_cv_HAVE_SENDFILE,[ + AC_TRY_LINK([\ +#include +#include +#include ], +[\ + int fromfd, tofd; + off_t offset, nwritten; + struct sf_hdtr hdr; + struct iovec hdtrl; + hdr->headers = &hdtrl; + hdr->hdr_cnt = 1; + hdr->trailers = NULL; + hdr->trl_cnt = 0; + hdtrl.iov_base = NULL; + hdtrl.iov_len = 0; + int ret = sendfile(fromfd, tofd, offset, total, &hdr, &nwritten, 0); +], +samba_cv_HAVE_SENDFILE=yes,samba_cv_HAVE_SENDFILE=no)]) + + if test x"$samba_cv_HAVE_SENDFILE" = x"yes"; then + AC_DEFINE(HAVE_SENDFILE) + AC_DEFINE(FREEBSD_SENDFILE_API) + AC_DEFINE(WITH_SENDFILE) + else + AC_MSG_RESULT(no); + fi + ;; + + *hpux*) + AC_CACHE_CHECK([for hpux sendfile64 support],samba_cv_HAVE_SENDFILE64,[ + AC_TRY_LINK([\ +#include +#include ], +[\ + int fromfd, tofd; + size_t total=0; + struct iovec hdtrl[2]; + ssize_t nwritten; + off64_t offset; + + hdtrl[0].iov_base = 0; + hdtrl[0].iov_len = 0; + + nwritten = sendfile64(tofd, fromfd, offset, total, &hdtrl[0], 0); +], +samba_cv_HAVE_SENDFILE64=yes,samba_cv_HAVE_SENDFILE64=no)]) + if test x"$samba_cv_HAVE_SENDFILE64" = x"yes"; then + AC_DEFINE(HAVE_SENDFILE64) + AC_DEFINE(HPUX_SENDFILE_API) + AC_DEFINE(WITH_SENDFILE) + else + AC_MSG_RESULT(no); + fi + + AC_CACHE_CHECK([for hpux sendfile support],samba_cv_HAVE_SENDFILE,[ + AC_TRY_LINK([\ +#include +#include ], +[\ + int fromfd, tofd; + size_t total=0; + struct iovec hdtrl[2]; + ssize_t nwritten; + off_t offset; + + hdtrl[0].iov_base = 0; + hdtrl[0].iov_len = 0; + + nwritten = sendfile(tofd, fromfd, offset, total, &hdtrl[0], 0); +], +samba_cv_HAVE_SENDFILE=yes,samba_cv_HAVE_SENDFILE=no)]) + if test x"$samba_cv_HAVE_SENDFILE" = x"yes"; then + AC_DEFINE(HAVE_SENDFILE) + AC_DEFINE(HPUX_SENDFILE_API) + AC_DEFINE(WITH_SENDFILE) + else + AC_MSG_RESULT(no); + fi + + ;; + + *) + ;; + esac + ;; + *) + AC_MSG_RESULT(no) + ;; + esac ], + AC_MSG_RESULT(no) +) + + ################################################# # Check whether winbind is supported on this platform. If so we need to # build and install client programs (WINBIND_TARGETS), sbin programs @@ -2778,6 +3015,26 @@ fi AC_SUBST(BUILD_POPT) AC_SUBST(FLAGS1) +################################################# +# Check if the user wants Python + +# At the moment, you can use this to set which Python binary to link +# against. (Libraries built for Python2.2 can't be used by 2.1, +# though they can coexist in different directories.) In the future +# this might make the Python stuff be built by default. + +AC_ARG_WITH(python, +[ --with-python=PYTHONNAME build Python libraries], +[ case "${withval-python}" in + yes) + PYTHON=python + ;; + *) + PYTHON=${withval-python} + ;; + esac ]) +AC_SUBST(PYTHON) + ################################################# # do extra things if we are running insure @@ -2797,7 +3054,10 @@ AC_TRY_RUN([#include "${srcdir-.}/tests/summary.c"], builddir=`pwd` AC_SUBST(builddir) -AC_OUTPUT(include/stamp-h Makefile script/findsmb ../examples/VFS/Makefile ../examples/VFS/block/Makefile) +# I added make files that are outside /source directory. +# I know this is not a good solution, will work out a better +# solution soon. --simo +AC_OUTPUT(include/stamp-h Makefile script/findsmb ../examples/VFS/Makefile ../examples/pdb/mysql/Makefile ../examples/pdb/xml/Makefile ../examples/sam/Makefile) ################################################# # Print very concise instructions on building/use diff --git a/source3/groupdb/aliasdb.c b/source3/groupdb/aliasdb.c index 718bf1d7ce1..05f584f980d 100644 --- a/source3/groupdb/aliasdb.c +++ b/source3/groupdb/aliasdb.c @@ -41,9 +41,7 @@ BOOL initialise_alias_db(void) return True; } -#ifdef WITH_NISPLUS - aldb_ops = nisplus_initialise_alias_db(); -#elif defined(WITH_LDAP) +#ifdef WITH_LDAP aldb_ops = ldap_initialise_alias_db(); #else aldb_ops = file_initialise_alias_db(); diff --git a/source3/groupdb/groupdb.c b/source3/groupdb/groupdb.c index c18463741d9..d50e4f7322d 100644 --- a/source3/groupdb/groupdb.c +++ b/source3/groupdb/groupdb.c @@ -39,9 +39,7 @@ BOOL initialise_group_db(void) return True; } -#ifdef WITH_NISPLUS - gpdb_ops = nisplus_initialise_group_db(); -#elif defined(WITH_LDAP) +#ifdef WITH_LDAP gpdb_ops = ldap_initialise_group_db(); #else gpdb_ops = file_initialise_group_db(); diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c index 70d6317a77a..56414312465 100644 --- a/source3/groupdb/mapping.c +++ b/source3/groupdb/mapping.c @@ -434,7 +434,7 @@ BOOL check_priv_in_privilege(PRIVILEGE_SET *priv_set, LUID_ATTR set) } /**************************************************************************** -remove a privilege to a privilege array +remove a privilege from a privilege array ****************************************************************************/ BOOL remove_privilege(PRIVILEGE_SET *priv_set, LUID_ATTR set) { @@ -1156,16 +1156,42 @@ BOOL get_uid_list_of_group(gid_t gid, uid_t **uid, int *num_uids) Create a UNIX group on demand. ****************************************************************************/ -int smb_create_group(char *unix_group) +int smb_create_group(char *unix_group, gid_t *new_gid) { pstring add_script; int ret; + int fd = 0; pstrcpy(add_script, lp_addgroup_script()); if (! *add_script) return -1; pstring_sub(add_script, "%g", unix_group); - ret = smbrun(add_script,NULL); + ret = smbrun(add_script, (new_gid!=NULL) ? &fd : NULL); DEBUG(3,("smb_create_group: Running the command `%s' gave %d\n",add_script,ret)); + if (ret != 0) + return ret; + + if (fd != 0) { + fstring output; + + *new_gid = 0; + if (read(fd, output, sizeof(output)) > 0) { + *new_gid = (gid_t)strtoul(output, NULL, 10); + } + close(fd); + + if (*new_gid == 0) { + /* The output was garbage. We assume nobody + will create group 0 via smbd. Now we try to + get the group via getgrnam. */ + + struct group *grp = getgrnam(unix_group); + if (grp != NULL) + *new_gid = grp->gr_gid; + else + return 1; + } + } + return ret; } @@ -1187,7 +1213,25 @@ int smb_delete_group(char *unix_group) } /**************************************************************************** - Create a UNIX group on demand. + Set a user's primary UNIX group. +****************************************************************************/ +int smb_set_primary_group(const char *unix_group, const char* unix_user) +{ + pstring add_script; + int ret; + + pstrcpy(add_script, lp_setprimarygroup_script()); + if (! *add_script) return -1; + all_string_sub(add_script, "%g", unix_group, sizeof(add_script)); + all_string_sub(add_script, "%u", unix_user, sizeof(add_script)); + ret = smbrun(add_script,NULL); + DEBUG(3,("smb_set_primary_group: " + "Running the command `%s' gave %d\n",add_script,ret)); + return ret; +} + +/**************************************************************************** + Add a user to a UNIX group. ****************************************************************************/ int smb_add_user_group(char *unix_group, char *unix_user) @@ -1205,7 +1249,7 @@ int smb_add_user_group(char *unix_group, char *unix_user) } /**************************************************************************** - Delete a UNIX group on demand. + Delete a user from a UNIX group ****************************************************************************/ int smb_delete_user_group(const char *unix_group, const char *unix_user) diff --git a/source3/include/ads.h b/source3/include/ads.h index 7504a369b4b..0181ae535e0 100644 --- a/source3/include/ads.h +++ b/source3/include/ads.h @@ -24,7 +24,8 @@ typedef struct { char *password; char *user_name; char *kdc_server; - int no_bind; + unsigned flags; + int time_offset; } auth; /* info derived from the servers config */ @@ -32,6 +33,7 @@ typedef struct { char *realm; char *bind_path; char *ldap_server_name; + time_t current_time; } config; } ADS_STRUCT; @@ -92,11 +94,14 @@ typedef struct { /* there are 4 possible types of errors the ads subsystem can produce */ enum ads_error_type {ADS_ERROR_KRB5, ADS_ERROR_GSS, - ADS_ERROR_LDAP, ADS_ERROR_SYSTEM}; + ADS_ERROR_LDAP, ADS_ERROR_SYSTEM, ADS_ERROR_NT}; typedef struct { enum ads_error_type error_type; - int rc; + union err_state{ + int rc; + NTSTATUS nt_status; + } err; /* For error_type = ADS_ERROR_GSS minor_status describe GSS API error */ /* Where rc represents major_status of GSS API error */ int minor_status; @@ -109,12 +114,14 @@ typedef void **ADS_MODLIST; #endif /* macros to simplify error returning */ -#define ADS_ERROR(rc) ads_build_error(ADS_ERROR_LDAP, rc, 0) +#define ADS_ERROR(rc) ADS_ERROR_LDAP(rc) +#define ADS_ERROR_LDAP(rc) ads_build_error(ADS_ERROR_LDAP, rc, 0) #define ADS_ERROR_SYSTEM(rc) ads_build_error(ADS_ERROR_SYSTEM, rc?rc:EINVAL, 0) #define ADS_ERROR_KRB5(rc) ads_build_error(ADS_ERROR_KRB5, rc, 0) #define ADS_ERROR_GSS(rc, minor) ads_build_error(ADS_ERROR_GSS, rc, minor) +#define ADS_ERROR_NT(rc) ads_build_nt_error(ADS_ERROR_NT,rc) -#define ADS_ERR_OK(status) ((status).rc == 0) +#define ADS_ERR_OK(status) ((status.error_type == ADS_ERROR_NT) ? NT_STATUS_IS_OK(status.err.nt_status):(status.err.rc == 0)) #define ADS_SUCCESS ADS_ERROR(0) /* time between reconnect attempts */ @@ -127,24 +134,102 @@ typedef void **ADS_MODLIST; #define ADS_PAGE_CTL_OID "1.2.840.113556.1.4.319" #define ADS_NO_REFERRALS_OID "1.2.840.113556.1.4.1339" #define ADS_SERVER_SORT_OID "1.2.840.113556.1.4.473" +#define ADS_PERMIT_MODIFY_OID "1.2.840.113556.1.4.1413" -#define UF_DONT_EXPIRE_PASSWD 0x10000 -#define UF_MNS_LOGON_ACCOUNT 0x20000 -#define UF_SMARTCARD_REQUIRED 0x40000 -#define UF_TRUSTED_FOR_DELEGATION 0x80000 -#define UF_NOT_DELEGATED 0x100000 -#define UF_USE_DES_KEY_ONLY 0x200000 -#define UF_DONT_REQUIRE_PREAUTH 0x400000 +/* UserFlags for userAccountControl */ +#define UF_SCRIPT 0x00000001 +#define UF_ACCOUNTDISABLE 0x00000002 +#define UF_UNUSED_1 0x00000004 +#define UF_HOMEDIR_REQUIRED 0x00000008 -#define UF_TEMP_DUPLICATE_ACCOUNT 0x0100 -#define UF_NORMAL_ACCOUNT 0x0200 -#define UF_INTERDOMAIN_TRUST_ACCOUNT 0x0800 -#define UF_WORKSTATION_TRUST_ACCOUNT 0x1000 -#define UF_SERVER_TRUST_ACCOUNT 0x2000 +#define UF_LOCKOUT 0x00000010 +#define UF_PASSWD_NOTREQD 0x00000020 +#define UF_PASSWD_CANT_CHANGE 0x00000040 +#define UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED 0x00000080 -/* account types */ -#define ATYPE_GROUP 0x10000000 -#define ATYPE_USER 0x30000000 +#define UF_TEMP_DUPLICATE_ACCOUNT 0x00000100 +#define UF_NORMAL_ACCOUNT 0x00000200 +#define UF_UNUSED_2 0x00000400 +#define UF_INTERDOMAIN_TRUST_ACCOUNT 0x00000800 + +#define UF_WORKSTATION_TRUST_ACCOUNT 0x00001000 +#define UF_SERVER_TRUST_ACCOUNT 0x00002000 +#define UF_UNUSED_3 0x00004000 +#define UF_UNUSED_4 0x00008000 + +#define UF_DONT_EXPIRE_PASSWD 0x00010000 +#define UF_MNS_LOGON_ACCOUNT 0x00020000 +#define UF_SMARTCARD_REQUIRED 0x00040000 +#define UF_TRUSTED_FOR_DELEGATION 0x00080000 + +#define UF_NOT_DELEGATED 0x00100000 +#define UF_USE_DES_KEY_ONLY 0x00200000 +#define UF_DONT_REQUIRE_PREAUTH 0x00400000 +#define UF_UNUSED_5 0x00800000 + +#define UF_UNUSED_6 0x01000000 +#define UF_UNUSED_7 0x02000000 +#define UF_UNUSED_8 0x04000000 +#define UF_UNUSED_9 0x08000000 + +#define UF_UNUSED_10 0x10000000 +#define UF_UNUSED_11 0x20000000 +#define UF_UNUSED_12 0x40000000 +#define UF_UNUSED_13 0x80000000 + +#define UF_MACHINE_ACCOUNT_MASK (\ + UF_INTERDOMAIN_TRUST_ACCOUNT |\ + UF_WORKSTATION_TRUST_ACCOUNT |\ + UF_SERVER_TRUST_ACCOUNT \ + ) + +#define UF_ACCOUNT_TYPE_MASK (\ + UF_TEMP_DUPLICATE_ACCOUNT |\ + UF_NORMAL_ACCOUNT |\ + UF_INTERDOMAIN_TRUST_ACCOUNT |\ + UF_WORKSTATION_TRUST_ACCOUNT |\ + UF_SERVER_TRUST_ACCOUNT \ + ) + +#define UF_SETTABLE_BITS (\ + UF_SCRIPT |\ + UF_ACCOUNTDISABLE |\ + UF_HOMEDIR_REQUIRED |\ + UF_LOCKOUT |\ + UF_PASSWD_NOTREQD |\ + UF_PASSWD_CANT_CHANGE |\ + UF_ACCOUNT_TYPE_MASK | \ + UF_DONT_EXPIRE_PASSWD | \ + UF_MNS_LOGON_ACCOUNT |\ + UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED |\ + UF_SMARTCARD_REQUIRED |\ + UF_TRUSTED_FOR_DELEGATION |\ + UF_NOT_DELEGATED |\ + UF_USE_DES_KEY_ONLY |\ + UF_DONT_REQUIRE_PREAUTH \ + ) + +/* sAMAccountType */ +#define ATYPE_NORMAL_ACCOUNT 0x30000000 /* 805306368 */ +#define ATYPE_WORKSTATION_TRUST 0x30000001 /* 805306369 */ +#define ATYPE_INTERDOMAIN_TRUST 0x30000002 /* 805306370 */ +#define ATYPE_SECURITY_GLOBAL_GROUP 0x10000000 /* 268435456 */ +#define ATYPE_DISTRIBUTION_GLOBAL_GROUP 0x10000001 /* 268435457 */ +#define ATYPE_DISTRIBUTION_UNIVERSAL_GROUP ATYPE_DISTRIBUTION_GLOBAL_GROUP +#define ATYPE_SECURITY_LOCAL_GROUP 0x20000000 /* 536870912 */ +#define ATYPE_DISTRIBUTION_LOCAL_GROUP 0x20000001 /* 536870913 */ + +#define ATYPE_ACCOUNT ATYPE_NORMAL_ACCOUNT /* 0x30000000 805306368 */ +#define ATYPE_GLOBAL_GROUP ATYPE_SECURITY_GLOBAL_GROUP /* 0x10000000 268435456 */ +#define ATYPE_LOCAL_GROUP ATYPE_SECURITY_LOCAL_GROUP /* 0x20000000 536870912 */ + +/* groupType */ +#define GTYPE_SECURITY_BUILTIN_LOCAL_GROUP 0x80000005 /* -2147483643 */ +#define GTYPE_SECURITY_DOMAIN_LOCAL_GROUP 0x80000004 /* -2147483644 */ +#define GTYPE_SECURITY_GLOBAL_GROUP 0x80000002 /* -2147483646 */ +#define GTYPE_DISTRIBUTION_GLOBAL_GROUP 0x00000002 /* 2 */ +#define GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP 0x00000004 /* 4 */ +#define GTYPE_DISTRIBUTION_UNIVERSAL_GROUP 0x00000008 /* 8 */ /* Mailslot or cldap getdcname response flags */ #define ADS_PDC 0x00000001 /* DC is PDC */ @@ -167,3 +252,8 @@ typedef void **ADS_MODLIST; /* DomainCntrollerAddressType */ #define ADS_INET_ADDRESS 0x00000001 #define ADS_NETBIOS_ADDRESS 0x00000002 + + +/* ads auth control flags */ +#define ADS_AUTH_DISABLE_KERBEROS 1 +#define ADS_AUTH_NO_BIND 2 diff --git a/source3/include/asn_1.h b/source3/include/asn_1.h index 090c5459d18..7783ab4c2f6 100644 --- a/source3/include/asn_1.h +++ b/source3/include/asn_1.h @@ -45,6 +45,7 @@ typedef struct { #define ASN1_BOOLEAN 0x1 #define ASN1_INTEGER 0x2 #define ASN1_ENUMERATED 0xa +#define ASN1_SET 0x31 #define ASN1_MAX_OIDS 20 diff --git a/source3/include/client.h b/source3/include/client.h index 711ae1fd196..1e8d1c3d293 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -60,6 +60,7 @@ struct print_job_info typedef struct smb_sign_info { BOOL use_smb_signing; BOOL negotiated_smb_signing; + BOOL temp_smb_signing; size_t mac_key_len; uint8 mac_key[44]; uint32 send_seq_num; diff --git a/source3/include/config.h.in b/source3/include/config.h.in index 4a138b6db6a..770af1a6b56 100644 --- a/source3/include/config.h.in +++ b/source3/include/config.h.in @@ -232,6 +232,7 @@ #undef MMAP_BLACKLIST #undef HAVE_IMMEDIATE_STRUCTURES #undef HAVE_CUPS +#undef WITH_SAM #undef WITH_LDAP_SAM #undef WITH_NISPLUS_SAM #undef WITH_TDB_SAM @@ -252,6 +253,7 @@ #undef HAVE_LDAP #undef HAVE_STAT_ST_BLOCKS #undef STAT_ST_BLOCKSIZE +#undef HAVE_STAT_ST_BLKSIZE #undef HAVE_DEVICE_MAJOR_FN #undef HAVE_DEVICE_MINOR_FN #undef HAVE_PASSWD_PW_COMMENT @@ -286,6 +288,14 @@ #endif #undef LDAP_SET_REBIND_PROC_ARGS +#undef HAVE_SENDFILE +#undef HAVE_SENDFILE64 +#undef LINUX_SENDFILE_API +#undef LINUX_BROKEN_SENDFILE_API +#undef WITH_SENDFILE +#undef FREEBSD_SENDFILE_API +#undef HPUX_SENDFILE_API +#undef WITH_ADS /* The number of bytes in a int. */ #undef SIZEOF_INT @@ -1088,6 +1098,9 @@ /* Define if you have the header file. */ #undef HAVE_SYS_SYSCALL_H +/* Define if you have the header file. */ +#undef HAVE_SYS_SYSLOG_H + /* Define if you have the header file. */ #undef HAVE_SYS_TERMIO_H @@ -1106,6 +1119,9 @@ /* Define if you have the header file. */ #undef HAVE_SYSCALL_H +/* Define if you have the header file. */ +#undef HAVE_SYSLOG_H + /* Define if you have the header file. */ #undef HAVE_TERMIO_H diff --git a/source3/include/debug.h b/source3/include/debug.h index 08858274337..4b0b4b1ac47 100644 --- a/source3/include/debug.h +++ b/source3/include/debug.h @@ -89,9 +89,10 @@ extern int DEBUGLEVEL; #define DBGC_RPC_SRV 6 #define DBGC_RPC_CLI 7 #define DBGC_PASSDB 8 -#define DBGC_AUTH 9 -#define DBGC_WINBIND 10 - +#define DBGC_SAM 9 +#define DBGC_AUTH 10 +#define DBGC_WINBIND 11 +#define DBGC_VFS 12 /* So you can define DBGC_CLASS before including debug.h */ #ifndef DBGC_CLASS diff --git a/source3/include/doserr.h b/source3/include/doserr.h index 135d799596c..93936463e68 100644 --- a/source3/include/doserr.h +++ b/source3/include/doserr.h @@ -148,17 +148,20 @@ /* these are win32 error codes. There are only a few places where these matter for Samba, primarily in the NT printing code */ #define WERR_OK W_ERROR(0) +#define WERR_BADFUNC W_ERROR(1) #define WERR_BADFILE W_ERROR(2) #define WERR_ACCESS_DENIED W_ERROR(5) #define WERR_BADFID W_ERROR(6) -#define WERR_BADFUNC W_ERROR(1) -#define WERR_INSUFFICIENT_BUFFER W_ERROR(122) +#define WERR_NOMEM W_ERROR(8) +#define WERR_GENERAL_FAILURE W_ERROR(31) +#define WERR_NOT_SUPPORTED W_ERROR(50) +#define WERR_PRINTQ_FULL W_ERROR(61) +#define WERR_NO_SPOOL_SPACE W_ERROR(62) #define WERR_NO_SUCH_SHARE W_ERROR(67) #define WERR_ALREADY_EXISTS W_ERROR(80) -#define WERR_INVALID_PARAM W_ERROR(87) -#define WERR_NOT_SUPPORTED W_ERROR(50) #define WERR_BAD_PASSWORD W_ERROR(86) -#define WERR_NOMEM W_ERROR(8) +#define WERR_INVALID_PARAM W_ERROR(87) +#define WERR_INSUFFICIENT_BUFFER W_ERROR(122) #define WERR_INVALID_NAME W_ERROR(123) #define WERR_UNKNOWN_LEVEL W_ERROR(124) #define WERR_OBJECT_PATH_INVALID W_ERROR(161) diff --git a/source3/include/includes.h b/source3/include/includes.h index 6084d583ed6..56b83578312 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -216,7 +216,15 @@ #include #include #include + +#ifdef HAVE_SYSLOG_H #include +#else +#ifdef HAVE_SYS_SYSLOG_H +#include +#endif +#endif + #include #ifdef HAVE_NETINET_TCP_H @@ -406,18 +414,14 @@ #if HAVE_GSSAPI_GSSAPI_H #include -#else -#undef HAVE_KRB5 #endif #if HAVE_GSSAPI_GSSAPI_GENERIC_H #include -#else -#undef HAVE_KRB5 #endif -/* we support ADS if we have krb5 and ldap libs */ -#if defined(HAVE_KRB5) && defined(HAVE_LDAP) && defined(HAVE_GSSAPI) +/* we support ADS if we want it and have krb5 and ldap libs */ +#if defined(WITH_ADS) && defined(HAVE_KRB5) && defined(HAVE_LDAP) #define HAVE_ADS #endif @@ -702,6 +706,7 @@ extern int errno; #include "../tdb/spinlock.h" #include "../tdb/tdbutil.h" #include "talloc.h" +#include "nt_status.h" #include "ads.h" #include "interfaces.h" #include "hash.h" @@ -747,6 +752,8 @@ extern int errno; #include "passdb.h" +#include "sam.h" + #include "session.h" #include "asn_1.h" @@ -755,6 +762,8 @@ extern int errno; #include "mangle.h" +#include "nsswitch/winbind_client.h" + /* * Type for wide character dirent structure. * Only d_name is defined by POSIX. @@ -794,6 +803,11 @@ struct functable { #include "nsswitch/nss.h" +/* forward declaration from printing.h to get around + header file dependencies */ + +struct printjob; + /***** automatically generated prototypes *****/ #include "proto.h" @@ -895,24 +909,6 @@ struct functable { #define ULTRIX_AUTH 1 #endif -#ifdef HAVE_LIBREADLINE -# ifdef HAVE_READLINE_READLINE_H -# include -# ifdef HAVE_READLINE_HISTORY_H -# include -# endif -# else -# ifdef HAVE_READLINE_H -# include -# ifdef HAVE_HISTORY_H -# include -# endif -# else -# undef HAVE_LIBREADLINE -# endif -# endif -#endif - #ifndef HAVE_STRDUP char *strdup(const char *s); #endif diff --git a/source3/include/libsmbclient.h b/source3/include/libsmbclient.h index f2695639969..2b45709a5e8 100644 --- a/source3/include/libsmbclient.h +++ b/source3/include/libsmbclient.h @@ -333,7 +333,7 @@ typedef struct _SMBCCTX { /** Space to store private data of the server cache. */ - void * server_cache; + struct smbc_server_cache * server_cache; /** INTERNAL functions * do _NOT_ touch these from your program ! diff --git a/source3/include/local.h b/source3/include/local.h index 2538715c412..5096e13fc39 100644 --- a/source3/include/local.h +++ b/source3/include/local.h @@ -67,10 +67,6 @@ #define MAX_OPEN_FILES 10000 #endif -/* the max number of simultanous connections to the server by all clients */ -/* zero means no limit. */ -#define MAXSTATUS 0 - #define WORDMAX 0xFFFF /* the maximum password length before we declare a likely attack */ @@ -117,7 +113,7 @@ #endif /* the size of the uid cache used to reduce valid user checks */ -#define UID_CACHE_SIZE 4 +#define VUID_CACHE_SIZE 32 /* the following control timings of various actions. Don't change them unless you know what you are doing. These are all in seconds */ @@ -126,7 +122,6 @@ #define IDLE_CLOSED_TIMEOUT (60) #define DPTR_IDLE_TIMEOUT (120) #define SMBD_SELECT_TIMEOUT (60) -#define SMBD_SELECT_TIMEOUT_WITH_PENDING_LOCKS (10) #define NMBD_SELECT_LOOP (10) #define BROWSE_INTERVAL (60) #define REGISTRATION_INTERVAL (10*60) diff --git a/source3/include/messages.h b/source3/include/messages.h index 58e606b40fa..0e995039ff5 100644 --- a/source3/include/messages.h +++ b/source3/include/messages.h @@ -59,4 +59,12 @@ #define MSG_SMB_SAM_SYNC 3003 #define MSG_SMB_SAM_REPL 3004 +/* Flags to classify messages - used in message_send_all() */ +/* Sender will filter by flag. */ + +#define FLAG_MSG_GENERAL 0x0001 +#define FLAG_MSG_SMBD 0x0002 +#define FLAG_MSG_NMBD 0x0004 +#define FLAG_MSG_PRINTING 0x0008 + #endif diff --git a/source3/include/nt_printing.h b/source3/include/nt_printing.h index 5e2b8f7f64a..57767fc3c6b 100644 --- a/source3/include/nt_printing.h +++ b/source3/include/nt_printing.h @@ -181,6 +181,7 @@ typedef struct nt_printer_driver_info_level #define SPOOL_DSDRIVER_KEY "DsDriver" #define SPOOL_DSUSER_KEY "DsUser" #define SPOOL_PNPDATA_KEY "PnPData" +#define SPOOL_OID_KEY "OID" /* container for a single registry key */ @@ -350,7 +351,7 @@ typedef struct _form #define SPOOLSS_NOTIFY_MSG_UNIX_JOBID 0x0001 /* Job id is unix */ -struct spoolss_notify_msg { +typedef struct spoolss_notify_msg { fstring printer; /* Name of printer notified */ uint32 type; /* Printer or job notify */ uint32 field; /* Notify field changed */ @@ -361,6 +362,18 @@ struct spoolss_notify_msg { uint32 value[2]; char *data; } notify; -}; +} SPOOLSS_NOTIFY_MSG; + +typedef struct { + fstring printername; + uint32 num_msgs; + SPOOLSS_NOTIFY_MSG *msgs; +} SPOOLSS_NOTIFY_MSG_GROUP; + +typedef struct { + TALLOC_CTX *ctx; + uint32 num_groups; + SPOOLSS_NOTIFY_MSG_GROUP *msg_groups; +} SPOOLSS_NOTIFY_MSG_CTR; #endif /* NT_PRINTING_H_ */ diff --git a/source3/include/printing.h b/source3/include/printing.h index ecf603b8fcc..9774a6acd95 100644 --- a/source3/include/printing.h +++ b/source3/include/printing.h @@ -43,6 +43,7 @@ struct printjob { fstring jobname; /* the job name given to us by the client */ fstring user; /* the user who started the job */ fstring queuename; /* service number of printer for this job */ + NT_DEVICEMODE *nt_devmode; }; /* Information for print interfaces */ diff --git a/source3/include/rpc_netlogon.h b/source3/include/rpc_netlogon.h index 80b00fbaad4..fb849f82380 100644 --- a/source3/include/rpc_netlogon.h +++ b/source3/include/rpc_netlogon.h @@ -4,6 +4,7 @@ Copyright (C) Andrew Tridgell 1992-1997 Copyright (C) Luke Kenneth Casson Leighton 1996-1997 Copyright (C) Paul Ashton 1997 + Copyright (C) Jean François Micouleau 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,17 +26,18 @@ /* NETLOGON pipe */ -#define NET_SAMLOGON 0x02 -#define NET_SAMLOGOFF 0x03 -#define NET_REQCHAL 0x04 -#define NET_AUTH 0x05 -#define NET_SRVPWSET 0x06 -#define NET_SAM_DELTAS 0x07 -#define NET_LOGON_CTRL 0x0c -#define NET_AUTH2 0x0f -#define NET_LOGON_CTRL2 0x0e -#define NET_SAM_SYNC 0x10 -#define NET_TRUST_DOM_LIST 0x13 +#define NET_SAMLOGON 0x02 +#define NET_SAMLOGOFF 0x03 +#define NET_REQCHAL 0x04 +#define NET_AUTH 0x05 +#define NET_SRVPWSET 0x06 +#define NET_SAM_DELTAS 0x07 +#define NET_LOGON_CTRL 0x0c +#define NET_AUTH2 0x0f +#define NET_LOGON_CTRL2 0x0e +#define NET_SAM_SYNC 0x10 +#define NET_TRUST_DOM_LIST 0x13 +#define NET_AUTH3 0x1a /* Secure Channel types. used in NetrServerAuthenticate negotiation */ #define SEC_CHAN_WKSTA 2 @@ -43,22 +45,27 @@ #define SEC_CHAN_BDC 6 /* Returned delta types */ -#define SAM_DELTA_DOMAIN_INFO 0x01 /* Domain */ -#define SAM_DELTA_GROUP_INFO 0x02 /* Domain groups */ -#define SAM_DELTA_ACCOUNT_INFO 0x05 /* Users */ -#define SAM_DELTA_GROUP_MEM 0x08 /* Group membership */ -#define SAM_DELTA_ALIAS_INFO 0x09 /* Local groups */ -#define SAM_DELTA_ALIAS_MEM 0x0C /* Local group membership */ -#define SAM_DELTA_DOM_INFO 0x0D /* Privilige stuff */ -#define SAM_DELTA_UNK0E_INFO 0x0e /* Privilige stuff */ -#define SAM_DELTA_PRIVS_INFO 0x10 /* Privilige stuff */ -#define SAM_DELTA_UNK12_INFO 0x12 /* Privilige stuff */ -#define SAM_DELTA_SAM_STAMP 0x16 /* Some kind of journal record? */ +#define SAM_DELTA_DOMAIN_INFO 0x01 +#define SAM_DELTA_GROUP_INFO 0x02 +#define SAM_DELTA_RENAME_GROUP 0x04 +#define SAM_DELTA_ACCOUNT_INFO 0x05 +#define SAM_DELTA_RENAME_USER 0x07 +#define SAM_DELTA_GROUP_MEM 0x08 +#define SAM_DELTA_ALIAS_INFO 0x09 +#define SAM_DELTA_RENAME_ALIAS 0x0b +#define SAM_DELTA_ALIAS_MEM 0x0c +#define SAM_DELTA_POLICY_INFO 0x0d +#define SAM_DELTA_TRUST_DOMS 0x0e +#define SAM_DELTA_PRIVS_INFO 0x10 /* DT_DELTA_ACCOUNTS */ +#define SAM_DELTA_SECRET_INFO 0x12 +#define SAM_DELTA_DELETE_GROUP 0x14 +#define SAM_DELTA_DELETE_USER 0x15 +#define SAM_DELTA_MODIFIED_COUNT 0x16 /* SAM database types */ #define SAM_DATABASE_DOMAIN 0x00 /* Domain users and groups */ #define SAM_DATABASE_BUILTIN 0x01 /* BUILTIN users and groups */ -#define SAM_DATABASE_PRIVS 0x02 /* Priviliges? */ +#define SAM_DATABASE_PRIVS 0x02 /* Privileges */ #if 0 /* I think this is correct - it's what gets parsed on the wire. JRA. */ @@ -157,8 +164,8 @@ typedef struct net_user_info_3 uint32 buffer_dom_id; /* undocumented logon domain id pointer */ uint8 padding[40]; /* unused padding bytes. expansion room */ - uint32 num_other_sids; /* 0 - num_sids */ - uint32 buffer_other_sids; /* NULL - undocumented pointer to SIDs. */ + uint32 num_other_sids; /* number of foreign/trusted domain sids */ + uint32 buffer_other_sids; UNISTR2 uni_user_name; /* username unicode string */ UNISTR2 uni_full_name; /* user's full name unicode string */ @@ -177,7 +184,7 @@ typedef struct net_user_info_3 uint32 num_other_groups; /* other groups */ DOM_GID *other_gids; /* group info */ - DOM_SID2 *other_sids; /* undocumented - domain SIDs */ + DOM_SID2 *other_sids; /* foreign/trusted domain SIDs */ } NET_USER_INFO_3; @@ -370,6 +377,23 @@ typedef struct net_r_auth2_info NTSTATUS status; /* return code */ } NET_R_AUTH_2; +/* NET_Q_AUTH_3 */ +typedef struct net_q_auth3_info +{ + DOM_LOG_INFO clnt_id; /* client identification info */ + DOM_CHAL clnt_chal; /* client-calculated credentials */ + NEG_FLAGS clnt_flgs; /* usually 0x6007 ffff */ +} NET_Q_AUTH_3; + +/* NET_R_AUTH_3 */ +typedef struct net_r_auth3_info +{ + DOM_CHAL srv_chal; /* server-calculated credentials */ + NEG_FLAGS srv_flgs; /* usually 0x6007 ffff */ + uint32 unknown; /* 0x0000045b */ + NTSTATUS status; /* return code */ +} NET_R_AUTH_3; + /* NET_Q_SRV_PWSET */ typedef struct net_q_srv_pwset_info @@ -692,51 +716,37 @@ typedef struct sam_alias_mem_info_info } SAM_ALIAS_MEM_INFO; -/* SAM_DELTA_DOM (0x0D) */ +/* SAM_DELTA_POLICY (0x0D) */ typedef struct { - uint32 unknown1; /* 0x5000 */ - uint32 unknown2; /* 0 */ - uint32 unknown3; /* 0 */ - uint32 unknown4; /* 0 */ - uint32 count1; - uint32 ptr1; - uint16 count2; - uint16 count3; - uint32 ptr2; - uint32 ptr3; - - uint32 unknown4b; /* 0x02000000 */ - uint32 unknown5; /* 0x00100000 */ - uint32 unknown6; /* 0x00010000 */ - uint32 unknown7; /* 0x0f000000 */ - uint32 unknown8; /* 0 */ - uint32 unknown9; /* 0 */ - uint32 unknown10; /* 0 */ - uint32 unknown11; /* 0x3c*/ - uint32 unknown12; /* 0*/ - - uint32 unknown13; /* a7080110 */ - uint32 unknown14; /* 01bfb0dd */ - uint32 unknown15; /* 0f */ - uint32 unknown16; /* 68 */ - uint32 unknown17; /* 00169000 */ - - uint32 count4; - uint32 unknown18; /* 0 times count4 */ - - uint32 unknown19; /* 8 */ - - uint32 unknown20; /* 0x04 times count1 */ - - uint32 ptr4; - - UNISTR2 domain_name; + uint32 max_log_size; /* 0x5000 */ + UINT64_S audit_retention_period; /* 0 */ + uint32 auditing_mode; /* 0 */ + uint32 num_events; + uint32 ptr_events; + UNIHDR hdr_dom_name; + uint32 sid_ptr; + + uint32 paged_pool_limit; /* 0x02000000 */ + uint32 non_paged_pool_limit; /* 0x00100000 */ + uint32 min_workset_size; /* 0x00010000 */ + uint32 max_workset_size; /* 0x0f000000 */ + uint32 page_file_limit; /* 0 */ + UINT64_S time_limit; /* 0 */ + NTTIME modify_time; /* 0x3c*/ + NTTIME create_time; /* a7080110 */ + BUFHDR2 hdr_sec_desc; + + uint32 num_event_audit_options; + uint32 event_audit_option; + + UNISTR2 domain_name; DOM_SID2 domain_sid; -} SAM_DELTA_DOM; + BUFFER4 buf_sec_desc; +} SAM_DELTA_POLICY; -/* SAM_DELTA_UNK0E (0x0e) */ +/* SAM_DELTA_TRUST_DOMS */ typedef struct { uint32 buf_size; @@ -754,34 +764,29 @@ typedef struct uint32 unknown3; UNISTR2 domain; -} SAM_DELTA_UNK0E; +} SAM_DELTA_TRUSTDOMS; /* SAM_DELTA_PRIVS (0x10) */ typedef struct { - uint32 buf_size; - SEC_DESC *sec_desc; DOM_SID2 sid; uint32 priv_count; - uint32 reserved1; /* 0x0 */ - - uint32 ptr1; - uint32 ptr2; - - uint32 unknown1; - uint32 unknown2; - uint32 unknown3; - uint32 unknown4; - uint32 unknown5; - uint32 unknown6; - uint32 unknown7; - uint32 unknown8; - uint32 unknown9; + uint32 priv_control; + + uint32 priv_attr_ptr; + uint32 priv_name_ptr; + + uint32 paged_pool_limit; /* 0x02000000 */ + uint32 non_paged_pool_limit; /* 0x00100000 */ + uint32 min_workset_size; /* 0x00010000 */ + uint32 max_workset_size; /* 0x0f000000 */ + uint32 page_file_limit; /* 0 */ + UINT64_S time_limit; /* 0 */ + uint32 system_flags; /* 1 */ + BUFHDR2 hdr_sec_desc; uint32 buf_size2; - uint32 ptr3; - uint32 unknown10; /* 48 bytes 0x0*/ uint32 attribute_count; uint32 *attributes; @@ -790,10 +795,10 @@ typedef struct UNIHDR *hdr_privslist; UNISTR2 *uni_privslist; - + BUFFER4 buf_sec_desc; } SAM_DELTA_PRIVS; -/* SAM_DELTA_UNK12 (0x12) */ +/* SAM_DELTA_SECRET */ typedef struct { uint32 buf_size; @@ -827,15 +832,15 @@ typedef struct uint32 buf_size3; SEC_DESC *sec_desc2; -} SAM_DELTA_UNK12; +} SAM_DELTA_SECRET; -/* SAM_DELTA_STAMP (0x16) */ +/* SAM_DELTA_MOD_COUNT (0x16) */ typedef struct { uint32 seqnum; uint32 dom_mod_count_ptr; UINT64_S dom_mod_count; /* domain mod count at last sync */ -} SAM_DELTA_STAMP; +} SAM_DELTA_MOD_COUNT; typedef union sam_delta_ctr_info { @@ -845,11 +850,11 @@ typedef union sam_delta_ctr_info SAM_GROUP_MEM_INFO grp_mem_info; SAM_ALIAS_INFO alias_info ; SAM_ALIAS_MEM_INFO als_mem_info; - SAM_DELTA_DOM dom_info; + SAM_DELTA_POLICY policy_info; SAM_DELTA_PRIVS privs_info; - SAM_DELTA_STAMP stamp; - SAM_DELTA_UNK0E unk0e_info; - SAM_DELTA_UNK12 unk12_info; + SAM_DELTA_MOD_COUNT mod_count; + SAM_DELTA_TRUSTDOMS trustdoms_info; + SAM_DELTA_SECRET secret_info; } SAM_DELTA_CTR; /* NET_R_SAM_SYNC */ diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index b7acf44c5de..456825a5f5c 100755 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -1240,8 +1240,8 @@ typedef struct job_info_ctr_info { union { - JOB_INFO_1 **job_info_1; - JOB_INFO_2 **job_info_2; + JOB_INFO_1 *job_info_1; + JOB_INFO_2 *job_info_2; void *info; } job; diff --git a/source3/include/smb.h b/source3/include/smb.h index 263dd67c548..c39ebed950f 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -3,7 +3,7 @@ SMB parameters and setup, plus a whole lot more. Copyright (C) Andrew Tridgell 1992-2000 - Copyright (C) John H Terpstra 1996-2000 + Copyright (C) John H Terpstra 1996-2002 Copyright (C) Luke Kenneth Casson Leighton 1996-2000 Copyright (C) Paul Ashton 1998-2000 Copyright (C) Simo Sorce 2001-2002 @@ -193,44 +193,6 @@ typedef struct nttime_info } NTTIME; -/* The Splint code analysis tool doesn't like immediate structures. */ - -#ifdef _SPLINT_ /* http://www.splint.org */ -#undef HAVE_IMMEDIATE_STRUCTURES -#endif - -/* the following rather strange looking definitions of NTSTATUS and WERROR - and there in order to catch common coding errors where different error types - are mixed up. This is especially important as we slowly convert Samba - from using BOOL for internal functions -*/ - -#if defined(HAVE_IMMEDIATE_STRUCTURES) -typedef struct {uint32 v;} NTSTATUS; -#define NT_STATUS(x) ((NTSTATUS) { x }) -#define NT_STATUS_V(x) ((x).v) -#else -typedef uint32 NTSTATUS; -#define NT_STATUS(x) (x) -#define NT_STATUS_V(x) (x) -#endif - -#if defined(HAVE_IMMEDIATE_STRUCTURES) -typedef struct {uint32 v;} WERROR; -#define W_ERROR(x) ((WERROR) { x }) -#define W_ERROR_V(x) ((x).v) -#else -typedef uint32 WERROR; -#define W_ERROR(x) (x) -#define W_ERROR_V(x) (x) -#endif - -#define NT_STATUS_IS_OK(x) (NT_STATUS_V(x) == 0) -#define NT_STATUS_IS_ERR(x) ((NT_STATUS_V(x) & 0xc0000000) == 0xc0000000) -#define NT_STATUS_EQUAL(x,y) (NT_STATUS_V(x) == NT_STATUS_V(y)) -#define W_ERROR_IS_OK(x) (W_ERROR_V(x) == 0) - - /* Allowable account control bits */ #define ACB_DISABLED 0x0001 /* 1 = User account disabled */ #define ACB_HOMDIRREQ 0x0002 /* 1 = Home directory required */ @@ -391,6 +353,7 @@ typedef struct files_struct BOOL delete_on_close; SMB_OFF_T pos; SMB_OFF_T size; + SMB_OFF_T initial_allocation_size; /* Faked up initial allocation on disk. */ mode_t mode; uint16 vuid; write_bmpx_struct *wbmpx_ptr; @@ -430,9 +393,9 @@ typedef struct time_t status_time; } dir_status_struct; -struct uid_cache { - int entries; - uid_t list[UID_CACHE_SIZE]; +struct vuid_cache { + unsigned int entries; + uint16 list[VUID_CACHE_SIZE]; }; typedef struct @@ -461,7 +424,8 @@ typedef struct connection_struct unsigned cnum; /* an index passed over the wire */ int service; BOOL force_user; - struct uid_cache uid_cache; + BOOL force_group; + struct vuid_cache vuid_cache; void *dirptr; BOOL printer; BOOL ipc; @@ -652,7 +616,7 @@ typedef struct sam_passwd DATA_BLOB lm_pw; /* .data is Null if no password */ DATA_BLOB nt_pw; /* .data is Null if no password */ - DATA_BLOB plaintext_pw; /* .data is Null if not available */ + char* plaintext_pw; /* is Null if not available */ uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */ uint32 unknown_3; /* 0x00ff ffff */ @@ -716,6 +680,7 @@ struct connections_data { char addr[24]; char machine[FSTRING_LEN]; time_t start; + uint32 bcast_msg_flags; }; @@ -788,12 +753,16 @@ struct bitmap { int n; }; -#define FLAG_BASIC 0x01 /* fundamental options */ -#define FLAG_SHARE 0x02 /* file sharing options */ -#define FLAG_PRINT 0x04 /* printing options */ -#define FLAG_GLOBAL 0x08 /* local options that should be globally settable in SWAT */ -#define FLAG_DEPRECATED 0x10 /* options that should no longer be used */ -#define FLAG_HIDE 0x20 /* options that should be hidden in SWAT */ +#define FLAG_BASIC 0x0001 /* fundamental options */ +#define FLAG_SHARE 0x0002 /* file sharing options */ +#define FLAG_PRINT 0x0004 /* printing options */ +#define FLAG_GLOBAL 0x0008 /* local options that should be globally settable in SWAT */ +#define FLAG_WIZARD 0x0010 /* Parameters that the wizard will operate on */ +#define FLAG_ADVANCED 0x0020 /* Parameters that the wizard will operate on */ +#define FLAG_DEVELOPER 0x0040 /* Parameters that the wizard will operate on */ +#define FLAG_DEPRECATED 0x1000 /* options that should no longer be used */ +#define FLAG_HIDE 0x2000 /* options that should be hidden in SWAT */ +#define FLAG_DOS_STRING 0x4000 /* convert from UNIX to DOS codepage when reading this string. */ #ifndef LOCKING_VERSION #define LOCKING_VERSION 4 @@ -1147,17 +1116,17 @@ struct bitmap { #define FILE_SHARE_DELETE 4 /* FileAttributesField */ -#define FILE_ATTRIBUTE_READONLY aRONLY -#define FILE_ATTRIBUTE_HIDDEN aHIDDEN -#define FILE_ATTRIBUTE_SYSTEM aSYSTEM -#define FILE_ATTRIBUTE_DIRECTORY aDIR -#define FILE_ATTRIBUTE_ARCHIVE aARCH -#define FILE_ATTRIBUTE_NORMAL 0x80L -#define FILE_ATTRIBUTE_TEMPORARY 0x100L -#define FILE_ATTRIBUTE_SPARSE 0x200L -#define FILE_ATTRIBUTE_COMPRESSED 0x800L -#define FILE_ATTRIBUTE_NONINDEXED 0x2000L -#define SAMBA_ATTRIBUTES_MASK 0x7F +#define FILE_ATTRIBUTE_READONLY 0x001L +#define FILE_ATTRIBUTE_HIDDEN 0x002L +#define FILE_ATTRIBUTE_SYSTEM 0x004L +#define FILE_ATTRIBUTE_DIRECTORY 0x010L +#define FILE_ATTRIBUTE_ARCHIVE 0x020L +#define FILE_ATTRIBUTE_NORMAL 0x080L +#define FILE_ATTRIBUTE_TEMPORARY 0x100L +#define FILE_ATTRIBUTE_SPARSE 0x200L +#define FILE_ATTRIBUTE_COMPRESSED 0x800L +#define FILE_ATTRIBUTE_NONINDEXED 0x2000L +#define SAMBA_ATTRIBUTES_MASK 0x7F /* Flags - combined with attributes. */ #define FILE_FLAG_WRITE_THROUGH 0x80000000L @@ -1185,8 +1154,10 @@ struct bitmap { #define FILE_EIGHT_DOT_THREE_ONLY 0x0400 #define FILE_RANDOM_ACCESS 0x0800 #define FILE_DELETE_ON_CLOSE 0x1000 +#define FILE_OPEN_BY_FILE_ID 0x2000 /* Responses when opening a file. */ +#define FILE_WAS_SUPERSEDED 0 #define FILE_WAS_OPENED 1 #define FILE_WAS_CREATED 2 #define FILE_WAS_OVERWRITTEN 3 @@ -1299,7 +1270,7 @@ char *strdup(char *s); */ #define DEFAULT_MAJOR_VERSION 0x04 -#define DEFAULT_MINOR_VERSION 0x05 +#define DEFAULT_MINOR_VERSION 0x09 /* Browser Election Values */ #define BROWSER_ELECTION_VERSION 0x010f @@ -1375,6 +1346,9 @@ enum schema_types {SCHEMA_COMPAT, SCHEMA_AD, SCHEMA_SAMBA}; /* LDAP SSL options */ enum ldap_ssl_types {LDAP_SSL_ON, LDAP_SSL_OFF, LDAP_SSL_START_TLS}; +/* LDAP PASSWD SYNC methods */ +enum ldap_passwd_sync_types {LDAP_PASSWD_SYNC_ON, LDAP_PASSWD_SYNC_OFF, LDAP_PASSWD_SYNC_ONLY}; + /* Remote architectures we know about. */ enum remote_arch_types {RA_UNKNOWN, RA_WFWG, RA_OS2, RA_WIN95, RA_WINNT, RA_WIN2K, RA_SAMBA}; @@ -1656,8 +1630,6 @@ struct unix_error_map { #define SAFE_NETBIOS_CHARS ". -_" -#include "nsswitch/winbindd_nss.h" - /* generic iconv conversion structure */ typedef struct { size_t (*direct)(void *cd, char **inbuf, size_t *inbytesleft, diff --git a/source3/include/smb_acls.h b/source3/include/smb_acls.h index 3ed670d38ba..e7edb62bde2 100644 --- a/source3/include/smb_acls.h +++ b/source3/include/smb_acls.h @@ -20,9 +20,6 @@ #ifndef _SMB_ACLS_H #define _SMB_ACLS_H - -#include "includes.h" - #if defined(HAVE_POSIX_ACLS) /* This is an identity mapping (just remove the SMB_). */ diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h index a2351c705ea..71d4bac7952 100644 --- a/source3/include/smb_macros.h +++ b/source3/include/smb_macros.h @@ -80,17 +80,20 @@ #define FNUM_OK(fsp,c) (OPEN_FSP(fsp) && (c)==(fsp)->conn) #define CHECK_FSP(fsp,conn) if (!FNUM_OK(fsp,conn)) \ - return(ERROR_DOS(ERRDOS,ERRbadfid)); \ - else if((fsp)->fd == -1) \ - return(ERROR_DOS(ERRDOS,ERRbadaccess)) + return(ERROR_DOS(ERRDOS,ERRbadfid)); \ + else if((fsp)->fd == -1) \ + return(ERROR_DOS(ERRDOS,ERRbadaccess)) #define CHECK_READ(fsp) if (!(fsp)->can_read) \ - return(ERROR_DOS(ERRDOS,ERRbadaccess)) + return(ERROR_DOS(ERRDOS,ERRbadaccess)) #define CHECK_WRITE(fsp) if (!(fsp)->can_write) \ - return(ERROR_DOS(ERRDOS,ERRbadaccess)) + return(ERROR_DOS(ERRDOS,ERRbadaccess)) #define CHECK_ERROR(fsp) if (HAS_CACHED_ERROR(fsp)) \ - return(CACHED_ERROR(fsp)) + return(CACHED_ERROR(fsp)) + +#define ERROR_WAS_LOCK_DENIED(status) (NT_STATUS_EQUAL((status), NT_STATUS_LOCK_NOT_GRANTED) || \ + NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT) ) /* translates a connection number into a service number */ #define SNUM(conn) ((conn)?(conn)->service:-1) @@ -165,8 +168,7 @@ /* this is how errors are generated */ #define UNIXERROR(defclass,deferror) unix_error_packet(outbuf,defclass,deferror,__LINE__,__FILE__) -#define SMB_ROUNDUP(x,g) (((x)+((g)-1))&~((g)-1)) -#define SMB_ROUNDUP_ALLOCATION(s) ((s) ? (SMB_ROUNDUP((SMB_OFF_T)((s)+1), ((SMB_OFF_T)SMB_ROUNDUP_ALLOCATION_SIZE))) : 0 ) +#define SMB_ROUNDUP(x,r) ( ((x)%(r)) ? ( (((x)+(r))/(r))*(r) ) : (x)) /* Extra macros added by Ying Chen at IBM - speed increase by inlining. */ #define smb_buf(buf) (((char *)(buf)) + smb_size + CVAL(buf,smb_wct)*2) diff --git a/source3/include/smbprofile.h b/source3/include/smbprofile.h index 82017cee854..e501de8c0e2 100644 --- a/source3/include/smbprofile.h +++ b/source3/include/smbprofile.h @@ -34,7 +34,7 @@ enum flush_reason_enum { SEEK_FLUSH, READ_FLUSH, WRITE_FLUSH, READRAW_FLUSH, #define PROF_SHMEM_KEY ((key_t)0x07021999) #define PROF_SHM_MAGIC 0x6349985 -#define PROF_SHM_VERSION 6 +#define PROF_SHM_VERSION 7 /* time values in the following structure are in microseconds */ @@ -65,6 +65,9 @@ struct profile_stats { unsigned syscall_write_bytes; /* bytes written with write syscall */ unsigned syscall_lseek_count; unsigned syscall_lseek_time; + unsigned syscall_sendfile_count; + unsigned syscall_sendfile_time; + unsigned syscall_sendfile_bytes; /* bytes read with sendfile syscall */ unsigned syscall_rename_count; unsigned syscall_rename_time; unsigned syscall_fsync_count; diff --git a/source3/include/trans2.h b/source3/include/trans2.h index fb265fdb1a8..3468d3b9950 100644 --- a/source3/include/trans2.h +++ b/source3/include/trans2.h @@ -193,16 +193,19 @@ Byte offset Type name description } FSINFO; *************************************************************/ -#define SMB_INFO_STANDARD 1 -#define SMB_INFO_QUERY_EA_SIZE 2 -#define SMB_INFO_QUERY_EAS_FROM_LIST 3 -#define SMB_INFO_QUERY_ALL_EAS 4 +#define SMB_INFO_STANDARD 1 /* FILESTATUS3 struct */ +#define SMB_INFO_SET_EA 2 /* EAOP2 struct, only valid on set not query */ +#define SMB_INFO_QUERY_EA_SIZE 2 /* FILESTATUS4 struct, only valid on query not set */ +#define SMB_INFO_QUERY_EAS_FROM_LIST 3 /* only valid on query not set */ +#define SMB_INFO_QUERY_ALL_EAS 4 /* only valid on query not set */ #define SMB_INFO_IS_NAME_VALID 6 -#define SMB_QUERY_FS_LABEL_INFO 0x101 -#define SMB_QUERY_FS_VOLUME_INFO 0x102 -#define SMB_QUERY_FS_SIZE_INFO 0x103 -#define SMB_QUERY_FS_DEVICE_INFO 0x104 -#define SMB_QUERY_FS_ATTRIBUTE_INFO 0x105 +#define SMB_INFO_STANDARD_LONG 11 /* similar to level 1, ie struct FileStatus3 */ +#define SMB_QUERY_EA_SIZE_LONG 12 /* similar to level 2, ie struct FileStatus4 */ +#define SMB_QUERY_FS_LABEL_INFO 0x101 +#define SMB_QUERY_FS_VOLUME_INFO 0x102 +#define SMB_QUERY_FS_SIZE_INFO 0x103 +#define SMB_QUERY_FS_DEVICE_INFO 0x104 +#define SMB_QUERY_FS_ATTRIBUTE_INFO 0x105 #define l2_vol_fdateCreation 0 diff --git a/source3/include/version.h b/source3/include/version.h index 74df1c99141..87e3673a7f6 100644 --- a/source3/include/version.h +++ b/source3/include/version.h @@ -1 +1 @@ -#define VERSION "3.0-alpha18" +#define VERSION "3.0-alpha19" diff --git a/source3/include/vfs.h b/source3/include/vfs.h index 1b1a13d7c12..9a067643713 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -44,17 +44,18 @@ /* Changed to version 2 for CIFS UNIX extensions (mknod and link added). JRA. */ /* Changed to version 3 for POSIX acl extensions. JRA. */ /* Changed to version 4 for cascaded VFS interface. Alexander Bokovoy. */ +/* Changed to version 5 for sendfile addition. JRA. */ #define SMB_VFS_INTERFACE_VERSION 5 /* Version of supported cascaded interface backward copmatibility. - (version 4 corresponds to SMB_VFS_INTERFACE_VERSION 4) + (version 5 corresponds to SMB_VFS_INTERFACE_VERSION 5) It is used in vfs_init_custom() to detect VFS modules which conform to cascaded VFS interface but implement elder version than current version of Samba uses. This allows to use old modules with new VFS interface as far as combined VFS operation set is coherent (will be in most cases). */ -#define SMB_VFS_INTERFACE_CASCADED 4 +#define SMB_VFS_INTERFACE_CASCADED 5 /* Each VFS module must provide following global functions: @@ -116,6 +117,7 @@ struct vfs_ops { ssize_t (*read)(struct files_struct *fsp, int fd, void *data, size_t n); ssize_t (*write)(struct files_struct *fsp, int fd, const void *data, size_t n); SMB_OFF_T (*lseek)(struct files_struct *fsp, int filedes, SMB_OFF_T offset, int whence); + ssize_t (*sendfile)(int tofd, files_struct *fsp, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count); int (*rename)(struct connection_struct *conn, const char *old, const char *new); int (*fsync)(struct files_struct *fsp, int fd); int (*stat)(struct connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf); @@ -210,6 +212,7 @@ typedef enum _vfs_op_type { SMB_VFS_OP_READ, SMB_VFS_OP_WRITE, SMB_VFS_OP_LSEEK, + SMB_VFS_OP_SENDFILE, SMB_VFS_OP_RENAME, SMB_VFS_OP_FSYNC, SMB_VFS_OP_STAT, diff --git a/source3/lib/account_pol.c b/source3/lib/account_pol.c index 07b5e2ecfc6..b5f205c5086 100644 --- a/source3/lib/account_pol.c +++ b/source3/lib/account_pol.c @@ -128,7 +128,7 @@ BOOL account_policy_get(int field, uint32 *value) return False; } if (!tdb_fetch_uint32(tdb, name, value)) { - DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for feild %d (%s), returning 0", field, name)); + DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for efild %d (%s), returning 0", field, name)); return False; } DEBUG(10,("account_policy_get: %s:%d\n", name, *value)); @@ -151,7 +151,7 @@ BOOL account_policy_set(int field, uint32 value) } if (!tdb_store_uint32(tdb, name, value)) { - DEBUG(1, ("tdb_store_uint32 failed for feild %d (%s) on value %u", field, name, value)); + DEBUG(1, ("tdb_store_uint32 failed for field %d (%s) on value %u", field, name, value)); return False; } diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index 6e961366435..cd8aa4fe55f 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -432,13 +432,14 @@ int push_ucs2(const void *base_ptr, void *dest, const char *src, int dest_len, i * @param dest always set at least to NULL * * @retval The number of bytes occupied by the string in the destination + * or -1 in case of error. **/ -int push_ucs2_talloc(TALLOC_CTX *ctx, void **dest, const char *src) +int push_ucs2_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src) { int src_len = strlen(src)+1; *dest = NULL; - return convert_string_talloc(ctx, CH_UNIX, CH_UCS2, src, src_len, dest); + return convert_string_talloc(ctx, CH_UNIX, CH_UCS2, src, src_len, (void **)dest); } /** @@ -447,13 +448,14 @@ int push_ucs2_talloc(TALLOC_CTX *ctx, void **dest, const char *src) * @param dest always set at least to NULL * * @retval The number of bytes occupied by the string in the destination + * or -1 in case of error. **/ -int push_ucs2_allocate(void **dest, const char *src) +int push_ucs2_allocate(smb_ucs2_t **dest, const char *src) { int src_len = strlen(src)+1; *dest = NULL; - return convert_string_allocate(CH_UNIX, CH_UCS2, src, src_len, dest); + return convert_string_allocate(CH_UNIX, CH_UCS2, src, src_len, (void **)dest); } /**************************************************************************** diff --git a/source3/lib/debug.c b/source3/lib/debug.c index 842d2dac1d6..f4f3ee2f9f9 100644 --- a/source3/lib/debug.c +++ b/source3/lib/debug.c @@ -153,8 +153,10 @@ static const char *default_classname_table[] = { "rpc_srv", /* DBGC_RPC_SRV */ "rpc_cli", /* DBGC_RPC_CLI */ "passdb", /* DBGC_PASSDB */ + "sam", /* DBGC_SAM */ "auth", /* DBGC_AUTH */ "winbind", /* DBGC_WINBIND */ + "vfs", /* DBGC_VFS */ NULL }; @@ -350,7 +352,7 @@ int debug_lookup_classname(const char *classname) /**************************************************************************** -dump the current registered denug levels +dump the current registered debug levels ****************************************************************************/ static void debug_dump_status(int level) { @@ -371,8 +373,7 @@ static void debug_dump_status(int level) parse the debug levels from smbcontrol. Example debug level parameter: printdrivers:7 ****************************************************************************/ -BOOL debug_parse_params(char **params, int *debuglevel_class, - BOOL *debuglevel_class_isset) +static BOOL debug_parse_params(char **params) { int i, ndx; char *class_name; @@ -385,8 +386,8 @@ BOOL debug_parse_params(char **params, int *debuglevel_class, * v.s. "all:10", this is the traditional way to set DEBUGLEVEL */ if (isdigit((int)params[0][0])) { - debuglevel_class[DBGC_ALL] = atoi(params[0]); - debuglevel_class_isset[DBGC_ALL] = True; + DEBUGLEVEL_CLASS[DBGC_ALL] = atoi(params[0]); + DEBUGLEVEL_CLASS_ISSET[DBGC_ALL] = True; i = 1; /* start processing at the next params */ } else @@ -397,8 +398,8 @@ BOOL debug_parse_params(char **params, int *debuglevel_class, if ((class_name=strtok(params[i],":")) && (class_level=strtok(NULL, "\0")) && ((ndx = debug_lookup_classname(class_name)) != -1)) { - debuglevel_class[ndx] = atoi(class_level); - debuglevel_class_isset[ndx] = True; + DEBUGLEVEL_CLASS[ndx] = atoi(class_level); + DEBUGLEVEL_CLASS_ISSET[ndx] = True; } else { DEBUG(0,("debug_parse_params: unrecognized debug class name or format [%s]\n", params[i])); return False; @@ -425,8 +426,7 @@ BOOL debug_parse_levels(const char *params_str) params = str_list_make(params_str, NULL); - if (debug_parse_params(params, DEBUGLEVEL_CLASS, - DEBUGLEVEL_CLASS_ISSET)) + if (debug_parse_params(params)) { debug_dump_status(5); str_list_free(¶ms); diff --git a/source3/lib/error.c b/source3/lib/error.c index 608d2b89bad..af8cf960e8f 100644 --- a/source3/lib/error.c +++ b/source3/lib/error.c @@ -45,6 +45,9 @@ const struct unix_error_map unix_dos_nt_errmap[] = { #endif #ifdef EROFS { EROFS, ERRHRD, ERRnowrite, NT_STATUS_ACCESS_DENIED }, +#endif +#ifdef ENAMETOOLONG + { ENAMETOOLONG, ERRDOS, 206, NT_STATUS_OBJECT_NAME_INVALID }, #endif { 0, 0, 0, NT_STATUS_OK } }; diff --git a/source3/lib/messages.c b/source3/lib/messages.c index e6d2de4a58b..d9886a54daf 100644 --- a/source3/lib/messages.c +++ b/source3/lib/messages.c @@ -382,10 +382,11 @@ void message_deregister(int msg_type) struct msg_all { int msg_type; + uint32 msg_flag; const void *buf; size_t len; BOOL duplicates; - int n_sent; + int n_sent; }; /**************************************************************************** @@ -405,13 +406,20 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void if (crec.cnum != -1) return 0; - /* if the msg send fails because the pid was not found (i.e. smbd died), + /* Don't send if the receiver hasn't registered an interest. */ + + if(!(crec.bcast_msg_flags & msg_all->msg_flag)) + return 0; + + /* If the msg send fails because the pid was not found (i.e. smbd died), * the msg has already been deleted from the messages.tdb.*/ + if (!message_send_pid(crec.pid, msg_all->msg_type, msg_all->buf, msg_all->len, msg_all->duplicates)) { - /* if the pid was not found delete the entry from connections.tdb */ + /* If the pid was not found delete the entry from connections.tdb */ + if (errno == ESRCH) { DEBUG(2,("pid %u doesn't exist - deleting connections %d [%s]\n", (unsigned int)crec.pid, crec.cnum, crec.name)); @@ -442,6 +450,17 @@ BOOL message_send_all(TDB_CONTEXT *conn_tdb, int msg_type, struct msg_all msg_all; msg_all.msg_type = msg_type; + if (msg_type < 1000) + msg_all.msg_flag = FLAG_MSG_GENERAL; + else if (msg_type > 1000 && msg_type < 2000) + msg_all.msg_flag = FLAG_MSG_NMBD; + else if (msg_type > 2000 && msg_type < 3000) + msg_all.msg_flag = FLAG_MSG_PRINTING; + else if (msg_type > 3000 && msg_type < 4000) + msg_all.msg_flag = FLAG_MSG_SMBD; + else + return False; + msg_all.buf = buf; msg_all.len = len; msg_all.duplicates = duplicates_allowed; @@ -452,73 +471,4 @@ BOOL message_send_all(TDB_CONTEXT *conn_tdb, int msg_type, *n_sent = msg_all.n_sent; return True; } - -static SIG_ATOMIC_T gotalarm; - -/*************************************************************** - Signal function to tell us we timed out. -****************************************************************/ - -static void gotalarm_sig(void) -{ - gotalarm = 1; -} - -/** - * Lock the messaging tdb based on a string - this is used as a primitive - * form of mutex between smbd instances. - * - * @param name A string identifying the name of the mutex. - */ - -BOOL message_named_mutex(char *name, unsigned int timeout) -{ - TDB_DATA key; - int ret; - void (*oldsig_handler)(int) = NULL; - - if (!message_init()) - return False; - - key.dptr = name; - key.dsize = strlen(name)+1; - - if (timeout) { - gotalarm = 0; - oldsig_handler = CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); - alarm(timeout); - } - - ret = tdb_chainlock(tdb, key); - - if (timeout) { - alarm(0); - CatchSignal(SIGALRM, SIGNAL_CAST oldsig_handler); - if (gotalarm) - return False; - } - - if (ret == 0) - DEBUG(10,("message_named_mutex: got mutex for %s\n", name )); - - return (ret == 0); -} - -/** - * Unlock a named mutex. - * - * @param name A string identifying the name of the mutex. - */ - -void message_named_mutex_release(char *name) -{ - TDB_DATA key; - - key.dptr = name; - key.dsize = strlen(name)+1; - - tdb_chainunlock(tdb, key); - DEBUG(10,("message_named_mutex: released mutex for %s\n", name )); -} - /** @} **/ diff --git a/source3/lib/popt_common.c b/source3/lib/popt_common.c index a3d6af4fbc1..bbc17cb704d 100644 --- a/source3/lib/popt_common.c +++ b/source3/lib/popt_common.c @@ -33,7 +33,7 @@ static void debug_callback(poptContext con, switch(opt->val) { case 'd': if (arg) { - DEBUGLEVEL = atoi(arg); + debug_parse_levels(arg); AllowDebugChange = False; } @@ -43,7 +43,7 @@ static void debug_callback(poptContext con, struct poptOption popt_common_debug[] = { { NULL, 0, POPT_ARG_CALLBACK, debug_callback }, - { "debuglevel", 'd', POPT_ARG_INT, NULL, 'd', "Set debug level", + { "debuglevel", 'd', POPT_ARG_STRING, NULL, 'd', "Set debug level", "DEBUGLEVEL" }, { 0 } }; diff --git a/source3/lib/readline.c b/source3/lib/readline.c index d80c571dd3b..58c4ecf482d 100644 --- a/source3/lib/readline.c +++ b/source3/lib/readline.c @@ -21,6 +21,24 @@ #include "includes.h" +#ifdef HAVE_LIBREADLINE +# ifdef HAVE_READLINE_READLINE_H +# include +# ifdef HAVE_READLINE_HISTORY_H +# include +# endif +# else +# ifdef HAVE_READLINE_H +# include +# ifdef HAVE_HISTORY_H +# include +# endif +# else +# undef HAVE_LIBREADLINE +# endif +# endif +#endif + #ifdef HAVE_NEW_LIBREADLINE # define RL_COMPLETION_CAST (rl_completion_func_t *) #else diff --git a/source3/lib/server_mutex.c b/source3/lib/server_mutex.c index 416d77564d7..3e5512c7342 100644 --- a/source3/lib/server_mutex.c +++ b/source3/lib/server_mutex.c @@ -38,7 +38,7 @@ BOOL grab_server_mutex(const char *name) DEBUG(0,("grab_server_mutex: malloc failed for %s\n", name)); return False; } - if (!message_named_mutex(mutex_server_name, 20)) { + if (!secrets_named_mutex(mutex_server_name, 10)) { DEBUG(10,("grab_server_mutex: failed for %s\n", name)); SAFE_FREE(mutex_server_name); return False; @@ -50,8 +50,7 @@ BOOL grab_server_mutex(const char *name) void release_server_mutex(void) { if (mutex_server_name) { - message_named_mutex_release(mutex_server_name); + secrets_named_mutex_release(mutex_server_name); SAFE_FREE(mutex_server_name); } } - diff --git a/source3/lib/substitute.c b/source3/lib/substitute.c index 026df0f67f1..2550d00d14c 100644 --- a/source3/lib/substitute.c +++ b/source3/lib/substitute.c @@ -297,8 +297,13 @@ void standard_sub_basic(const char *smb_name, char *str,size_t len) case 'L' : if (local_machine_name && *local_machine_name) string_sub(p,"%L", local_machine_name,l); - else - string_sub(p,"%L", global_myname,l); + else { + pstring temp_name; + + pstrcpy(temp_name, global_myname); + strlower(temp_name); + string_sub(p,"%L", temp_name,l); + } break; case 'M' : string_sub(p,"%M", client_name(),l); @@ -675,6 +680,19 @@ void standard_sub_conn(connection_struct *conn, char *str, size_t len) conn->gid, current_user_info.smb_name, str, len); } +char *talloc_sub_conn(TALLOC_CTX *mem_ctx, connection_struct *conn, char *str) +{ + return talloc_sub_advanced(mem_ctx, SNUM(conn), conn->user, + conn->connectpath, conn->gid, + current_user_info.smb_name, str); +} + +char *alloc_sub_conn(connection_struct *conn, char *str) +{ + return alloc_sub_advanced(SNUM(conn), conn->user, conn->connectpath, + conn->gid, current_user_info.smb_name, str); +} + /**************************************************************************** Like standard_sub but by snum. ****************************************************************************/ diff --git a/source3/lib/system.c b/source3/lib/system.c index edda54a78d2..873b8737d50 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -1233,26 +1233,23 @@ int sys_dup2(int oldfd, int newfd) Wrapper for Admin Logs. ****************************************************************************/ -void sys_adminlog(int priority, const char *format_str, ...) +void sys_adminlog(int priority, char *format_str, ...) { va_list ap; int ret; - char **msgbuf = NULL; - - if (!lp_admin_log()) - return; + char *msgbuf = NULL; va_start( ap, format_str ); - ret = vasprintf( msgbuf, format_str, ap ); + ret = vasprintf( &msgbuf, format_str, ap ); va_end( ap ); if (ret == -1) return; #if defined(HAVE_SYSLOG) - syslog( priority, "%s", *msgbuf ); + syslog( priority, "%s", msgbuf ); #else - DEBUG(0,("%s", *msgbuf )); + DEBUG(0,("%s", msgbuf )); #endif - SAFE_FREE(*msgbuf); + SAFE_FREE(msgbuf); } diff --git a/source3/lib/system_smbd.c b/source3/lib/system_smbd.c index 28ceaf39390..0cd30869453 100644 --- a/source3/lib/system_smbd.c +++ b/source3/lib/system_smbd.c @@ -41,6 +41,11 @@ static int getgrouplist_internals(const char *user, gid_t gid, gid_t *groups, in gid_t *gids_saved; int ret, ngrp_saved; + if (non_root_mode()) { + *grpcnt = 0; + return 0; + } + /* work out how many groups we need to save */ ngrp_saved = getgroups(0, NULL); if (ngrp_saved == -1) { @@ -56,13 +61,14 @@ static int getgrouplist_internals(const char *user, gid_t gid, gid_t *groups, in ngrp_saved = getgroups(ngrp_saved, gids_saved); if (ngrp_saved == -1) { - free(gids_saved); + SAFE_FREE(gids_saved); /* very strange! */ return -1; } if (initgroups(user, gid) != 0) { - free(gids_saved); + DEBUG(0, ("getgrouplist_internals: initgroups() failed!\n")); + SAFE_FREE(gids_saved); return -1; } @@ -101,5 +107,6 @@ int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grpcnt) become_root(); retval = getgrouplist_internals(user, gid, groups, grpcnt); unbecome_root(); + return retval; #endif } diff --git a/source3/lib/time.c b/source3/lib/time.c index 9d87414aea0..ef12dc15f34 100644 --- a/source3/lib/time.c +++ b/source3/lib/time.c @@ -40,6 +40,12 @@ int extra_time_offset = 0; #define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN) #endif +void get_nttime_max(NTTIME *t) +{ + /* FIXME: This is incorrect */ + unix_to_nt_time(t, get_time_t_max()); +} + /******************************************************************* External access to time_t_min and time_t_max. ********************************************************************/ diff --git a/source3/lib/username.c b/source3/lib/username.c index 5db7f58b1e2..ef11542ab19 100644 --- a/source3/lib/username.c +++ b/source3/lib/username.c @@ -273,27 +273,6 @@ done: return ret; } -/**************************************************************************** - Get_Pwnam wrapper for modification. - NOTE: This can potentially modify 'user'! -****************************************************************************/ - -struct passwd *Get_Pwnam_Modify(fstring user) -{ - fstring user2; - struct passwd *ret; - - fstrcpy(user2, user); - - ret = Get_Pwnam_internals(user, user2); - - /* If caller wants the modified username, ensure they get it */ - fstrcpy(user,user2); - - /* We can safely assume ret is NULL if none of the above succeed */ - return(ret); -} - /**************************************************************************** Get_Pwnam wrapper without modification. NOTE: This with NOT modify 'user'! @@ -636,39 +615,3 @@ static struct passwd * uname_string_combinations(char *s,struct passwd * (*fn)(c return(NULL); } -/**************************************************************************** - These wrappers allow appliance mode to work. In appliance mode the username - takes the form DOMAIN/user. -****************************************************************************/ - -struct passwd *smb_getpwnam(char *user, BOOL allow_change) -{ - struct passwd *pw; - char *p; - char *sep; - extern pstring global_myname; - - if (allow_change) - pw = Get_Pwnam_Modify(user); - else - pw = Get_Pwnam(user); - - if (pw) - return pw; - - /* - * If it is a domain qualified name and it isn't in our password - * database but the domain portion matches our local machine name then - * lookup just the username portion locally. - */ - - sep = lp_winbind_separator(); - p = strchr_m(user,*sep); - if (p && strncasecmp(global_myname, user, strlen(global_myname))==0) { - if (allow_change) - pw = Get_Pwnam_Modify(p+1); - else - pw = Get_Pwnam(p+1); - } - return NULL; -} diff --git a/source3/lib/util.c b/source3/lib/util.c index ae94b710b2c..51b92568b4d 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -260,8 +260,8 @@ void show_msg(char *buf) int i; int bcc=0; - if (DEBUGLEVEL < 5) return; - + if (!DEBUGLVL(5)) return; + DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n", smb_len(buf), (int)CVAL(buf,smb_com), @@ -270,31 +270,26 @@ void show_msg(char *buf) (int)SVAL(buf,smb_err), (int)CVAL(buf,smb_flg), (int)SVAL(buf,smb_flg2))); - DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n", + DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n", (int)SVAL(buf,smb_tid), (int)SVAL(buf,smb_pid), (int)SVAL(buf,smb_uid), - (int)SVAL(buf,smb_mid), - (int)CVAL(buf,smb_wct))); + (int)SVAL(buf,smb_mid))); + DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf,smb_wct))); for (i=0;i<(int)CVAL(buf,smb_wct);i++) - { - DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i, + DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i, SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i))); - } - + bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct))); - DEBUG(5,("smb_bcc=%d\n",bcc)); + DEBUGADD(5,("smb_bcc=%d\n",bcc)); if (DEBUGLEVEL < 10) return; - if (DEBUGLEVEL < 50) - { - bcc = MIN(bcc, 512); - } + if (DEBUGLEVEL < 50) bcc = MIN(bcc, 512); - dump_data(10, smb_buf(buf), bcc); + dump_data(10, smb_buf(buf), bcc); } /******************************************************************* @@ -1140,8 +1135,18 @@ something really nasty happened - panic! void smb_panic(char *why) { char *cmd = lp_panic_action(); + int result; + if (cmd && *cmd) { - system(cmd); + DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd)); + result = system(cmd); + + if (result == -1) + DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n", + strerror(errno))); + else + DEBUG(0, ("smb_panic(): action returned status %d\n", + WEXITSTATUS(result))); } DEBUG(0,("PANIC: %s\n", why)); dbgflush(); @@ -1564,35 +1569,35 @@ void print_asc(int level, const unsigned char *buf,int len) void dump_data(int level, const char *buf1,int len) { - const unsigned char *buf = (const unsigned char *)buf1; - int i=0; - if (len<=0) return; - - DEBUG(level,("[%03X] ",i)); - for (i=0;i8) DEBUG(level,(" ")); - while (n--) DEBUG(level,(" ")); - - n = MIN(8,i%16); - print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" ")); - n = (i%16) - n; - if (n>0) print_asc(level,&buf[i-n],n); - DEBUG(level,("\n")); - } + const unsigned char *buf = (const unsigned char *)buf1; + int i=0; + if (len<=0) return; + + if (!DEBUGLVL(level)) return; + + DEBUGADD(level,("[%03X] ",i)); + for (i=0;i8) DEBUGADD(level,(" ")); + while (n--) DEBUGADD(level,(" ")); + n = MIN(8,i%16); + print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,( " " )); + n = (i%16) - n; + if (n>0) print_asc(level,&buf[i-n],n); + DEBUGADD(level,("\n")); + } } char *tab_depth(int depth) @@ -1819,6 +1824,17 @@ char *smb_xstrdup(const char *s) return s1; } +/** + strndup that aborts on malloc fail. +**/ +char *smb_xstrndup(const char *s, size_t n) +{ + char *s1 = strndup(s, n); + if (!s1) + smb_panic("smb_xstrndup: malloc fail\n"); + return s1; +} + /* vasprintf that aborts on malloc fail */ diff --git a/source3/lib/util_seaccess.c b/source3/lib/util_seaccess.c index 9fdf03adfc8..b137023e55c 100644 --- a/source3/lib/util_seaccess.c +++ b/source3/lib/util_seaccess.c @@ -21,6 +21,8 @@ #include "includes.h" +extern DOM_SID global_sid_Builtin; + /********************************************************************************** Check if this ACE has a SID in common with the token. **********************************************************************************/ @@ -42,7 +44,7 @@ static BOOL token_sid_in_ace(const NT_USER_TOKEN *token, const SEC_ACE *ace) bits not yet granted. Zero means permission allowed (no more needed bits). **********************************************************************************/ -static uint32 check_ace(SEC_ACE *ace, NT_USER_TOKEN *token, uint32 acc_desired, +static uint32 check_ace(SEC_ACE *ace, const NT_USER_TOKEN *token, uint32 acc_desired, NTSTATUS *status) { uint32 mask = ace->info.mask; @@ -102,7 +104,7 @@ static uint32 check_ace(SEC_ACE *ace, NT_USER_TOKEN *token, uint32 acc_desired, include other bits requested. **********************************************************************************/ -static BOOL get_max_access( SEC_ACL *the_acl, NT_USER_TOKEN *token, uint32 *granted, +static BOOL get_max_access( SEC_ACL *the_acl, const NT_USER_TOKEN *token, uint32 *granted, uint32 desired, NTSTATUS *status) { @@ -224,7 +226,7 @@ void se_map_standard(uint32 *access_mask, struct standard_mapping *mapping) "Access-Checking" document in MSDN. *****************************************************************************/ -BOOL se_access_check(SEC_DESC *sd, NT_USER_TOKEN *token, +BOOL se_access_check(SEC_DESC *sd, const NT_USER_TOKEN *token, uint32 acc_desired, uint32 *acc_granted, NTSTATUS *status) { @@ -262,12 +264,13 @@ BOOL se_access_check(SEC_DESC *sd, NT_USER_TOKEN *token, } /* The user sid is the first in the token */ - - DEBUG(3, ("se_access_check: user sid is %s\n", sid_to_string(sid_str, &token->user_sids[PRIMARY_USER_SID_INDEX]) )); - - for (i = 1; i < token->num_sids; i++) { - DEBUG(3, ("se_access_check: also %s\n", - sid_to_string(sid_str, &token->user_sids[i]))); + if (DEBUGLVL(3)) { + DEBUG(3, ("se_access_check: user sid is %s\n", sid_to_string(sid_str, &token->user_sids[PRIMARY_USER_SID_INDEX]) )); + + for (i = 1; i < token->num_sids; i++) { + DEBUGADD(3, ("se_access_check: also %s\n", + sid_to_string(sid_str, &token->user_sids[i]))); + } } /* Is the token the owner of the SID ? */ @@ -297,7 +300,7 @@ BOOL se_access_check(SEC_DESC *sd, NT_USER_TOKEN *token, for ( i = 0 ; i < the_acl->num_aces && tmp_acc_desired != 0; i++) { SEC_ACE *ace = &the_acl->ace[i]; - DEBUG(10,("se_access_check: ACE %u: type %d, flags = 0x%02x, SID = %s mask = %x, current desired = %x\n", + DEBUGADD(10,("se_access_check: ACE %u: type %d, flags = 0x%02x, SID = %s mask = %x, current desired = %x\n", (unsigned int)i, ace->type, ace->flags, sid_to_string(sid_str, &ace->trustee), (unsigned int) ace->info.mask, @@ -442,3 +445,42 @@ SEC_DESC_BUF *se_create_child_secdesc(TALLOC_CTX *ctx, SEC_DESC *parent_ctr, return sdb; } + +/******************************************************************* + samr_make_sam_obj_sd + ********************************************************************/ + +NTSTATUS samr_make_sam_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size) +{ + extern DOM_SID global_sid_World; + DOM_SID adm_sid; + DOM_SID act_sid; + + SEC_ACE ace[3]; + SEC_ACCESS mask; + + SEC_ACL *psa = NULL; + + sid_copy(&adm_sid, &global_sid_Builtin); + sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS); + + sid_copy(&act_sid, &global_sid_Builtin); + sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS); + + /*basic access for every one*/ + init_sec_access(&mask, SAMR_EXECUTE | SAMR_READ); + init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); + + /*full access for builtin aliases Administrators and Account Operators*/ + init_sec_access(&mask, SAMR_ALL_ACCESS); + init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); + init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); + + if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL) + return NT_STATUS_NO_MEMORY; + + if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL) + return NT_STATUS_NO_MEMORY; + + return NT_STATUS_OK; +} diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c index ad09f912346..e9635fc7f84 100644 --- a/source3/lib/util_sid.c +++ b/source3/lib/util_sid.c @@ -30,13 +30,11 @@ extern fstring global_myworkgroup; * Some useful sids */ -DOM_SID global_sid_Builtin; /* Local well-known domain */ DOM_SID global_sid_World_Domain; /* Everyone domain */ DOM_SID global_sid_World; /* Everyone */ DOM_SID global_sid_Creator_Owner_Domain; /* Creator Owner domain */ DOM_SID global_sid_NT_Authority; /* NT Authority */ DOM_SID global_sid_NULL; /* NULL sid */ -DOM_SID global_sid_Builtin_Guests; /* Builtin guest users */ DOM_SID global_sid_Authenticated_Users; /* All authenticated rids */ DOM_SID global_sid_Network; /* Network rids */ @@ -44,6 +42,11 @@ static DOM_SID global_sid_Creator_Owner; /* Creator Owner */ static DOM_SID global_sid_Creator_Group; /* Creator Group */ static DOM_SID global_sid_Anonymous; /* Anonymous login */ +DOM_SID global_sid_Builtin; /* Local well-known domain */ +DOM_SID global_sid_Builtin_Administrators; +DOM_SID global_sid_Builtin_Users; +DOM_SID global_sid_Builtin_Guests; /* Builtin guest users */ + /* * An NT compatible anonymous token. */ @@ -99,6 +102,8 @@ const char *sid_type_lookup(uint32 sid_type) void generate_wellknown_sids(void) { string_to_sid(&global_sid_Builtin, "S-1-5-32"); + string_to_sid(&global_sid_Builtin_Administrators, "S-1-5-32-544"); + string_to_sid(&global_sid_Builtin_Users, "S-1-5-32-545"); string_to_sid(&global_sid_Builtin_Guests, "S-1-5-32-546"); string_to_sid(&global_sid_World_Domain, "S-1-1"); string_to_sid(&global_sid_World, "S-1-1-0"); @@ -525,3 +530,18 @@ char *sid_binstring(DOM_SID *sid) return s; } + +/* + print a GUID structure for debugging +*/ +void print_guid(GUID *guid) +{ + int i; + + d_printf("%08x-%04x-%04x", + IVAL(guid->info, 0), SVAL(guid->info, 4), SVAL(guid->info, 6)); + d_printf("-%02x%02x-", guid->info[8], guid->info[9]); + for (i=10;iinfo[i]); + d_printf("\n"); +} diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 5e2b7c5ed97..fc2abf976f4 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -871,7 +871,7 @@ static BOOL matchname(char *remotehost,struct in_addr addr) /* Look up the host address in the address list we just got. */ for (i = 0; hp->h_addr_list[i]; i++) { - if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0) + if (memcmp(hp->h_addr_list[i], (char *) & addr, sizeof(addr)) == 0) return True; } @@ -976,6 +976,7 @@ int create_pipe_sock(const char *socket_dir, const char *socket_name, mode_t dir_perms) { +#ifdef HAVE_UNIXSOCKET struct sockaddr_un sunaddr; struct stat st; int sock; @@ -1064,6 +1065,10 @@ int create_pipe_sock(const char *socket_dir, /* Success! */ return sock; +#else + DEBUG(0, ("create_pipe_sock: No Unix sockets on this system\n")); + return -1; +#endif /* HAVE_UNIXSOCKET */ } /******************************************************************* diff --git a/source3/lib/util_unistr.c b/source3/lib/util_unistr.c index ba02819bdc6..eb472524131 100644 --- a/source3/lib/util_unistr.c +++ b/source3/lib/util_unistr.c @@ -218,6 +218,16 @@ void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen) pull_ucs2(NULL, dest, str->buffer, maxlen, str->uni_str_len*2, STR_NOALIGN); } +/******************************************************************* +give a static string for displaying a UNISTR2 +********************************************************************/ +const char *unistr2_static(const UNISTR2 *str) +{ + static pstring ret; + unistr2_to_ascii(ret, str, sizeof(ret)); + return ret; +} + /******************************************************************* duplicate a UNISTR2 string into a null terminated char* diff --git a/source3/lib/xfile.c b/source3/lib/xfile.c index b5710f3a39e..7621712e9ad 100644 --- a/source3/lib/xfile.c +++ b/source3/lib/xfile.c @@ -43,6 +43,7 @@ XFILE *x_stderr = &_x_stderr; #define X_FLAG_EOF 1 #define X_FLAG_ERROR 2 +#define X_FLAG_EINVAL 3 /* simulate setvbuf() */ int x_setvbuf(XFILE *f, char *buf, int mode, size_t size) @@ -341,3 +342,36 @@ char *x_fgets(char *s, int size, XFILE *stream) *s = 0; return s0; } + +/* trivial seek, works only for SEEK_SET and SEEK_END if SEEK_CUR is + * set then an error is returned */ +off_t x_tseek(XFILE *f, off_t offset, int whence) +{ + if (f->flags & X_FLAG_ERROR) + return -1; + + /* only SEEK_SET and SEEK_END are supported */ + /* SEEK_CUR needs internal offset counter */ + if (whence != SEEK_SET && whence != SEEK_END) { + f->flags |= X_FLAG_EINVAL; + errno = EINVAL; + return -1; + } + + /* empty the buffer */ + switch (f->open_flags & O_ACCMODE) { + case O_RDONLY: + f->bufused = 0; + break; + case O_WRONLY: + if (x_fflush(f) != 0) + return -1; + break; + default: + errno = EINVAL; + return -1; + } + + f->flags &= ~X_FLAG_EOF; + return (off_t)sys_lseek(f->fd, offset, whence); +} diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index 2d1830435fe..d85f9c9b58a 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -30,19 +30,49 @@ ADS_STATUS ads_build_error(enum ads_error_type etype, int rc, int minor_status) { ADS_STATUS ret; - ret.error_type = etype; - ret.rc = rc; + + if (etype == ADS_ERROR_NT) { + DEBUG(0,("don't use ads_build_error with ADS_ERROR_NT!\n")); + ret.err.rc = -1; + ret.error_type = ADS_ERROR_SYSTEM; + ret.minor_status = 0; + return ret; + } + + ret.err.rc = rc; + ret.error_type = etype; ret.minor_status = minor_status; return ret; } +ADS_STATUS ads_build_nt_error(enum ads_error_type etype, + NTSTATUS nt_status) +{ + ADS_STATUS ret; + + if (etype != ADS_ERROR_NT) { + DEBUG(0,("don't use ads_build_nt_error without ADS_ERROR_NT!\n")); + ret.err.rc = -1; + ret.error_type = ADS_ERROR_SYSTEM; + ret.minor_status = 0; + return ret; + } + ret.err.nt_status = nt_status; + ret.error_type = etype; + ret.minor_status = 0; + return ret; +} + /* do a rough conversion between ads error codes and NT status codes we'll need to fill this in more */ -NTSTATUS ads_ntstatus(ADS_STATUS rc) +NTSTATUS ads_ntstatus(ADS_STATUS status) { - if (ADS_ERR_OK(rc)) return NT_STATUS_OK; + if (status.error_type == ADS_ERROR_NT){ + return status.err.nt_status; + } + if (ADS_ERR_OK(status)) return NT_STATUS_OK; return NT_STATUS_UNSUCCESSFUL; } @@ -59,14 +89,14 @@ const char *ads_errstr(ADS_STATUS status) switch (status.error_type) { case ADS_ERROR_SYSTEM: - return strerror(status.rc); + return strerror(status.err.rc); #ifdef HAVE_LDAP case ADS_ERROR_LDAP: - return ldap_err2string(status.rc); + return ldap_err2string(status.err.rc); #endif #ifdef HAVE_KRB5 case ADS_ERROR_KRB5: - return error_message(status.rc); + return error_message(status.err.rc); #endif #ifdef HAVE_GSSAPI case ADS_ERROR_GSS: @@ -76,7 +106,7 @@ const char *ads_errstr(ADS_STATUS status) gss_buffer_desc msg1, msg2; msg1.value = NULL; msg2.value = NULL; - gss_display_status(&minor, status.rc, GSS_C_GSS_CODE, + gss_display_status(&minor, status.err.rc, GSS_C_GSS_CODE, GSS_C_NULL_OID, &msg_ctx, &msg1); gss_display_status(&minor, status.minor_status, GSS_C_MECH_CODE, GSS_C_NULL_OID, &msg_ctx, &msg2); @@ -86,6 +116,8 @@ const char *ads_errstr(ADS_STATUS status) return ret; } #endif + case ADS_ERROR_NT: + return nt_errstr(ads_ntstatus(status)); default: return "Unknown ADS error type!? (not compiled in?)"; } diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 9a486237c9f..a80837cf4df 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -50,7 +50,7 @@ kerb_prompter(krb5_context ctx, void *data, simulate a kinit, putting the tgt in the default cache location remus@snapserver.com */ -int kerberos_kinit_password(const char *principal, const char *password) +int kerberos_kinit_password(const char *principal, const char *password, int time_offset) { krb5_context ctx; krb5_error_code code = 0; @@ -60,6 +60,10 @@ int kerberos_kinit_password(const char *principal, const char *password) if ((code = krb5_init_context(&ctx))) return code; + + if (time_offset != 0) { + krb5_set_real_time(ctx, time(NULL) + time_offset, 0); + } if ((code = krb5_cc_default(ctx, &cc))) { krb5_free_context(ctx); @@ -111,7 +115,7 @@ int ads_kinit_password(ADS_STRUCT *ads) int ret; asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm); - ret = kerberos_kinit_password(s, ads->auth.password); + ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index ec79a8658fe..a49b6cbe3b0 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -248,7 +248,8 @@ static krb5_error_code parse_setpw_reply(krb5_context context, return 0; } -ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char *newpw) +ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char *newpw, + int time_offset) { krb5_context context; krb5_auth_context auth_context = NULL; @@ -268,6 +269,10 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char return ADS_ERROR_KRB5(ret); } + if (time_offset != 0) { + krb5_set_real_time(context, time(NULL) + time_offset, 0); + } + ret = krb5_cc_default(context, &ccache); if (ret) { krb5_free_context(context); @@ -452,16 +457,17 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char ADS_STATUS kerberos_set_password(const char *kpasswd_server, const char *auth_principal, const char *auth_password, - const char *target_principal, const char *new_password) + const char *target_principal, const char *new_password, + int time_offset) { int ret; - if ((ret = kerberos_kinit_password(auth_principal, auth_password))) { + if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset))) { DEBUG(1,("Failed kinit for principal %s (%s)\n", auth_principal, error_message(ret))); return ADS_ERROR_KRB5(ret); } - return krb5_set_password(kpasswd_server, target_principal, new_password); + return krb5_set_password(kpasswd_server, target_principal, new_password, time_offset); } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 26724894829..7a0afb1a816 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -63,6 +63,7 @@ static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) ads->ldap_port = port; ads->ldap_ip = *interpret_addr2(srv); free(srv); + return True; } @@ -204,7 +205,6 @@ static BOOL ads_try_netbios(ADS_STRUCT *ads) ADS_STATUS ads_connect(ADS_STRUCT *ads) { int version = LDAP_VERSION3; - int code; ADS_STATUS status; ads->last_attempt = time(NULL); @@ -226,7 +226,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) /* try via DNS */ if (ads_try_dns(ads)) { goto got_connection; - } + } /* try via netbios lookups */ if (!lp_disable_netbios() && ads_try_netbios(ads)) { @@ -274,12 +274,7 @@ got_connection: } #endif - if (ads->auth.password) { - if ((code = ads_kinit_password(ads))) - return ADS_ERROR_KRB5(code); - } - - if (ads->auth.no_bind) { + if (ads->auth.flags & ADS_AUTH_NO_BIND) { return ADS_SUCCESS; } @@ -613,14 +608,17 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, char *utf8_exp, *utf8_path, **search_attrs = NULL; TALLOC_CTX *ctx; - if (!(ctx = talloc_init())) + if (!(ctx = talloc_init())) { + DEBUG(1,("ads_do_search: talloc_init() failed!")); return ADS_ERROR(LDAP_NO_MEMORY); + } /* 0 means the conversion worked but the result was empty so we only fail if it's negative. In any case, it always at least nulls out the dest */ if ((push_utf8_talloc(ctx, &utf8_exp, exp) < 0) || (push_utf8_talloc(ctx, &utf8_path, bind_path) < 0)) { + DEBUG(1,("ads_do_search: push_utf8_talloc() failed!")); rc = LDAP_NO_MEMORY; goto done; } @@ -632,6 +630,7 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */ if (!(str_list_copy(&search_attrs, attrs))) { + DEBUG(1,("ads_do_search: str_list_copy() failed!")); rc = LDAP_NO_MEMORY; goto done; } @@ -826,7 +825,11 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, ADS_STATUS ads_mod_str(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const char *val) { - const char *values[2] = {val, NULL}; + const char *values[2]; + + values[0] = val; + values[1] = NULL; + if (!val) return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, name, @@ -861,7 +864,10 @@ ADS_STATUS ads_mod_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, static ADS_STATUS ads_mod_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const struct berval *val) { - const struct berval *values[2] = {val, NULL}; + const struct berval *values[2]; + + values[0] = val; + values[1] = NULL; if (!val) return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE|LDAP_MOD_BVALUES, @@ -884,7 +890,7 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) non-existent attribute (but allowable for the object) to run */ LDAPControl PermitModify = { - "1.2.840.113556.1.4.1413", + ADS_PERMIT_MODIFY_OID, {0, NULL}, (char) 1}; LDAPControl *controls[2]; @@ -1410,7 +1416,7 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, */ asprintf(&principal, "%s$@%s", host, ads->auth.realm); - status = krb5_set_password(ads->auth.kdc_server, principal, password); + status = krb5_set_password(ads->auth.kdc_server, principal, password, ads->auth.time_offset); free(host); free(principal); @@ -1616,6 +1622,26 @@ ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn) return ADS_SUCCESS; } +/* parse a ADS timestring - typical string is + '20020917091222.0Z0' which means 09:12.22 17th September + 2002, timezone 0 */ +static time_t ads_parse_time(const char *str) +{ + struct tm tm; + + ZERO_STRUCT(tm); + + if (sscanf(str, "%4d%2d%2d%2d%2d%2d", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, + &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { + return 0; + } + tm.tm_year -= 1900; + tm.tm_mon -= 1; + + return timegm(&tm); +} + /** * Find the servers name and realm - this can be done before authentication @@ -1626,22 +1652,37 @@ ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn) **/ ADS_STATUS ads_server_info(ADS_STRUCT *ads) { - const char *attrs[] = {"ldapServiceName", NULL}; + const char *attrs[] = {"ldapServiceName", "currentTime", NULL}; ADS_STATUS status; void *res; - char **values; + char *value; char *p; + char *timestr; + TALLOC_CTX *ctx; + + if (!(ctx = talloc_init())) { + return ADS_ERROR(LDAP_NO_MEMORY); + } status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (!ADS_ERR_OK(status)) return status; - values = ldap_get_values(ads->ld, res, "ldapServiceName"); - if (!values || !values[0]) return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + value = ads_pull_string(ads, ctx, res, "ldapServiceName"); + if (!value) { + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } + + timestr = ads_pull_string(ads, ctx, res, "currentTime"); + if (!timestr) { + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } + + ldap_msgfree(res); - p = strchr(values[0], ':'); + p = strchr(value, ':'); if (!p) { - ldap_value_free(values); - ldap_msgfree(res); + talloc_destroy(ctx); + DEBUG(1, ("ads_server_info: returned ldap server name did not contain a ':' so was deemed invalid\n")); return ADS_ERROR(LDAP_DECODING_ERROR); } @@ -1650,9 +1691,9 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) ads->config.ldap_server_name = strdup(p+1); p = strchr(ads->config.ldap_server_name, '$'); if (!p || p[1] != '@') { - ldap_value_free(values); - ldap_msgfree(res); + talloc_destroy(ctx); SAFE_FREE(ads->config.ldap_server_name); + DEBUG(1, ("ads_server_info: returned ldap server name did not contain '$@' so was deemed invalid\n")); return ADS_ERROR(LDAP_DECODING_ERROR); } @@ -1667,6 +1708,15 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) DEBUG(3,("got ldap server name %s@%s\n", ads->config.ldap_server_name, ads->config.realm)); + ads->config.current_time = ads_parse_time(timestr); + + if (ads->config.current_time != 0) { + ads->auth.time_offset = ads->config.current_time - time(NULL); + DEBUG(4,("time offset is %d seconds\n", ads->auth.time_offset)); + } + + talloc_destroy(ctx); + return ADS_SUCCESS; } diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 64ae8252c81..66984477b81 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -28,7 +28,7 @@ results can be used. It should be freed using ads_msgfree. */ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res, - char *printer, char *servername) + const char *printer, char *servername) { ADS_STATUS status; char *srv_dn, **srv_cn, *exp; diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 81dedb0a81e..f7dd01084a2 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -22,37 +22,198 @@ #ifdef HAVE_ADS -#if USE_CYRUS_SASL -/* - this is a minimal interact function, just enough for SASL to talk - GSSAPI/kerberos to W2K - Error handling is a bit of a problem. I can't see how to get Cyrus-sasl - to give sensible errors +/* + perform a LDAP/SASL/SPNEGO/NTLMSSP bind (just how many layers can + we fit on one socket??) */ -static int sasl_interact(LDAP *ld,unsigned flags,void *defaults,void *in) +static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) { - sasl_interact_t *interact = in; + const char *mechs[] = {OID_NTLMSSP, NULL}; + DATA_BLOB msg1; + DATA_BLOB blob, chal1, chal2, auth; + uint8 challenge[8]; + uint8 nthash[24], lmhash[24], sess_key[16]; + uint32 neg_flags; + struct berval cred, *scred; + ADS_STATUS status; + extern pstring global_myname; + int rc; - while (interact->id != SASL_CB_LIST_END) { - interact->result = strdup(""); - interact->len = strlen(interact->result); - interact++; + if (!ads->auth.password) { + /* No password, don't segfault below... */ + return ADS_ERROR_NT(NT_STATUS_LOGON_FAILURE); } - - return LDAP_SUCCESS; + + neg_flags = NTLMSSP_NEGOTIATE_UNICODE | + NTLMSSP_NEGOTIATE_128 | + NTLMSSP_NEGOTIATE_NTLM; + + memset(sess_key, 0, 16); + + /* generate the ntlmssp negotiate packet */ + msrpc_gen(&blob, "CddB", + "NTLMSSP", + NTLMSSP_NEGOTIATE, + neg_flags, + sess_key, 16); + + /* and wrap it in a SPNEGO wrapper */ + msg1 = gen_negTokenTarg(mechs, blob); + data_blob_free(&blob); + + cred.bv_val = msg1.data; + cred.bv_len = msg1.length; + + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + if (rc != LDAP_SASL_BIND_IN_PROGRESS) { + status = ADS_ERROR(rc); + goto failed; + } + + blob = data_blob(scred->bv_val, scred->bv_len); + + /* the server gives us back two challenges */ + if (!spnego_parse_challenge(blob, &chal1, &chal2)) { + DEBUG(3,("Failed to parse challenges\n")); + status = ADS_ERROR(LDAP_OPERATIONS_ERROR); + goto failed; + } + + data_blob_free(&blob); + + /* encrypt the password with the challenge */ + memcpy(challenge, chal1.data + 24, 8); + SMBencrypt(ads->auth.password, challenge,lmhash); + SMBNTencrypt(ads->auth.password, challenge,nthash); + + data_blob_free(&chal1); + data_blob_free(&chal2); + + /* this generates the actual auth packet */ + msrpc_gen(&blob, "CdBBUUUBd", + "NTLMSSP", + NTLMSSP_AUTH, + lmhash, 24, + nthash, 24, + lp_workgroup(), + ads->auth.user_name, + global_myname, + sess_key, 16, + neg_flags); + + /* wrap it in SPNEGO */ + auth = spnego_gen_auth(blob); + + data_blob_free(&blob); + + /* now send the auth packet and we should be done */ + cred.bv_val = auth.data; + cred.bv_len = auth.length; + + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + + return ADS_ERROR(rc); + +failed: + return status; } + +/* + perform a LDAP/SASL/SPNEGO/KRB5 bind +*/ +static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *principal) +{ + DATA_BLOB blob; + struct berval cred, *scred; + int rc; + + blob = spnego_gen_negTokenTarg(principal, ads->auth.time_offset); + + if (!blob.data) { + return ADS_ERROR(LDAP_OPERATIONS_ERROR); + } + + /* now send the auth packet and we should be done */ + cred.bv_val = blob.data; + cred.bv_len = blob.length; + + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + + data_blob_free(&blob); + + return ADS_ERROR(rc); +} + +/* + this performs a SASL/SPNEGO bind +*/ +static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) +{ + struct berval *scred=NULL; + int rc, i; + ADS_STATUS status; + DATA_BLOB blob; + char *principal; + char *OIDs[ASN1_MAX_OIDS]; + BOOL got_kerberos_mechanism = False; + + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred); + + if (rc != LDAP_SASL_BIND_IN_PROGRESS) { + status = ADS_ERROR(rc); + goto failed; + } + + blob = data_blob(scred->bv_val, scred->bv_len); + +#if 0 + file_save("sasl_spnego.dat", blob.data, blob.length); #endif + /* the server sent us the first part of the SPNEGO exchange in the negprot + reply */ + if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) { + data_blob_free(&blob); + status = ADS_ERROR(LDAP_OPERATIONS_ERROR); + goto failed; + } + data_blob_free(&blob); + + /* make sure the server understands kerberos */ + for (i=0;OIDs[i];i++) { + DEBUG(3,("got OID=%s\n", OIDs[i])); + if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 || + strcmp(OIDs[i], OID_KERBEROS5) == 0) { + got_kerberos_mechanism = True; + } + free(OIDs[i]); + } + DEBUG(3,("got principal=%s\n", principal)); + if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && + got_kerberos_mechanism && ads_kinit_password(ads) == 0) { + return ads_sasl_spnego_krb5_bind(ads, principal); + } + + /* lets do NTLMSSP ... this has the big advantage that we don't need + to sync clocks, and we don't rely on special versions of the krb5 + library for HMAC_MD4 encryption */ + return ads_sasl_spnego_ntlmssp_bind(ads); + +failed: + return status; +} + +#ifdef HAVE_GSSAPI #define MAX_GSS_PASSES 3 /* this performs a SASL/gssapi bind we avoid using cyrus-sasl to make Samba more robust. cyrus-sasl is very dependent on correctly configured DNS whereas this routine is much less fragile - see RFC2078 for details + see RFC2078 and RFC2222 for details */ -ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) +static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) { int minor_status; gss_name_t serv_name; @@ -68,6 +229,7 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) uint8 *p; uint32 max_msg_size; char *sname; + unsigned sec_layer; ADS_STATUS status; krb5_principal principal; krb5_context ctx; @@ -159,22 +321,25 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) p = (uint8 *)output_token.value; + file_save("sasl_gssapi.dat", output_token.value, output_token.length); + max_msg_size = (p[1]<<16) | (p[2]<<8) | p[3]; + sec_layer = *p; gss_release_buffer(&minor_status, &output_token); output_token.value = malloc(strlen(ads->config.bind_path) + 8); p = output_token.value; - *p++ = 1; /* no sign or seal */ + *p++ = 1; /* no sign & seal selection */ /* choose the same size as the server gave us */ *p++ = max_msg_size>>16; *p++ = max_msg_size>>8; *p++ = max_msg_size; snprintf(p, strlen(ads->config.bind_path)+4, "dn:%s", ads->config.bind_path); - p += strlen(ads->config.bind_path); + p += strlen(p); - output_token.length = strlen(ads->config.bind_path) + 8; + output_token.length = PTR_DIFF(p, output_token.value); gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT, &output_token, &conf_state, @@ -198,18 +363,51 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) failed: return status; } +#endif + +/* mapping between SASL mechanisms and functions */ +static struct { + const char *name; + ADS_STATUS (*fn)(ADS_STRUCT *); +} sasl_mechanisms[] = { + {"GSS-SPNEGO", ads_sasl_spnego_bind}, +#ifdef HAVE_GSSAPI + {"GSSAPI", ads_sasl_gssapi_bind}, /* doesn't work with .NET RC1. No idea why */ +#endif + {NULL, NULL} +}; ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads) { -#if USE_CYRUS_SASL - int rc; - rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, - LDAP_SASL_QUIET, - sasl_interact, NULL); - return ADS_ERROR(rc); -#else - return ads_sasl_gssapi_bind(ads); -#endif + const char *attrs[] = {"supportedSASLMechanisms", NULL}; + char **values; + ADS_STATUS status; + int i, j; + void *res; + + /* get a list of supported SASL mechanisms */ + status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + if (!ADS_ERR_OK(status)) return status; + + values = ldap_get_values(ads->ld, res, "supportedSASLMechanisms"); + + /* try our supported mechanisms in order */ + for (i=0;sasl_mechanisms[i].name;i++) { + /* see if the server supports it */ + for (j=0;values && values[j];j++) { + if (strcmp(values[j], sasl_mechanisms[i].name) == 0) { + DEBUG(4,("Found SASL mechanism %s\n", values[j])); + status = sasl_mechanisms[i].fn(ads); + ldap_value_free(values); + ldap_msgfree(res); + return status; + } + } + } + + ldap_value_free(values); + ldap_msgfree(res); + return ADS_ERROR(LDAP_AUTH_METHOD_NOT_SUPPORTED); } #endif diff --git a/source3/libads/util.c b/source3/libads/util.c index b10b130a313..021f2d93e4a 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -40,7 +40,7 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip asprintf(&service_principal, "HOST/%s", host_principal); ret = kerberos_set_password(ads->auth.kdc_server, host_principal, password, - service_principal, new_password); + service_principal, new_password, ads->auth.time_offset); if (!secrets_store_machine_password(new_password)) { DEBUG(1,("Failed to save machine password\n")); diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index b4ad3ad0b89..b7cfca41fbf 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -174,6 +174,16 @@ BOOL asn1_write_BOOLEAN(ASN1_DATA *data, BOOL v) return !data->has_error; } +/* write a BOOLEAN - hmm, I suspect this one is the correct one, and the + above boolean is bogus. Need to check */ +BOOL asn1_write_BOOLEAN2(ASN1_DATA *data, BOOL v) +{ + asn1_push_tag(data, ASN1_BOOLEAN); + asn1_write_uint8(data, v); + asn1_pop_tag(data); + return !data->has_error; +} + /* check a BOOLEAN */ BOOL asn1_check_BOOLEAN(ASN1_DATA *data, BOOL v) { @@ -244,15 +254,12 @@ BOOL asn1_start_tag(ASN1_DATA *data, uint8 tag) asn1_read_uint8(data, &b); if (b & 0x80) { int n = b & 0x7f; - if (n > 2) { - data->has_error = True; - return False; - } asn1_read_uint8(data, &b); nesting->taglen = b; - if (n == 2) { + while (n > 1) { asn1_read_uint8(data, &b); nesting->taglen = (nesting->taglen << 8) | b; + n--; } } else { nesting->taglen = b; @@ -366,6 +373,7 @@ BOOL asn1_read_GeneralString(ASN1_DATA *data, char **s) BOOL asn1_read_OctetString(ASN1_DATA *data, DATA_BLOB *blob) { int len; + ZERO_STRUCTP(blob); if (!asn1_start_tag(data, ASN1_OCTET_STRING)) return False; len = asn1_tag_remaining(data); *blob = data_blob(NULL, len); @@ -382,7 +390,8 @@ BOOL asn1_read_Integer(ASN1_DATA *data, int *i) if (!asn1_start_tag(data, ASN1_INTEGER)) return False; while (asn1_tag_remaining(data)>0) { - *i = (*i << 8) + asn1_read_uint8(data, &b); + asn1_read_uint8(data, &b); + *i = (*i << 8) + b; } return asn1_end_tag(data); diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 93cf3d95db7..62acccdfb77 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -50,14 +50,12 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, fstring pword; char *p; - if (passlen > sizeof(pword)-1) { + if (passlen > sizeof(pword)-1) return False; - } /* if in share level security then don't send a password now */ - if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) { + if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) passlen = 0; - } if (passlen > 0 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen != 24) { /* Encrypted mode needed, and non encrypted password supplied. */ @@ -99,9 +97,8 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, show_msg(cli->inbuf); - if (cli_is_error(cli)) { + if (cli_is_error(cli)) return False; - } /* use the returned vuid from now on */ cli->vuid = SVAL(cli->inbuf,smb_uid); @@ -118,17 +115,14 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli) { uint32 capabilities = CAP_NT_SMBS; - if (!cli->force_dos_errors) { + if (!cli->force_dos_errors) capabilities |= CAP_STATUS32; - } - if (cli->use_level_II_oplocks) { + if (cli->use_level_II_oplocks) capabilities |= CAP_LEVEL_II_OPLOCKS; - } - if (cli->capabilities & CAP_UNICODE) { + if (cli->capabilities & CAP_UNICODE) capabilities |= CAP_UNICODE; - } return capabilities; } @@ -167,9 +161,8 @@ static BOOL cli_session_setup_guest(struct cli_state *cli) show_msg(cli->inbuf); - if (cli_is_error(cli)) { + if (cli_is_error(cli)) return False; - } cli->vuid = SVAL(cli->inbuf,smb_uid); @@ -223,9 +216,8 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, show_msg(cli->inbuf); - if (cli_is_error(cli)) { + if (cli_is_error(cli)) return False; - } cli->vuid = SVAL(cli->inbuf,smb_uid); p = smb_buf(cli->inbuf); @@ -237,15 +229,41 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, return True; } +static void set_signing_on_cli (struct cli_state *cli, char* pass, uint8 response[24]) +{ + uint8 zero_sig[8]; + ZERO_STRUCT(zero_sig); + + DEBUG(5, ("Server returned security sig:\n")); + dump_data(5, &cli->inbuf[smb_ss_field], 8); -/** + if (cli->sign_info.use_smb_signing) { + DEBUG(5, ("smb signing already active on connection\n")); + } else if (memcmp(&cli->inbuf[smb_ss_field], zero_sig, 8) != 0) { + + DEBUG(3, ("smb signing enabled!\n")); + cli->sign_info.use_smb_signing = True; + cli_calculate_mac_key(cli, pass, response); + } else { + DEBUG(5, ("smb signing NOT enabled!\n")); + } +} + +static void set_temp_signing_on_cli(struct cli_state *cli) +{ + if (cli->sign_info.negotiated_smb_signing) + cli->sign_info.temp_smb_signing = True; +} + + +/**************************************************************************** do a NT1 NTLM/LM encrypted session setup @param cli client state to create do session setup on @param user username @param pass *either* cleartext password (passlen !=24) or LM response. @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear @param workgroup The user's domain. -*/ +****************************************************************************/ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, char *pass, int passlen, @@ -256,11 +274,10 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, uchar pword[24]; uchar ntpword[24]; char *p; - BOOL tried_signing = False; + BOOL have_plaintext = False; - if (passlen > sizeof(pword) || ntpasslen > sizeof(ntpword)) { + if (passlen > sizeof(pword) || ntpasslen > sizeof(ntpword)) return False; - } if (passlen != 24) { /* non encrypted password supplied. Ignore ntpass. */ @@ -268,19 +285,18 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, ntpasslen = 24; SMBencrypt(pass,cli->secblob.data,pword); SMBNTencrypt(pass,cli->secblob.data,ntpword); - if (!cli->sign_info.use_smb_signing && cli->sign_info.negotiated_smb_signing) { - cli_calculate_mac_key(cli, pass, ntpword); - tried_signing = True; - } + + have_plaintext = True; + set_temp_signing_on_cli(cli); } else { - /* pre-encrypted password supplied. Only used for security=server, can't do + /* pre-encrypted password supplied. Only used for + security=server, can't do signing becouse we don't have oringial key */ memcpy(pword, pass, 24); - if (ntpasslen == 24) { + if (ntpasslen == 24) memcpy(ntpword, ntpass, 24); - } else { + else ZERO_STRUCT(ntpword); - } } /* send a session setup command */ @@ -301,31 +317,22 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; memcpy(p,ntpword,ntpasslen); p += ntpasslen; - p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER); - p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER); + p += clistr_push(cli, p, user, -1, STR_TERMINATE); + p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - if (tried_signing) { - /* We only use it if we have a successful non-guest connect */ - cli->sign_info.use_smb_signing = False; - } + if (!cli_send_smb(cli)) return False; - } - show_msg(cli->inbuf); + if (!cli_receive_smb(cli)) + return False; - if (tried_signing && (cli_is_error(cli) || SVAL(cli->inbuf,smb_vwv2) /* guest */)) { - /* We only use it if we have a successful non-guest connect */ - cli->sign_info.use_smb_signing = False; - } + show_msg(cli->inbuf); - if (cli_is_error(cli)) { + if (cli_is_error(cli)) return False; - } /* use the returned vuid from now on */ cli->vuid = SVAL(cli->inbuf,smb_uid); @@ -337,6 +344,11 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, fstrcpy(cli->user_name, user); + if (have_plaintext) { + /* Have plaintext orginal */ + set_signing_on_cli(cli, pass, ntpword); + } + return True; } @@ -360,6 +372,9 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) set_message(cli->outbuf,12,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); + + set_temp_signing_on_cli(cli); + cli_setup_packet(cli); SCVAL(cli->outbuf,smb_vwv0,0xFF); @@ -375,8 +390,8 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); - cli_send_smb(cli); + if (!cli_receive_smb(cli)) return blob2; @@ -404,7 +419,6 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) return blob2; } - #ifdef HAVE_KRB5 /**************************************************************************** Do a spnego/kerberos encrypted session setup. @@ -417,7 +431,7 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principal, c DEBUG(2,("Doing kerberos session setup\n")); /* generate the encapsulated kerberos5 ticket */ - negTokenTarg = spnego_gen_negTokenTarg(cli, principal); + negTokenTarg = spnego_gen_negTokenTarg(principal, 0); if (!negTokenTarg.data) return False; @@ -443,28 +457,32 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principal, c static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, char *pass, char *workgroup) { - const char *mechs[] = {OID_NTLMSSP, NULL}; - DATA_BLOB msg1; - DATA_BLOB blob, chal1, chal2, auth; + DATA_BLOB msg1, struct_blob; + DATA_BLOB blob, chal1, chal2, auth, challenge_blob; uint8 challenge[8]; uint8 nthash[24], lmhash[24], sess_key[16]; - uint32 neg_flags; + uint32 neg_flags, chal_flags, ntlmssp_command, unkn1, unkn2; + pstring server_domain; /* FIX THIS, SHOULD be UCS2-LE */ neg_flags = NTLMSSP_NEGOTIATE_UNICODE | - NTLMSSP_NEGOTIATE_LM_KEY | + NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_NTLM; memset(sess_key, 0, 16); + DEBUG(10, ("sending NTLMSSP_NEGOTIATE\n")); + /* generate the ntlmssp negotiate packet */ - msrpc_gen(&blob, "CddB", + msrpc_gen(&blob, "CddAA", "NTLMSSP", NTLMSSP_NEGOTIATE, neg_flags, - sess_key, 16); - + workgroup, strlen(workgroup), + cli->calling.name, strlen(cli->calling.name) + 1); + DEBUG(10, ("neg_flags: %0X, workgroup: %s, calling name %s\n", + neg_flags, workgroup, cli->calling.name)); /* and wrap it in a SPNEGO wrapper */ - msg1 = gen_negTokenTarg(mechs, blob); + msg1 = gen_negTokenInit(OID_NTLMSSP, blob); data_blob_free(&blob); /* now send that blob on its way */ @@ -472,9 +490,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, data_blob_free(&msg1); - if (!NT_STATUS_EQUAL(cli_nt_error(cli), NT_STATUS_MORE_PROCESSING_REQUIRED)) { + if (!NT_STATUS_EQUAL(cli_nt_error(cli), NT_STATUS_MORE_PROCESSING_REQUIRED)) return False; - } #if 0 file_save("chal.dat", blob.data, blob.length); @@ -488,10 +505,38 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, data_blob_free(&blob); - /* encrypt the password with the challenge */ - memcpy(challenge, chal1.data + 24, 8); + /* + * Ok, chal1 and chal2 are actually two identical copies of + * the NTLMSSP Challenge BLOB, and they contain, encoded in them + * the challenge to use. + */ + + if (!msrpc_parse(&chal1, "CdUdbddB", + "NTLMSSP", + &ntlmssp_command, + &server_domain, + &chal_flags, + &challenge_blob, 8, + &unkn1, &unkn2, + &struct_blob)) { + DEBUG(0, ("Failed to parse the NTLMSSP Challenge\n")); + return False; + } + + if (ntlmssp_command != NTLMSSP_CHALLENGE) { + DEBUG(0, ("NTLMSSP Response != NTLMSSP_CHALLENGE. Got %0X\n", + ntlmssp_command)); + return False; + } + + DEBUG(10, ("Challenge:\n")); + dump_data(10, challenge_blob.data, 8); + + /* encrypt the password with the challenge which is in the blob */ + memcpy(challenge, challenge_blob.data, 8); SMBencrypt(pass, challenge,lmhash); SMBNTencrypt(pass, challenge,nthash); + data_blob_free(&challenge_blob); #if 0 file_save("nthash.dat", nthash, 24); @@ -511,7 +556,7 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, workgroup, user, cli->calling.name, - sess_key, 16, + sess_key, 0, neg_flags); /* wrap it in SPNEGO */ @@ -525,7 +570,12 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, data_blob_free(&auth); data_blob_free(&blob); - return !cli_is_error(cli); + if (cli_is_error(cli)) + return False; + + set_signing_on_cli(cli, pass, nthash); + + return True; } /**************************************************************************** @@ -537,17 +587,14 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, { char *principal; char *OIDs[ASN1_MAX_OIDS]; - uint8 guid[16]; int i; BOOL got_kerberos_mechanism = False; - - /* spnego security cannot use SMB signing (for now). */ - cli->sign_info.use_smb_signing = False; + DATA_BLOB blob; DEBUG(2,("Doing spnego session setup (blob length=%d)\n", cli->secblob.length)); /* the server might not even do spnego */ - if (cli->secblob.length == 16) { + if (cli->secblob.length <= 16) { DEBUG(3,("server didn't supply a full spnego negprot\n")); goto ntlmssp; } @@ -556,11 +603,16 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, file_save("negprot.dat", cli->secblob.data, cli->secblob.length); #endif + /* there is 16 bytes of GUID before the real spnego packet starts */ + blob = data_blob(cli->secblob.data+16, cli->secblob.length-16); + /* the server sent us the first part of the SPNEGO exchange in the negprot reply */ - if (!spnego_parse_negTokenInit(cli->secblob, guid, OIDs, &principal)) { + if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) { + data_blob_free(&blob); return False; } + data_blob_free(&blob); /* make sure the server understands kerberos */ for (i=0;OIDs[i];i++) { @@ -620,35 +672,38 @@ BOOL cli_session_setup(struct cli_state *cli, flow a bit easier to understand (tridge) */ /* if its an older server then we have to use the older request format */ - if (cli->protocol < PROTOCOL_NT1) { + + if (cli->protocol < PROTOCOL_NT1) return cli_session_setup_lanman2(cli, user, pass, passlen, workgroup); - } /* if no user is supplied then we have to do an anonymous connection. passwords are ignored */ - if (!user || !*user) { + + if (!user || !*user) return cli_session_setup_guest(cli); - } /* if the server is share level then send a plaintext null password at this point. The password is sent in the tree connect */ - if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) { + + if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) return cli_session_setup_plaintext(cli, user, "", workgroup); - } /* if the server doesn't support encryption then we have to use plaintext. The second password is ignored */ - if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) { + + if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) return cli_session_setup_plaintext(cli, user, pass, workgroup); - } + /* Indidicate signing */ + /* if the server supports extended security then use SPNEGO */ - if (cli->capabilities & CAP_EXTENDED_SECURITY) { + + if (cli->capabilities & CAP_EXTENDED_SECURITY) return cli_session_setup_spnego(cli, user, pass, workgroup); - } /* otherwise do a NT1 style session setup */ + return cli_session_setup_nt1(cli, user, pass, passlen, ntpass, ntpasslen, workgroup); @@ -738,15 +793,13 @@ BOOL cli_send_tconX(struct cli_state *cli, if (!cli_receive_smb(cli)) return False; - if (cli_is_error(cli)) { + if (cli_is_error(cli)) return False; - } clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, STR_TERMINATE|STR_ASCII); - if (strcasecmp(share,"IPC$")==0) { + if (strcasecmp(share,"IPC$")==0) fstrcpy(cli->dev, "IPC"); - } if (cli->protocol >= PROTOCOL_NT1 && smb_buflen(cli->inbuf) == 3) { @@ -786,9 +839,8 @@ void cli_negprot_send(struct cli_state *cli) char *p; int numprots; - if (cli->protocol < PROTOCOL_NT1) { + if (cli->protocol < PROTOCOL_NT1) cli->use_spnego = False; - } memset(cli->outbuf,'\0',smb_size); @@ -827,9 +879,8 @@ BOOL cli_negprot(struct cli_state *cli) return False; } - if (cli->protocol < PROTOCOL_NT1) { + if (cli->protocol < PROTOCOL_NT1) cli->use_spnego = False; - } memset(cli->outbuf,'\0',smb_size); @@ -891,12 +942,8 @@ BOOL cli_negprot(struct cli_state *cli) smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN); } - /* A way to attempt to force SMB signing */ - if (getenv("CLI_FORCE_SMB_SIGNING")) + if ((cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) cli->sign_info.negotiated_smb_signing = True; - - if (cli->sign_info.negotiated_smb_signing && !(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) - cli->sign_info.negotiated_smb_signing = False; } else if (cli->protocol >= PROTOCOL_LANMAN1) { cli->use_spnego = False; @@ -920,9 +967,8 @@ BOOL cli_negprot(struct cli_state *cli) cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE); /* a way to force ascii SMB */ - if (getenv("CLI_FORCE_ASCII")) { + if (getenv("CLI_FORCE_ASCII")) cli->capabilities &= ~CAP_UNICODE; - } return True; } @@ -938,15 +984,6 @@ BOOL cli_session_request(struct cli_state *cli, int len = 4; extern pstring user_socket_options; - /* 445 doesn't have session request */ - if (cli->port == 445) return True; - - if (cli->sign_info.use_smb_signing) { - DEBUG(0, ("Cannot send session resquest again, particularly after setting up SMB Signing\n")); - return False; - } - - /* send a session request (RFC 1002) */ memcpy(&(cli->calling), calling, sizeof(*calling)); memcpy(&(cli->called ), called , sizeof(*called )); @@ -960,6 +997,16 @@ BOOL cli_session_request(struct cli_state *cli, name_mangle(cli->calling.name, p, cli->calling.name_type); len += name_len(p); + /* 445 doesn't have session request */ + if (cli->port == 445) + return True; + + if (cli->sign_info.use_smb_signing) { + DEBUG(0, ("Cannot send session resquest again, particularly after setting up SMB Signing\n")); + return False; + } + + /* send a session request (RFC 1002) */ /* setup the packet length * Remove four bytes from the length count, since the length * field in the NBT Session Service header counts the number @@ -1066,7 +1113,8 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, cli->timeout); } - if (cli->fd != -1) cli->port = port; + if (cli->fd != -1) + cli->port = port; } if (cli->fd == -1) { DEBUG(1,("Error connecting to %s (%s)\n", @@ -1141,11 +1189,10 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, return NT_STATUS_UNSUCCESSFUL; } - if (dest_ip) { + if (dest_ip) ip = *dest_ip; - } else { + else ZERO_STRUCT(ip); - } again: @@ -1162,8 +1209,7 @@ again: char *p; DEBUG(1,("session request to %s failed (%s)\n", called.name, cli_errstr(cli))); - cli_shutdown(cli); - if ((p=strchr(called.name, '.'))) { + if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) { *p = 0; goto again; } @@ -1174,11 +1220,10 @@ again: return NT_STATUS_UNSUCCESSFUL; } - if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO) { + if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO) cli->use_spnego = False; - } else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) { + else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) cli->use_kerberos = True; - } if (!cli_negprot(cli)) { DEBUG(1,("failed negprot\n")); @@ -1261,18 +1306,22 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \ with error %s.\n", desthost, cli_errstr(cli) )); - cli_shutdown(cli); return False; } - cli_shutdown(cli); + /* + * We need to close the connection here but can't call cli_shutdown as + * will free an allocated cli struct. cli_close_connection was invented + * for this purpose. JRA. Based on work by "Kim R. Pedersen" . + */ + + cli_close_connection(cli); if (!cli_initialise(cli) || !cli_connect(cli, desthost, pdest_ip) || !cli_session_request(cli, &calling, &smbservername)) { DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \ name *SMBSERVER with error %s\n", desthost, cli_errstr(cli) )); - cli_shutdown(cli); return False; } } diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index c9500ead5d2..793dd19644f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -32,49 +32,48 @@ int cli_set_port(struct cli_state *cli, int port) } /**************************************************************************** - read an smb from a fd ignoring all keepalive packets. Note that the buffer - *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN. - The timeout is in milliseconds - - This is exactly the same as receive_smb except that it never returns - a session keepalive packet (just as receive_smb used to do). - receive_smb was changed to return keepalives as the oplock processing means this call - should never go into a blocking read. + Read an smb from a fd ignoring all keepalive packets. Note that the buffer + *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN. + The timeout is in milliseconds + + This is exactly the same as receive_smb except that it never returns + a session keepalive packet (just as receive_smb used to do). + receive_smb was changed to return keepalives as the oplock processing means this call + should never go into a blocking read. ****************************************************************************/ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) { - BOOL ret; - - for(;;) - { - ret = receive_smb(fd, buffer, timeout); - - if (!ret) - { - DEBUG(10,("client_receive_smb failed\n")); - show_msg(buffer); - return ret; - } - - /* Ignore session keepalive packets. */ - if(CVAL(buffer,0) != SMBkeepalive) - break; - } - show_msg(buffer); - return ret; -} + BOOL ret; + + for(;;) { + ret = receive_smb(fd, buffer, timeout); + if (!ret) { + DEBUG(10,("client_receive_smb failed\n")); + show_msg(buffer); + return ret; + } + + /* Ignore session keepalive packets. */ + if(CVAL(buffer,0) != SMBkeepalive) + break; + } + show_msg(buffer); + return ret; +} /**************************************************************************** -recv an smb + Recv an smb. ****************************************************************************/ + BOOL cli_receive_smb(struct cli_state *cli) { BOOL ret; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ - if (cli->fd == -1) return False; + if (cli->fd == -1) + return False; again: ret = client_receive_smb(cli->fd,cli->inbuf,cli->timeout); @@ -151,34 +150,32 @@ void cli_setup_packet(struct cli_state *cli) uint16 flags2; SCVAL(cli->outbuf,smb_flg,0x8); flags2 = FLAGS2_LONG_PATH_COMPONENTS; - if (cli->capabilities & CAP_UNICODE) { + if (cli->capabilities & CAP_UNICODE) flags2 |= FLAGS2_UNICODE_STRINGS; - } - if (cli->capabilities & CAP_STATUS32) { + if (cli->capabilities & CAP_STATUS32) flags2 |= FLAGS2_32_BIT_ERROR_CODES; - } - if (cli->use_spnego) { + if (cli->use_spnego) flags2 |= FLAGS2_EXTENDED_SECURITY; - } - if (cli->sign_info.use_smb_signing) + if (cli->sign_info.use_smb_signing + || cli->sign_info.temp_smb_signing) flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; SSVAL(cli->outbuf,smb_flg2, flags2); } } /**************************************************************************** -setup the bcc length of the packet from a pointer to the end of the data + Setup the bcc length of the packet from a pointer to the end of the data. ****************************************************************************/ + void cli_setup_bcc(struct cli_state *cli, void *p) { set_message_bcc(cli->outbuf, PTR_DIFF(p, smb_buf(cli->outbuf))); } - - /**************************************************************************** -initialise credentials of a client structure + Initialise credentials of a client structure. ****************************************************************************/ + void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) { /* copy_nt_creds(&cli->usr, usr); */ @@ -193,10 +190,10 @@ void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) cli->ntlmssp_flags,cli->ntlmssp_cli_flgs)); } - /**************************************************************************** -initialise a client structure + Initialise a client structure. ****************************************************************************/ + struct cli_state *cli_initialise(struct cli_state *cli) { BOOL alloced_cli = False; @@ -215,9 +212,8 @@ struct cli_state *cli_initialise(struct cli_state *cli) alloced_cli = True; } - if (cli->initialised) { - cli_shutdown(cli); - } + if (cli->initialised) + cli_close_connection(cli); ZERO_STRUCTP(cli); @@ -234,7 +230,9 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->outbuf = (char *)malloc(cli->bufsize); cli->inbuf = (char *)malloc(cli->bufsize); cli->oplock_handler = cli_oplock_ack; - cli->use_spnego = True; + if (lp_use_spnego()) { + cli->use_spnego = True; + } /* Set the CLI_FORCE_DOSERR environment variable to test client routines using DOS errors instead of STATUS32 @@ -243,6 +241,10 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->force_dos_errors = True; } + /* A way to attempt to force SMB signing */ + if (getenv("CLI_FORCE_SMB_SIGNING")) + cli->sign_info.negotiated_smb_signing = True; + if (!cli->outbuf || !cli->inbuf) goto error; @@ -273,43 +275,75 @@ struct cli_state *cli_initialise(struct cli_state *cli) } /**************************************************************************** -shutdown a client structure + Close a client connection and free the memory without destroying cli itself. ****************************************************************************/ -void cli_shutdown(struct cli_state *cli) + +void cli_close_connection(struct cli_state *cli) { - BOOL allocated; SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); data_blob_free(&cli->secblob); - if (cli->mem_ctx) + if (cli->mem_ctx) { talloc_destroy(cli->mem_ctx); + cli->mem_ctx = NULL; + } if (cli->fd != -1) close(cli->fd); - allocated = cli->allocated; + cli->fd = -1; +} + +/**************************************************************************** + Shutdown a client structure. +****************************************************************************/ + +void cli_shutdown(struct cli_state *cli) +{ + BOOL allocated = cli->allocated; + cli_close_connection(cli); ZERO_STRUCTP(cli); if (allocated) { free(cli); } } - /**************************************************************************** -set socket options on a open connection + Set socket options on a open connection. ****************************************************************************/ + void cli_sockopt(struct cli_state *cli, char *options) { set_socket_options(cli->fd, options); } /**************************************************************************** -set the PID to use for smb messages. Return the old pid. + Set the PID to use for smb messages. Return the old pid. ****************************************************************************/ + uint16 cli_setpid(struct cli_state *cli, uint16 pid) { uint16 ret = cli->pid; cli->pid = pid; return ret; } + +/**************************************************************************** +Send a keepalive packet to the server +****************************************************************************/ +BOOL cli_send_keepalive(struct cli_state *cli) +{ + if (cli->fd == -1) { + DEBUG(3, ("cli_send_keepalive: fd == -1\n")); + return False; + } + if (!send_keepalive(cli->fd)) { + close(cli->fd); + cli->fd = -1; + DEBUG(0,("Error sending keepalive packet to client.\n")); + return False; + } + return True; +} + diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 591c04db22d..e1507c6048e 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -156,7 +156,7 @@ void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode) /* Return a UNIX errno from a dos error class, error number tuple */ -int cli_errno_from_dos(uint8 eclass, uint32 num) +static int cli_errno_from_dos(uint8 eclass, uint32 num) { if (eclass == ERRDOS) { switch (num) { @@ -205,7 +205,7 @@ static struct { {NT_STATUS(0), 0} }; -int cli_errno_from_nt(NTSTATUS status) +static int cli_errno_from_nt(NTSTATUS status) { int i; DEBUG(10,("cli_errno_from_nt: 32 bit codes: code=%08x\n", NT_STATUS_V(status))); diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index a47c956a555..07b1ff6b6f5 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -94,7 +94,7 @@ uint32 unix_perms_to_wire(mode_t perms) ret |= ((perms & S_ISGID) ? UNIX_SET_GID : 0); #endif #ifdef S_ISUID - ret |= ((perms & S_ISVTX) ? UNIX_SET_UID : 0); + ret |= ((perms & S_ISUID) ? UNIX_SET_UID : 0); #endif return ret; } diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 685c4a25e04..e7143d065d7 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -64,6 +64,14 @@ static krb5_error_code krb5_mk_req2(krb5_context context, goto cleanup_creds; } + /* cope with the ticket being in the future due to clock skew */ + if ((unsigned)credsp->times.starttime > time(NULL)) { + time_t t = time(NULL); + int time_offset = (unsigned)credsp->times.starttime - t; + DEBUG(4,("Advancing clock by %d seconds to cope with clock skew\n", time_offset)); + krb5_set_real_time(context, t + time_offset + 1, 0); + } + in_data.length = 0; retval = krb5_mk_req_extended(context, auth_context, ap_req_options, &in_data, credsp, outbuf); @@ -86,7 +94,7 @@ cleanup_princ: /* get a kerberos5 ticket for the given service */ -DATA_BLOB krb5_get_ticket(char *principal) +DATA_BLOB krb5_get_ticket(char *principal, time_t time_offset) { krb5_error_code retval; krb5_data packet; @@ -94,7 +102,12 @@ DATA_BLOB krb5_get_ticket(char *principal) krb5_context context; krb5_auth_context auth_context = NULL; DATA_BLOB ret; - krb5_enctype enc_types[] = {ENCTYPE_DES_CBC_MD5, ENCTYPE_NULL}; + krb5_enctype enc_types[] = { +#ifdef ENCTYPE_ARCFOUR_HMAC + ENCTYPE_ARCFOUR_HMAC, +#endif + ENCTYPE_DES_CBC_MD5, + ENCTYPE_NULL}; retval = krb5_init_context(&context); if (retval) { @@ -103,6 +116,10 @@ DATA_BLOB krb5_get_ticket(char *principal) goto failed; } + if (time_offset != 0) { + krb5_set_real_time(context, time(NULL) + time_offset, 0); + } + if ((retval = krb5_cc_default(context, &ccdef))) { DEBUG(1,("krb5_cc_default failed (%s)\n", error_message(retval))); @@ -137,7 +154,7 @@ failed: #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ - DATA_BLOB krb5_get_ticket(char *principal) + DATA_BLOB krb5_get_ticket(char *principal, time_t time_offset) { DEBUG(0,("NO KERBEROS SUPPORT\n")); return data_blob(NULL, 0); diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 17a759f9e39..3eacc25380a 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -22,13 +22,13 @@ #include "includes.h" - /**************************************************************************** -interpret a long filename structure - this is mostly guesses at the moment -The length of the structure is returned -The structure of a long filename depends on the info level. 260 is used -by NT and 2 is used by OS/2 + Interpret a long filename structure - this is mostly guesses at the moment. + The length of the structure is returned + The structure of a long filename depends on the info level. 260 is used + by NT and 2 is used by OS/2 ****************************************************************************/ + static int interpret_long_filename(struct cli_state *cli, int level,char *p,file_info *finfo) { @@ -41,8 +41,7 @@ static int interpret_long_filename(struct cli_state *cli, memcpy(finfo,&def_finfo,sizeof(*finfo)); - switch (level) - { + switch (level) { case 1: /* OS/2 understands this */ /* these dates are converted to GMT by make_unix_date */ @@ -126,16 +125,16 @@ static int interpret_long_filename(struct cli_state *cli, namelen, 0); return SVAL(base, 0); } - } + } DEBUG(1,("Unknown long filename format %d\n",level)); return(SVAL(p,0)); } - /**************************************************************************** - do a directory listing, calling fn on each file found - ****************************************************************************/ + Do a directory listing, calling fn on each file found. +****************************************************************************/ + int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(file_info *, const char *, void *), void *state) { @@ -307,12 +306,11 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, return(total_received); } - - /**************************************************************************** -interpret a short filename structure -The length of the structure is returned + Interpret a short filename structure. + The length of the structure is returned. ****************************************************************************/ + static int interpret_short_filename(struct cli_state *cli, char *p,file_info *finfo) { extern file_info def_finfo; @@ -334,10 +332,11 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi /**************************************************************************** - do a directory listing, calling fn on each file found - this uses the old SMBsearch interface. It is needed for testing Samba, - but should otherwise not be used - ****************************************************************************/ + Do a directory listing, calling fn on each file found. + this uses the old SMBsearch interface. It is needed for testing Samba, + but should otherwise not be used. +****************************************************************************/ + int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(file_info *, const char *, void *), void *state) { @@ -453,16 +452,15 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, return(num_received); } - /**************************************************************************** - do a directory listing, calling fn on each file found - this auto-switches between old and new style - ****************************************************************************/ + Do a directory listing, calling fn on each file found. + This auto-switches between old and new style. +****************************************************************************/ + int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(file_info *, const char *, void *), void *state) { - if (cli->protocol <= PROTOCOL_LANMAN1) { + if (cli->protocol <= PROTOCOL_LANMAN1) return cli_list_old(cli, Mask, attribute, fn, state); - } return cli_list_new(cli, Mask, attribute, fn, state); } diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 756a6cce2f9..875df11dca4 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -127,7 +127,7 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ return total; } -#if 0 /* relies on client_recieve_smb(), now a static in libsmb/clientgen.c */ +#if 0 /* relies on client_receive_smb(), now a static in libsmb/clientgen.c */ /* This call is INCOMPATIBLE with SMB signing. If you remove the #if 0 you must fix ensure you don't attempt to sign the packets - data diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 16702c375b2..55f49c59871 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -73,13 +73,56 @@ DATA_BLOB spnego_gen_negTokenInit(uint8 guid[16], return ret; } +/* + Generate a negTokenInit as used by the client side ... It has a mechType + (OID), and a mechToken (a security blob) ... + + Really, we need to break out the NTLMSSP stuff as well, because it could be + raw in the packets! +*/ +DATA_BLOB gen_negTokenInit(const char *OID, DATA_BLOB blob) +{ + ASN1_DATA data; + DATA_BLOB ret; + + memset(&data, 0, sizeof(data)); + + asn1_push_tag(&data, ASN1_APPLICATION(0)); + asn1_write_OID(&data,OID_SPNEGO); + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_write_OID(&data, OID); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_push_tag(&data, ASN1_CONTEXT(2)); + asn1_write_OctetString(&data,blob.data,blob.length); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + + if (data.has_error) { + DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data.ofs)); + asn1_free(&data); + } + + ret = data_blob(data.data, data.length); + asn1_free(&data); + + return ret; +} /* parse a negTokenInit packet giving a GUID, a list of supported OIDs (the mechanisms) and a principal name string */ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, - uint8 guid[16], char *OIDs[ASN1_MAX_OIDS], char **principal) { @@ -89,7 +132,6 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, asn1_load(&data, blob); - asn1_read(&data, guid, 16); asn1_start_tag(&data,ASN1_APPLICATION(0)); asn1_check_OID(&data,OID_SPNEGO); asn1_start_tag(&data,ASN1_CONTEXT(0)); @@ -279,13 +321,13 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket) generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY kerberos session setup */ -DATA_BLOB spnego_gen_negTokenTarg(struct cli_state *cli, char *principal) +DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset) { DATA_BLOB tkt, tkt_wrapped, targ; const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; /* get a kerberos ticket for the service */ - tkt = krb5_get_ticket(principal); + tkt = krb5_get_ticket(principal, time_offset); /* wrap that up in a nice GSS-API wrapping */ tkt_wrapped = spnego_gen_krb5_wrap(tkt); @@ -473,8 +515,10 @@ DATA_BLOB spnego_gen_auth_response(void) U = unicode string (input is unix string) a = address (1 byte type, 1 byte length, unicode string, all inline) + A = ASCII string (pointer + length) Actually same as B B = data blob (pointer + length) b = data blob in header (pointer + length) + D d = word (4 bytes) C = constant ascii string */ @@ -502,6 +546,7 @@ BOOL msrpc_gen(DATA_BLOB *blob, s = va_arg(ap, char *); data_size += (str_charnum(s) * 2) + 4; break; + case 'A': case 'B': b = va_arg(ap, uint8 *); head_size += 8; @@ -553,7 +598,8 @@ BOOL msrpc_gen(DATA_BLOB *blob, } data_ofs += n*2; break; - + + case 'A': case 'B': b = va_arg(ap, uint8 *); n = va_arg(ap, int); @@ -688,37 +734,39 @@ BOOL msrpc_parse(DATA_BLOB *blob, void debug_ntlmssp_flags(uint32 neg_flags) { + DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags)); + if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) - DEBUG(4, (" NTLMSSP_NEGOTIATE_UNICODE\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_UNICODE\n")); if (neg_flags & NTLMSSP_NEGOTIATE_OEM) - DEBUG(4, (" NTLMSSP_NEGOTIATE_OEM\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM\n")); if (neg_flags & NTLMSSP_REQUEST_TARGET) - DEBUG(4, (" NTLMSSP_REQUEST_TARGET\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) - DEBUG(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); + DEBUGADD(4, (" NTLMSSP_REQUEST_TARGET\n")); if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) - DEBUG(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_SEAL) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) - DEBUG(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) - DEBUG(4, (" NTLMSSP_NEGOTIATE_NETWARE\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NETWARE\n")); if (neg_flags & NTLMSSP_NEGOTIATE_NTLM) - DEBUG(4, (" NTLMSSP_NEGOTIATE_NTLM\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM\n")); if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED) - DEBUG(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n")); if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED) - DEBUG(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n")); if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL) - DEBUG(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n")); if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) - DEBUG(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n")); if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) - DEBUG(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) - DEBUG(4, (" NTLMSSP_CHAL_TARGET_INFO\n")); + DEBUGADD(4, (" NTLMSSP_CHAL_TARGET_INFO\n")); if (neg_flags & NTLMSSP_NEGOTIATE_128) - DEBUG(4, (" NTLMSSP_NEGOTIATE_128\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n")); if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) - DEBUG(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n")); } diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index 34b818ee748..df02cf3718f 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -89,7 +89,7 @@ static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * new, goto failed; } - DLIST_ADD(((struct smbc_server_cache *)context->server_cache), srvcache); + DLIST_ADD((context->server_cache), srvcache); return 0; failed: @@ -139,7 +139,7 @@ static int smbc_remove_cached_server(SMBCCTX * context, SMBCSRV * server) if (server == srv->server) { /* remove this sucker */ - DLIST_REMOVE(((struct smbc_server_cache *)context->server_cache), srv); + DLIST_REMOVE(context->server_cache, srv); SAFE_FREE(srv->server_name); SAFE_FREE(srv->share_name); SAFE_FREE(srv->workgroup); diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 0ffc1c1378e..44cba611d2f 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -180,14 +180,13 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, static int smbc_errno(SMBCCTX *context, struct cli_state *c) { - int ret; - + int ret = cli_errno(c); + if (cli_is_dos_error(c)) { uint8 eclass; uint32 ecode; cli_dos_error(c, &eclass, &ecode); - ret = cli_errno_from_dos(eclass, ecode); DEBUG(3,("smbc_error %d %d (0x%x) -> %d\n", (int)eclass, (int)ecode, (int)ecode, ret)); @@ -195,10 +194,9 @@ static int smbc_errno(SMBCCTX *context, struct cli_state *c) NTSTATUS status; status = cli_nt_error(c); - ret = cli_errno_from_nt(status); DEBUG(3,("smbc errno %s -> %d\n", - get_nt_error_msg(status), ret)); + nt_errstr(status), ret)); } return ret; @@ -213,7 +211,7 @@ static int smbc_errno(SMBCCTX *context, struct cli_state *c) */ int smbc_check_server(SMBCCTX * context, SMBCSRV * server) { - if ( cli_send_keepalive(&server->cli) == False ) + if ( send_keepalive(server->cli.fd) == False ) return 1; /* connection is ok */ @@ -380,7 +378,7 @@ SMBCSRV *smbc_server(SMBCCTX *context, fstring remote_name; struct in_addr rem_ip; - if (!inet_aton(server, &rem_ip)) { + if ((rem_ip.s_addr=inet_addr(server)) == INADDR_NONE) { DEBUG(4, ("Could not convert IP address %s to struct in_addr\n", server)); errno = ENOENT; return NULL; diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index fc09d8eac2a..2252e8e59ce 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -29,24 +29,24 @@ static TDB_CONTEXT *namecache_tdb; struct nc_value { time_t expiry; /* When entry expires */ int count; /* Number of addresses */ - struct in_addr ip_list[0]; /* Address list */ + struct in_addr ip_list[1]; /* Address list */ }; /* Initialise namecache system */ -void namecache_enable(void) +BOOL namecache_enable(void) { /* Check if we have been here before, or name caching disabled by setting the name cache timeout to zero. */ if (done_namecache_init) - return; + return False; done_namecache_init = True; if (lp_name_cache_timeout() == 0) { DEBUG(5, ("namecache_init: disabling netbios name cache\n")); - return; + return False; } /* Open namecache tdb in read/write or readonly mode */ @@ -58,13 +58,15 @@ void namecache_enable(void) if (!namecache_tdb) { DEBUG(5, ("namecache_init: could not open %s\n", lock_path("namecache.tdb"))); - return; + return False; } DEBUG(5, ("namecache_init: enabling netbios namecache, timeout %d " "seconds\n", lp_name_cache_timeout())); enable_namecache = True; + + return True; } /* Return a key for a name and name type. The caller must free @@ -91,17 +93,20 @@ static TDB_DATA namecache_value(struct in_addr *ip_list, int num_names, { TDB_DATA retval; struct nc_value *value; - int size; + int size = sizeof(struct nc_value); - size = sizeof(struct nc_value) + sizeof(struct in_addr) * - num_names; + if (num_names > 0) + size += sizeof(struct in_addr) * (num_names-1); value = (struct nc_value *)malloc(size); - + + memset(value, 0, size); + value->expiry = expiry; value->count = num_names; - memcpy(value->ip_list, ip_list, num_names * sizeof(struct in_addr)); + if (ip_list) + memcpy(value->ip_list, ip_list, sizeof(struct in_addr) * num_names); retval.dptr = (char *)value; retval.dsize = size; @@ -160,6 +165,9 @@ BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list, time_t now; int i; + *ip_list = NULL; + *num_names = 0; + if (!enable_namecache) return False; @@ -209,20 +217,23 @@ BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list, /* Extract and return namelist */ - *ip_list = (struct in_addr *)malloc( - sizeof(struct in_addr) * data->count); - - memcpy(*ip_list, data->ip_list, sizeof(struct in_addr) * - data->count); + DEBUG(5, ("namecache_fetch: returning %d address%s for %s#%02x: ", + data->count, data->count == 1 ? "" : "es", name, name_type)); - *num_names = data->count; + if (data->count) { - DEBUG(5, ("namecache_fetch: returning %d address%s for %s#%02x: ", - *num_names, *num_names == 1 ? "" : "es", name, name_type)); + *ip_list = (struct in_addr *)malloc( + sizeof(struct in_addr) * data->count); + + memcpy(*ip_list, data->ip_list, sizeof(struct in_addr) * data->count); + + *num_names = data->count; + + for (i = 0; i < *num_names; i++) + DEBUGADD(5, ("%s%s", inet_ntoa((*ip_list)[i]), + i == (*num_names - 1) ? "" : ", ")); - for (i = 0; i < *num_names; i++) - DEBUGADD(5, ("%s%s", inet_ntoa((*ip_list)[i]), - i == (*num_names - 1) ? "" : ", ")); + } DEBUGADD(5, ("\n")); diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index e2da6318e1d..02fd53fc056 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -28,7 +28,7 @@ typedef const struct NTSTATUS nt_errcode; } nt_err_code_struct; -nt_err_code_struct nt_errs[] = +static nt_err_code_struct nt_errs[] = { { "NT_STATUS_OK", NT_STATUS_OK }, { "NT_STATUS_UNSUCCESSFUL", NT_STATUS_UNSUCCESSFUL }, diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index dfa355a7ec6..db265c4bf7c 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -116,39 +116,63 @@ void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16]) } /* Does both the NTLMv2 owfs of a user's password */ -void ntv2_owf_gen(const uchar owf[16], - const char *user_n, const char *domain_n, uchar kr_buf[16]) +BOOL ntv2_owf_gen(const uchar owf[16], + const char *user_in, const char *domain_in, uchar kr_buf[16]) { - pstring user_u; - pstring dom_u; + smb_ucs2_t *user; + smb_ucs2_t *domain; + + int user_byte_len; + int domain_byte_len; + HMACMD5Context ctx; - int user_l = strlen(user_n); - int domain_l = strlen(domain_n); + user_byte_len = push_ucs2_allocate(&user, user_in); + if (user_byte_len < 0) { + DEBUG(0, ("push_uss2_allocate() for user returned %d (probably malloc() failure)\n", user_byte_len)); + return False; + } - push_ucs2(NULL, user_u, user_n, (user_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); - push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); + domain_byte_len = push_ucs2_allocate(&domain, domain_in); + if (domain_byte_len < 0) { + DEBUG(0, ("push_uss2_allocate() for domain returned %d (probably malloc() failure)\n", user_byte_len)); + return False; + } + + strupper_w(user); + strupper_w(domain); + + /* We don't want null termination */ + user_byte_len = user_byte_len - 2; + domain_byte_len = domain_byte_len - 2; + + SMB_ASSERT(user_byte_len >= 0); + SMB_ASSERT(domain_byte_len >= 0); hmac_md5_init_limK_to_64(owf, 16, &ctx); - hmac_md5_update((const unsigned char *)user_u, user_l * 2, &ctx); - hmac_md5_update((const unsigned char *)dom_u, domain_l * 2, &ctx); + hmac_md5_update((const unsigned char *)user, user_byte_len, &ctx); + hmac_md5_update((const unsigned char *)domain, domain_byte_len, &ctx); hmac_md5_final(kr_buf, &ctx); #ifdef DEBUG_PASSWORD DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n")); - dump_data(100, user_u, user_l * 2); - dump_data(100, dom_u, domain_l * 2); + dump_data(100, (const char *)user, user_byte_len); + dump_data(100, (const char *)domain, domain_byte_len); dump_data(100, owf, 16); dump_data(100, kr_buf, 16); #endif + + SAFE_FREE(user); + SAFE_FREE(domain); + return True; } /* Does the des encryption from the NT or LM MD4 hash. */ void SMBOWFencrypt(const uchar passwd[16], const uchar *c8, uchar p24[24]) { uchar p21[21]; - - memset(p21,'\0',21); + + ZERO_STRUCT(p21); memcpy(p21, passwd, 16); E_P24(p21, c8, p24); @@ -362,6 +386,12 @@ void cli_caclulate_sign_mac(struct cli_state *cli) unsigned char calc_md5_mac[16]; struct MD5Context md5_ctx; + if (cli->sign_info.temp_smb_signing) { + memcpy(&cli->outbuf[smb_ss_field], "SignRequest", 8); + cli->sign_info.temp_smb_signing = False; + return; + } + if (!cli->sign_info.use_smb_signing) { return; } @@ -380,6 +410,8 @@ void cli_caclulate_sign_mac(struct cli_state *cli) MD5Final(calc_md5_mac, &md5_ctx); memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8); +/* cli->outbuf[smb_ss_field+2]=0; + Uncomment this to test if the remote server actually verifies signitures...*/ cli->sign_info.send_seq_num++; cli->sign_info.reply_seq_num = cli->sign_info.send_seq_num; cli->sign_info.send_seq_num++; diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c index fe6b673e39e..4d7acd19888 100644 --- a/source3/libsmb/trust_passwd.c +++ b/source3/libsmb/trust_passwd.c @@ -35,8 +35,9 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ unsigned char new_trust_passwd_hash[16]) { NTSTATUS result; - result = cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? - SEC_CHAN_WKSTA : SEC_CHAN_BDC, orig_trust_passwd_hash); + uint32 neg_flags = 0x000001ff; + + result = cli_nt_setup_creds(cli, get_sec_chan(), orig_trust_passwd_hash, &neg_flags, 2); if (!NT_STATUS_IS_OK(result)) { DEBUG(1,("just_change_the_password: unable to setup creds (%s)!\n", diff --git a/source3/locking/locking.c b/source3/locking/locking.c index d42d041b790..3eb7ca47832 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -142,7 +142,7 @@ static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_p } /**************************************************************************** - Utility function called by locking requests. This is *DISGISTING*. It also + Utility function called by locking requests. This is *DISGUSTING*. It also appears to be "What Windows Does" (tm). Andrew, ever wonder why Windows 2000 is so slow on the locking tests...... ? This is the reason. Much though I hate it, we need this. JRA. diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c index d6605d08f56..b65cebe2035 100644 --- a/source3/nmbd/nmbd_processlogon.c +++ b/source3/nmbd/nmbd_processlogon.c @@ -334,7 +334,8 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", /* Push domain components */ dc = domain; q1 = q; - while ((component = strsep(&dc, "."))) { + while ((component = strtok(dc, "."))) { + dc = NULL; size = push_ascii(&q[1], component, -1, 0); SCVAL(q, 0, size); q += (size + 1); diff --git a/source3/nmbd/nmbd_synclists.c b/source3/nmbd/nmbd_synclists.c index bf03d4d1cf2..24adf4e69f2 100644 --- a/source3/nmbd/nmbd_synclists.c +++ b/source3/nmbd/nmbd_synclists.c @@ -70,7 +70,11 @@ static void sync_child(char *name, int nm_type, uint32 local_type = local ? SV_TYPE_LOCAL_LIST_ONLY : 0; struct nmb_name called, calling; - if (!cli_initialise(&cli) || !cli_connect(&cli, name, &ip)) { + /* W2K DMB's return empty browse lists on port 445. Use 139. + * Patch from Andy Levine andyl@epicrealm.com. + */ + + if (!cli_initialise(&cli) || !cli_set_port(&cli, 139) || !cli_connect(&cli, name, &ip)) { return; } diff --git a/source3/nsswitch/pam_winbind.c b/source3/nsswitch/pam_winbind.c index 29ceca4e79e..f95caefb4cd 100644 --- a/source3/nsswitch/pam_winbind.c +++ b/source3/nsswitch/pam_winbind.c @@ -11,11 +11,6 @@ #include "pam_winbind.h" -/* prototypes from common.c */ -void init_request(struct winbindd_request *req,int rq_type); -int write_sock(void *buffer, int count); -int read_reply(struct winbindd_response *response); - /* data tokens */ #define MAX_PASSWD_TRIES 3 @@ -99,24 +94,30 @@ static int _make_remark(pam_handle_t * pamh, int type, const char *text) return retval; } -static int winbind_request(enum winbindd_cmd req_type, - struct winbindd_request *request, - struct winbindd_response *response) +static int pam_winbind_request(enum winbindd_cmd req_type, + struct winbindd_request *request, + struct winbindd_response *response) { + /* Fill in request and send down pipe */ init_request(request, req_type); if (write_sock(request, sizeof(*request)) == -1) { _pam_log(LOG_ERR, "write to socket failed!"); + close_sock(); return PAM_SERVICE_ERR; } /* Wait for reply */ if (read_reply(response) == -1) { _pam_log(LOG_ERR, "read from socket failed!"); + close_sock(); return PAM_SERVICE_ERR; } + /* We are done with the socket - close it and avoid mischeif */ + close_sock(); + /* Copy reply data from socket */ if (response->result != WINBINDD_OK) { if (response->data.auth.pam_error != PAM_SUCCESS) { @@ -148,7 +149,7 @@ static int winbind_auth_request(const char *user, const char *pass, int ctrl) strncpy(request.data.auth.pass, pass, sizeof(request.data.auth.pass)-1); - retval = winbind_request(WINBINDD_PAM_AUTH, &request, &response); + retval = pam_winbind_request(WINBINDD_PAM_AUTH, &request, &response); switch (retval) { case PAM_AUTH_ERR: @@ -217,7 +218,7 @@ static int winbind_chauthtok_request(const char *user, const char *oldpass, request.data.chauthtok.newpass[0] = '\0'; } - return winbind_request(WINBINDD_PAM_CHAUTHTOK, &request, &response); + return pam_winbind_request(WINBINDD_PAM_CHAUTHTOK, &request, &response); } /* diff --git a/source3/nsswitch/pam_winbind.h b/source3/nsswitch/pam_winbind.h index 9897249e164..fae635d8067 100644 --- a/source3/nsswitch/pam_winbind.h +++ b/source3/nsswitch/pam_winbind.h @@ -90,5 +90,4 @@ do { \ #define on(x, y) (x & y) #define off(x, y) (!(x & y)) -#include "winbind_nss_config.h" -#include "winbindd_nss.h" +#include "winbind_client.h" diff --git a/source3/nsswitch/wb_common.c b/source3/nsswitch/wb_common.c index 9bc9faafb50..51792f63fe2 100644 --- a/source3/nsswitch/wb_common.c +++ b/source3/nsswitch/wb_common.c @@ -5,6 +5,8 @@ Copyright (C) Tim Potter 2000 Copyright (C) Andrew Tridgell 2000 + Copyright (C) Andrew Bartlett 2002 + This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -75,7 +77,7 @@ void init_response(struct winbindd_response *response) /* Close established socket */ -static void close_sock(void) +void close_sock(void) { if (winbindd_fd != -1) { close(winbindd_fd); @@ -83,14 +85,75 @@ static void close_sock(void) } } +/* Make sure socket handle isn't stdin, stdout or stderr */ +#define RECURSION_LIMIT 3 + +static int make_nonstd_fd_internals(int fd, int limit /* Recursion limiter */) +{ + int new_fd; + if (fd >= 0 && fd <= 2) { +#ifdef F_DUPFD + if ((new_fd = fcntl(fd, F_DUPFD, 3)) == -1) { + return -1; + } + /* Parinoia */ + if (new_fd < 3) { + close(new_fd); + return -1; + } + close(fd); + return new_fd; +#else + if (limit <= 0) + return -1; + + new_fd = dup(fd); + if (new_fd == -1) + return -1; + + /* use the program stack to hold our list of FDs to close */ + new_fd = make_nonstd_fd_internals(new_fd, limit - 1); + close(fd); + return new_fd; +#endif + } + return fd; +} + +static int make_safe_fd(int fd) +{ + int result, flags; + int new_fd = make_nonstd_fd_internals(fd, RECURSION_LIMIT); + if (new_fd == -1) { + close(fd); + return -1; + } + /* Socket should be closed on exec() */ + +#ifdef FD_CLOEXEC + result = flags = fcntl(new_fd, F_GETFD, 0); + if (flags >= 0) { + flags |= FD_CLOEXEC; + result = fcntl( new_fd, F_SETFD, flags ); + } + if (result < 0) { + close(new_fd); + return -1; + } +#endif + return new_fd; +} + /* Connect to winbindd socket */ int winbind_open_pipe_sock(void) { +#ifdef HAVE_UNIXSOCKET struct sockaddr_un sunaddr; static pid_t our_pid; struct stat st; pstring path; + int fd; if (our_pid != getpid()) { close_sock(); @@ -144,9 +207,13 @@ int winbind_open_pipe_sock(void) /* Connect to socket */ - if ((winbindd_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { return -1; } + + if ((winbindd_fd = make_safe_fd( fd)) == -1) { + return winbindd_fd; + } if (connect(winbindd_fd, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) { @@ -155,6 +222,9 @@ int winbind_open_pipe_sock(void) } return winbindd_fd; +#else + return -1; +#endif /* HAVE_UNIXSOCKET */ } /* Write data to winbindd socket */ @@ -366,8 +436,8 @@ NSS_STATUS winbindd_get_response(struct winbindd_response *response) /* Handle simple types of requests */ NSS_STATUS winbindd_request(int req_type, - struct winbindd_request *request, - struct winbindd_response *response) + struct winbindd_request *request, + struct winbindd_response *response) { NSS_STATUS status; diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c index 4d36acc51b3..875df231dca 100644 --- a/source3/nsswitch/wbinfo.c +++ b/source3/nsswitch/wbinfo.c @@ -28,11 +28,7 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND -/* Prototypes from common.h */ - -NSS_STATUS winbindd_request(int req_type, - struct winbindd_request *request, - struct winbindd_response *response); +extern int winbindd_fd; static char winbind_separator(void) { @@ -450,9 +446,10 @@ static BOOL wbinfo_auth(char *username) d_printf("plaintext password authentication %s\n", (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed"); - d_printf("error code was %s (0x%x)\n", - response.data.auth.nt_status_string, - response.data.auth.nt_status); + if (response.data.auth.nt_status) + d_printf("error code was %s (0x%x)\n", + response.data.auth.nt_status_string, + response.data.auth.nt_status); return result == NSS_STATUS_SUCCESS; } @@ -504,9 +501,10 @@ static BOOL wbinfo_auth_crap(char *username) d_printf("challenge/response password authentication %s\n", (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed"); - d_printf("error code was %s (0x%x)\n", - response.data.auth.nt_status_string, - response.data.auth.nt_status); + if (response.data.auth.nt_status) + d_printf("error code was %s (0x%x)\n", + response.data.auth.nt_status_string, + response.data.auth.nt_status); return result == NSS_STATUS_SUCCESS; } @@ -608,43 +606,17 @@ static BOOL wbinfo_set_auth_user(char *username) static BOOL wbinfo_ping(void) { NSS_STATUS result; - + result = winbindd_request(WINBINDD_PING, NULL, NULL); /* Display response */ - d_printf("'ping' to winbindd %s\n", - (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed"); + d_printf("'ping' to winbindd %s on fd %d\n", + (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed", winbindd_fd); return result == NSS_STATUS_SUCCESS; } -/* Print program usage */ - -static void usage(void) -{ - d_printf("Usage: wbinfo -ug | -n name | -sSY sid | -UG uid/gid | -tm " - "| -[aA] user%%password\n"); - d_printf("\t-u\t\t\tlists all domain users\n"); - d_printf("\t-g\t\t\tlists all domain groups\n"); - d_printf("\t-n name\t\t\tconverts name to sid\n"); - d_printf("\t-s sid\t\t\tconverts sid to name\n"); - d_printf("\t-N name\t\t\tconverts NetBIOS name to IP (WINS)\n"); - d_printf("\t-I name\t\t\tconverts IP address to NetBIOS name (WINS)\n"); - d_printf("\t-U uid\t\t\tconverts uid to sid\n"); - d_printf("\t-G gid\t\t\tconverts gid to sid\n"); - d_printf("\t-S sid\t\t\tconverts sid to uid\n"); - d_printf("\t-Y sid\t\t\tconverts sid to gid\n"); - d_printf("\t-t\t\t\tcheck shared secret\n"); - d_printf("\t-m\t\t\tlist trusted domains\n"); - d_printf("\t-r user\t\t\tget user groups\n"); - d_printf("\t-a user%%password\tauthenticate user\n"); - d_printf("\t-A user%%password\tstore user and password used by winbindd (root only)\n"); - d_printf("\t-p\t\t\t'ping' winbindd to see if it is alive\n"); - d_printf("\t--sequence\t\tshow sequence numbers of all domains\n"); - d_printf("\t--set-auth-user DOMAIN\\user%%password\tset password for restrict anonymous\n"); -} - /* Main program */ enum { @@ -664,28 +636,28 @@ int main(int argc, char **argv) int result = 1; struct poptOption long_options[] = { + POPT_AUTOHELP /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ - { "help", 'h', POPT_ARG_NONE, 0, 'h' }, - { "domain-users", 'u', POPT_ARG_NONE, 0, 'u' }, - { "domain-groups", 'g', POPT_ARG_NONE, 0, 'g' }, - { "WINS-by-name", 'N', POPT_ARG_STRING, &string_arg, 'N' }, - { "WINS-by-ip", 'I', POPT_ARG_STRING, &string_arg, 'I' }, - { "name-to-sid", 'n', POPT_ARG_STRING, &string_arg, 'n' }, - { "sid-to-name", 's', POPT_ARG_STRING, &string_arg, 's' }, - { "uid-to-sid", 'U', POPT_ARG_INT, &int_arg, 'U' }, - { "gid-to-sid", 'G', POPT_ARG_INT, &int_arg, 'G' }, - { "sid-to-uid", 'S', POPT_ARG_STRING, &string_arg, 'S' }, - { "sid-to-gid", 'Y', POPT_ARG_STRING, &string_arg, 'Y' }, - { "check-secret", 't', POPT_ARG_NONE, 0, 't' }, - { "trusted-domains", 'm', POPT_ARG_NONE, 0, 'm' }, - { "sequence", 0, POPT_ARG_NONE, 0, OPT_SEQUENCE }, - { "user-groups", 'r', POPT_ARG_STRING, &string_arg, 'r' }, - { "authenticate", 'a', POPT_ARG_STRING, &string_arg, 'a' }, - { "set-auth-user", 'A', POPT_ARG_STRING, &string_arg, OPT_SET_AUTH_USER }, - { "ping", 'p', POPT_ARG_NONE, 0, 'p' }, + { "domain-users", 'u', POPT_ARG_NONE, 0, 'u', "Lists all domain users"}, + { "domain-groups", 'g', POPT_ARG_NONE, 0, 'g', "Lists all domain groups" }, + { "WINS-by-name", 'N', POPT_ARG_STRING, &string_arg, 'N', "Converts NetBIOS name to IP (WINS)" }, + { "WINS-by-ip", 'I', POPT_ARG_STRING, &string_arg, 'I', "Converts IP address to NetBIOS name (WINS)" }, + { "name-to-sid", 'n', POPT_ARG_STRING, &string_arg, 'n', "Converts name to sid" }, + { "sid-to-name", 's', POPT_ARG_STRING, &string_arg, 's', "Converts sid to name" }, + { "uid-to-sid", 'U', POPT_ARG_INT, &int_arg, 'U', "Converts uid to sid" }, + { "gid-to-sid", 'G', POPT_ARG_INT, &int_arg, 'G', "Converts gid to sid" }, + { "sid-to-uid", 'S', POPT_ARG_STRING, &string_arg, 'S', "Converts sid to uid" }, + { "sid-to-gid", 'Y', POPT_ARG_STRING, &string_arg, 'Y', "Converts sid to gid" }, + { "check-secret", 't', POPT_ARG_NONE, 0, 't', "Check shared secret" }, + { "trusted-domains", 'm', POPT_ARG_NONE, 0, 'm', "List trusted domains" }, + { "sequence", 0, POPT_ARG_NONE, 0, OPT_SEQUENCE, "show sequence numbers of all domains" }, + { "user-groups", 'r', POPT_ARG_STRING, &string_arg, 'r', "Get user groups" }, + { "authenticate", 'a', POPT_ARG_STRING, &string_arg, 'a', "authenticate user", "user%password" }, + { "set-auth-user", 'A', POPT_ARG_STRING, &string_arg, OPT_SET_AUTH_USER, "Store user and password used by winbindd (root only)", "user%password" }, + { "ping", 'p', POPT_ARG_NONE, 0, 'p', "'ping' winbindd to see if it is alive" }, { 0, 0, 0, 0 } }; @@ -708,17 +680,17 @@ int main(int argc, char **argv) load_interfaces(); + /* Parse options */ + + pc = poptGetContext("wbinfo", argc, (const char **)argv, long_options, 0); + /* Parse command line options */ if (argc == 1) { - usage(); + poptPrintHelp(pc, stderr, 0); return 1; } - /* Parse options */ - - pc = poptGetContext("wbinfo", argc, (const char **)argv, long_options, 0); - while((opt = poptGetNextOpt(pc)) != -1) { if (got_command) { d_fprintf(stderr, "No more than one command may be specified at once.\n"); @@ -734,10 +706,6 @@ int main(int argc, char **argv) while((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { - case 'h': - usage(); - result = 0; - goto done; case 'u': if (!print_domain_users()) { d_printf("Error looking up domain users\n"); @@ -859,7 +827,7 @@ int main(int argc, char **argv) break; default: d_fprintf(stderr, "Invalid option\n"); - usage(); + poptPrintHelp(pc, stderr, 0); goto done; } } diff --git a/source3/nsswitch/winbind_nss.c b/source3/nsswitch/winbind_nss.c index 594b5fbadb2..0b4c0ce1d08 100644 --- a/source3/nsswitch/winbind_nss.c +++ b/source3/nsswitch/winbind_nss.c @@ -21,8 +21,7 @@ Boston, MA 02111-1307, USA. */ -#include "winbind_nss_config.h" -#include "winbindd_nss.h" +#include "winbind_client.h" #ifdef HAVE_NS_API_H #undef VOLATILE @@ -37,17 +36,6 @@ extern int winbindd_fd; -void init_request(struct winbindd_request *req,int rq_type); -NSS_STATUS winbindd_send_request(int req_type, - struct winbindd_request *request); -NSS_STATUS winbindd_get_response(struct winbindd_response *response); -NSS_STATUS winbindd_request(int req_type, - struct winbindd_request *request, - struct winbindd_response *response); -int winbind_open_pipe_sock(void); -int write_sock(void *buffer, int count); -int read_reply(struct winbindd_response *response); -void free_response(struct winbindd_response *response); #ifdef HAVE_NS_API_H /* IRIX version */ diff --git a/source3/nsswitch/winbind_nss_config.h b/source3/nsswitch/winbind_nss_config.h index b9c738211e1..d9a9b8aaaef 100644 --- a/source3/nsswitch/winbind_nss_config.h +++ b/source3/nsswitch/winbind_nss_config.h @@ -38,6 +38,10 @@ #include #endif +#ifdef HAVE_SYS_SELECT_H +#include +#endif + #ifdef HAVE_SYS_SOCKET_H #include #endif @@ -58,6 +62,14 @@ #include #endif +#ifdef HAVE_FCNTL_H +#include +#else +#ifdef HAVE_SYS_FCNTL_H +#include +#endif +#endif + #include #include #include diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c index 256c0203c0e..bb4a1b78ec5 100644 --- a/source3/nsswitch/winbindd.c +++ b/source3/nsswitch/winbindd.c @@ -628,8 +628,8 @@ static void process_loop(int accept_sock) if (state->read_buf_len >= sizeof(uint32) && *(uint32 *) &state->request != sizeof(state->request)) { - DEBUG(0,("process_loop: Invalid request size (%d) send, should be (%d)\n", - *(uint32 *) &state->request, sizeof(state->request))); + DEBUG(0,("process_loop: Invalid request size from pid %d: %d bytes sent, should be %d\n", + state->request.pid, *(uint32 *) &state->request, sizeof(state->request))); remove_client(state); break; @@ -858,6 +858,7 @@ static void usage(void) pidfile_create("winbindd"); } + #if HAVE_SETPGID /* * If we're interactive we want to set our own process group for diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c index b0b70178a45..4f91ed0f20c 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -143,7 +143,7 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain) /* if we get ECONNREFUSED then it might be a NT4 server, fall back to MSRPC */ if (status.error_type == ADS_ERROR_SYSTEM && - status.rc == ECONNREFUSED) { + status.err.rc == ECONNREFUSED) { DEBUG(1,("Trying MSRPC methods\n")); domain->methods = &msrpc_methods; } @@ -170,9 +170,9 @@ static void sid_from_rid(struct winbindd_domain *domain, uint32 rid, DOM_SID *si static enum SID_NAME_USE ads_atype_map(uint32 atype) { switch (atype & 0xF0000000) { - case ATYPE_GROUP: + case ATYPE_GLOBAL_GROUP: return SID_NAME_DOM_GRP; - case ATYPE_USER: + case ATYPE_ACCOUNT: return SID_NAME_USER; default: DEBUG(1,("hmm, need to map account type 0x%x\n", atype)); @@ -339,7 +339,7 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain, if (!ads_pull_uint32(ads, msg, "sAMAccountType", &account_type) || - !(account_type & ATYPE_GROUP)) continue; + !(account_type & ATYPE_GLOBAL_GROUP)) continue; name = pull_username(ads, mem_ctx, msg); gecos = ads_pull_string(ads, mem_ctx, msg, "name"); diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c index 2dec9f05586..01f55698893 100644 --- a/source3/nsswitch/winbindd_cm.c +++ b/source3/nsswitch/winbindd_cm.c @@ -109,7 +109,7 @@ static BOOL cm_ads_find_dc(const char *domain, struct in_addr *dc_ip, fstring sr } /* we don't need to bind, just connect */ - ads->auth.no_bind = 1; + ads->auth.flags |= ADS_AUTH_NO_BIND; DEBUG(4,("cm_ads_find_dc: domain=%s\n", domain)); @@ -145,11 +145,16 @@ static BOOL cm_rpc_find_dc(const char *domain, struct in_addr *dc_ip, fstring sr /* Lookup domain controller name. Try the real PDC first to avoid SAM sync delays */ - if (!get_dc_list(True, domain, &ip_list, &count)) { - if (!get_dc_list(False, domain, &ip_list, &count)) { - DEBUG(3, ("Could not look up dc's for domain %s\n", domain)); - return False; - } + if (get_dc_list(True, domain, &ip_list, &count) && + name_status_find(domain, 0x1c, 0x20, ip_list[0], srv_name)) { + *dc_ip = ip_list[0]; + SAFE_FREE(ip_list); + return True; + } + + if (!get_dc_list(False, domain, &ip_list, &count)) { + DEBUG(3, ("Could not look up dc's for domain %s\n", domain)); + return False; } /* Pick a nice close server */ @@ -377,16 +382,6 @@ static NTSTATUS cm_open_connection(const char *domain,const char *pipe_name, fstrcpy(new_conn->domain, domain); fstrcpy(new_conn->pipe_name, pipe_name); - /* Look for a domain controller for this domain. Negative results - are cached so don't bother applying the caching for this - function just yet. */ - - if (!cm_get_dc_name(domain, new_conn->controller, &dc_ip)) { - result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; - add_failed_connection_entry(new_conn, result); - return result; - } - /* Return false if we have tried to look up this domain and netbios name before and failed. */ @@ -418,6 +413,16 @@ static NTSTATUS cm_open_connection(const char *domain,const char *pipe_name, return result; } + /* Look for a domain controller for this domain. Negative results + are cached so don't bother applying the caching for this + function just yet. */ + + if (!cm_get_dc_name(domain, new_conn->controller, &dc_ip)) { + result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; + add_failed_connection_entry(new_conn, result); + return result; + } + /* Initialise SMB connection */ cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password); @@ -859,6 +864,7 @@ NTSTATUS cm_get_netlogon_cli(char *domain, unsigned char *trust_passwd, { NTSTATUS result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; struct winbindd_cm_conn *conn; + uint32 neg_flags = 0x000001ff; if (!cli) { return NT_STATUS_INVALID_PARAMETER; @@ -870,8 +876,7 @@ NTSTATUS cm_get_netlogon_cli(char *domain, unsigned char *trust_passwd, return result; } - result = cli_nt_setup_creds(conn->cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? - SEC_CHAN_WKSTA : SEC_CHAN_BDC, trust_passwd); + result = cli_nt_setup_creds(conn->cli, get_sec_chan(), trust_passwd, &neg_flags, 2); if (!NT_STATUS_IS_OK(result)) { DEBUG(0, ("error connecting to domain password server: %s\n", @@ -884,8 +889,7 @@ NTSTATUS cm_get_netlogon_cli(char *domain, unsigned char *trust_passwd, } /* Try again */ - result = cli_nt_setup_creds(conn->cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? - SEC_CHAN_WKSTA : SEC_CHAN_BDC, trust_passwd); + result = cli_nt_setup_creds( conn->cli, get_sec_chan(),trust_passwd, &neg_flags, 2); } if (!NT_STATUS_IS_OK(result)) { diff --git a/source3/nsswitch/winbindd_nss.h b/source3/nsswitch/winbindd_nss.h index 9eea94e7c0d..368bf10cea5 100644 --- a/source3/nsswitch/winbindd_nss.h +++ b/source3/nsswitch/winbindd_nss.h @@ -127,6 +127,9 @@ struct winbindd_request { uid_t uid; /* getpwuid, uid_to_sid */ gid_t gid; /* getgrgid, gid_to_sid */ struct { + /* We deliberatedly don't split into domain/user to + avoid having the client know what the separator + character is. */ fstring user; fstring pass; } auth; /* pam_winbind auth module */ diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index a8b508a49c6..3e7a8ad9713 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -147,7 +147,7 @@ done: fstrcpy(state->response.data.auth.error_string, nt_errstr(result)); state->response.data.auth.pam_error = nt_status_to_pam(result); - DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Plain-text authenticaion for user %s returned %s (PAM: %d)\n", + DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Plain-text authentication for user %s returned %s (PAM: %d)\n", state->request.data.auth.user, state->response.data.auth.nt_status_string, state->response.data.auth.pam_error)); @@ -183,7 +183,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) /* Ensure null termination */ state->request.data.auth_crap.domain[sizeof(state->request.data.auth_crap.domain)-1]='\0'; - if (!(mem_ctx = talloc_init_named("winbind pam auth crap for (utf8) %s", state->request.data.auth.user))) { + if (!(mem_ctx = talloc_init_named("winbind pam auth crap for (utf8) %s", state->request.data.auth_crap.user))) { DEBUG(0, ("winbindd_pam_auth_crap: could not talloc_init()!\n")); result = NT_STATUS_NO_MEMORY; goto done; @@ -292,7 +292,7 @@ done: state->response.data.auth.pam_error = nt_status_to_pam(result); DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, - ("NTLM CRAP authenticaion for user [%s]\\[%s] returned %s (PAM: %d)\n", + ("NTLM CRAP authentication for user [%s]\\[%s] returned %s (PAM: %d)\n", domain, user, state->response.data.auth.nt_status_string, diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c index 5ec34f663d8..047280e21e4 100644 --- a/source3/nsswitch/winbindd_rpc.c +++ b/source3/nsswitch/winbindd_rpc.c @@ -315,6 +315,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain, cli_samr_close(hnd->cli, mem_ctx, &user_pol); got_user_pol = False; + user_info->user_rid = user_rid; user_info->group_rid = ctr->info.id21->group_rid; user_info->acct_name = unistr2_tdup(mem_ctx, &ctr->info.id21->uni_user_name); @@ -419,7 +420,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; BOOL got_dom_pol = False, got_group_pol = False; - DEBUG(3,("rpc: lookup_groupmem rid=%u\n", group_rid)); + DEBUG(10,("rpc: lookup_groupmem %s rid=%u\n", domain->name, group_rid)); *num_names = 0; @@ -523,7 +524,7 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq) BOOL got_dom_pol = False; uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; - DEBUG(3,("rpc: sequence_number\n")); + DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name)); *seq = DOM_SEQUENCE_NONE; diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c index daa3abb3400..2016c27881d 100644 --- a/source3/nsswitch/winbindd_util.c +++ b/source3/nsswitch/winbindd_util.c @@ -83,10 +83,16 @@ 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 (strcmp(domain_name, domain->name) == 0 || - strcmp(domain_name, domain->alt_name) == 0) { + if (strcasecmp(domain_name, domain->name) == 0 || + strcasecmp(domain_name, domain->alt_name) == 0) { return domain; } + if (alt_name && *alt_name) { + if (strcasecmp(alt_name, domain->name) == 0 || + strcasecmp(alt_name, domain->alt_name) == 0) { + return domain; + } + } } /* Create new domain entry */ diff --git a/source3/pam_smbpass/pam_smb_passwd.c b/source3/pam_smbpass/pam_smb_passwd.c index 0f527552525..91eae3c7a19 100644 --- a/source3/pam_smbpass/pam_smb_passwd.c +++ b/source3/pam_smbpass/pam_smb_passwd.c @@ -96,6 +96,8 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, char *pass_old; char *pass_new; + NTSTATUS nt_status; + /* Samba initialization. */ setup_logging( "pam_smbpass", False ); in_client = True; @@ -124,10 +126,11 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, } /* obtain user record */ - pdb_init_sam(&sampass); - pdb_getsampwnam(sampass,user); + if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sampass))) { + return nt_status_to_pam(nt_status); + } - if (sampass == NULL) { + if (!pdb_getsampwnam(sampass,user)) { _log_err( LOG_ALERT, "Failed to find entry for user %s.", user ); return PAM_USER_UNKNOWN; } diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index b16f4483f84..c4844398370 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -112,6 +112,7 @@ typedef struct char *szSMBPasswdFile; char *szPrivateDir; char **szPassdbBackend; + char **szSamBackend; char *szPasswordServer; char *szSocketOptions; char *szWorkGroup; @@ -139,6 +140,7 @@ typedef struct char *szDelGroupScript; char *szAddUserToGroupScript; char *szDelUserFromGroupScript; + char *szSetPrimaryGroupScript; char *szAddMachineScript; char *szShutdownScript; char *szAbortShutdownScript; @@ -171,7 +173,6 @@ typedef struct int max_xmit; int max_mux; int max_open_files; - int max_packet; int pwordlevel; int unamelevel; int deadtime; @@ -206,11 +207,11 @@ typedef struct int iLockSpinTime; char *szLdapMachineSuffix; char *szLdapUserSuffix; - int ldap_port; int ldap_ssl; char *szLdapSuffix; char *szLdapFilter; char *szLdapAdminDn; + int ldap_passwd_sync; BOOL bMsAddPrinterWizard; BOOL bDNSproxy; BOOL bWINSsupport; @@ -231,7 +232,6 @@ typedef struct BOOL bReadPrediction; BOOL bReadbmpx; BOOL bSyslogOnly; - BOOL bAdminLog; BOOL bBrowseList; BOOL bNISHomeMap; BOOL bTimeServer; @@ -335,7 +335,6 @@ typedef struct int iOplockContentionLimit; int iCSCPolicy; int iBlock_size; - BOOL bAlternatePerm; BOOL bPreexecClose; BOOL bRootpreexecClose; BOOL bCaseSensitive; @@ -343,6 +342,7 @@ typedef struct BOOL bShortCasePreserve; BOOL bCaseMangle; BOOL bHideDotFiles; + BOOL bHideSpecialFiles; BOOL bHideUnReadable; BOOL bHideUnWriteableFiles; BOOL bBrowseable; @@ -385,6 +385,10 @@ typedef struct BOOL bUseClientDriver; BOOL bDefaultDevmode; BOOL bNTAclSupport; +#ifdef WITH_SENDFILE + BOOL bUseSendfile; +#endif + BOOL bProfileAcls; char dummy[3]; /* for alignment */ } @@ -455,7 +459,6 @@ static service sDefault = { 2, /* iOplockContentionLimit */ 0, /* iCSCPolicy */ 1024, /* iBlock_size */ - False, /* bAlternatePerm */ False, /* bPreexecClose */ False, /* bRootpreexecClose */ False, /* case sensitive */ @@ -463,6 +466,7 @@ static service sDefault = { True, /* short case preserve */ False, /* case mangle */ True, /* bHideDotFiles */ + False, /* bHideSpecialFiles */ False, /* bHideUnReadable */ False, /* bHideUnWriteableFiles */ True, /* bBrowseable */ @@ -505,6 +509,10 @@ static service sDefault = { False, /* bUseClientDriver */ False, /* bDefaultDevmode */ True, /* bNTAclSupport */ +#ifdef WITH_SENDFILE + False, /* bUseSendfile */ +#endif + False, /* bProfileAcls */ "" /* dummy */ }; @@ -592,6 +600,22 @@ static struct enum_list enum_ldap_ssl[] = { {-1, NULL} }; +static struct enum_list enum_ldap_passwd_sync[] = { + {LDAP_PASSWD_SYNC_ON, "Yes"}, + {LDAP_PASSWD_SYNC_ON, "yes"}, + {LDAP_PASSWD_SYNC_ON, "on"}, + {LDAP_PASSWD_SYNC_ON, "On"}, + {LDAP_PASSWD_SYNC_OFF, "no"}, + {LDAP_PASSWD_SYNC_OFF, "No"}, + {LDAP_PASSWD_SYNC_OFF, "off"}, + {LDAP_PASSWD_SYNC_OFF, "Off"}, +#ifdef LDAP_EXOP_X_MODIFY_PASSWD + {LDAP_PASSWD_SYNC_ONLY, "Only"}, + {LDAP_PASSWD_SYNC_ONLY, "only"}, +#endif /* LDAP_EXOP_X_MODIFY_PASSWD */ + {-1, NULL} +}; + /* Types of machine we can announce as. */ #define ANNOUNCE_AS_NT_SERVER 1 #define ANNOUNCE_AS_WIN95 2 @@ -666,66 +690,75 @@ static struct enum_list enum_map_to_guest[] = { {-1, NULL} }; -/* note that we do not initialise the defaults union - it is not allowed in ANSI C */ +/* Note: We do not initialise the defaults union - it is not allowed in ANSI C + * + * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it + * is implied in current control logic. This may change at some later time. A + * flag value of 0 means - show as development option only. + * + * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit + * screen in SWAT. This is used to exclude parameters as well as to squash all + * parameters that have been duplicated by pseudonyms. + */ static struct parm_struct parm_table[] = { {"Base Options", P_SEP, P_SEPARATOR}, - {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, 0}, - {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, 0}, - {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, 0}, - {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT}, - {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT}, - {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, 0}, - {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC}, - {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC}, - {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC}, - {"netbios name", P_UGSTRING, P_GLOBAL, global_myname, handle_netbios_name, NULL, FLAG_BASIC}, - {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, 0}, - {"netbios scope", P_UGSTRING, P_GLOBAL, global_scope, NULL, NULL, 0}, - {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC }, - {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC}, - {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, 0}, + {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER}, + {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER}, + {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE}, + {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, + {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, + {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, + {"netbios name", P_UGSTRING, P_GLOBAL, global_myname, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, + {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, + {"netbios scope", P_UGSTRING, P_GLOBAL, global_scope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER}, + {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, + {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, {"Security Options", P_SEP, P_SEPARATOR}, - {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC}, - {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC}, - {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC}, - {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC}, - {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, 0}, - {"alternate permissions", P_BOOL, P_LOCAL, &sDefault.bAlternatePerm, NULL, NULL, FLAG_GLOBAL | FLAG_DEPRECATED}, - {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, 0}, - {"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, 0}, - {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, 0}, - {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, 0}, - {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, 0}, - {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, 0}, - {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, 0}, - {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, 0}, - {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, 0}, - {"passdb backend", P_LIST, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, 0}, - {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, 0}, - {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.bAlgorithmicRidBase, NULL, NULL, 0}, - {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0}, - {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0}, - {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0}, - {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC}, + {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, + {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, + {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, + {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER}, + {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, + {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"passdb backend", P_LIST, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"sam backend", P_LIST, P_GLOBAL, &Globals.szSamBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.bAlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER}, + {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER}, - {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, 0}, - {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, 0}, - {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, 0}, - {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, 0}, - {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, 0}, - {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, 0}, - {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, 0}, - {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, 0}, - {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, 0}, - {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, 0}, - {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, 0}, + {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER | FLAG_DEVELOPER}, + {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, - {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0}, - {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0}, + {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE}, + {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE}, {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, @@ -735,12 +768,12 @@ static struct parm_struct parm_table[] = { {"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_GLOBAL | FLAG_PRINT}, {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_SHARE}, {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_SHARE}, - {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0}, + {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_SHARE}, - {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0}, - {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0}, - {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0}, + {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE}, + {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE}, + {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE}, + {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE}, {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL}, @@ -755,101 +788,103 @@ static struct parm_struct parm_table[] = { {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_SHARE}, {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_SHARE}, {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE}, - {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0}, + {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE}, - {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT}, - {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, 0}, + {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER}, + {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE}, {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE}, - {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_SHARE | FLAG_PRINT}, - {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, 0}, - {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_SHARE | FLAG_PRINT}, - {"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, 0}, + {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER}, + {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_HIDE}, + {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER}, + {"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_HIDE}, {"Logging Options", P_SEP, P_SEPARATOR}, - {"admin log", P_BOOL, P_GLOBAL, &Globals.bAdminLog, NULL, NULL, 0}, - {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, 0}, - {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, 0}, - {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, 0}, - {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, 0}, - {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, 0}, + {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_HIDE}, + {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, 0}, - {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0}, - {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0}, - {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, 0}, - {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, 0}, - {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, 0}, + {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_DEVELOPER}, + {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, FLAG_DEVELOPER}, + {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, FLAG_DEVELOPER}, + {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, FLAG_DEVELOPER}, {"Protocol Options", P_SEP, P_SEPARATOR}, - {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, 0}, - {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0}, - {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, 0}, - {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0}, - {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, 0}, - {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, 0}, - {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, 0}, - {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, 0}, - {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, 0}, - {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, 0}, + {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER}, + {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER}, + {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER}, + {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER}, + {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, FLAG_DEVELOPER}, + {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER}, + {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER}, + {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + + {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE | FLAG_ADVANCED | FLAG_WIZARD}, + {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"profile acls", P_BOOL, P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE | FLAG_ADVANCED | FLAG_WIZARD}, - {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, 0}, - {"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE }, - {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, 0}, - {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, 0}, - {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, 0}, - {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, 0}, - {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, 0}, + {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER}, + {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER}, + {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, 0}, - {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0}, - {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0}, - {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, 0}, - {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, 0}, - {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, 0}, - {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, 0}, - {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, 0}, - {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, 0}, + {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, + {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER}, {"Tuning Options", P_SEP, P_SEPARATOR}, {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, - {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, 0}, - {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, 0}, - {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, 0}, - {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, 0}, + {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, FLAG_DEVELOPER}, + {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_DEVELOPER}, + {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_DEVELOPER}, + {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, 0}, - {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, 0}, + {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER}, + {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_DEVELOPER}, {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE}, - {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, 0}, - {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, 0}, - {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, 0}, + {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER}, + {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_DEVELOPER}, + {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT}, - {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, 0}, + {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, FLAG_DEVELOPER}, - {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, 0}, - {"stat cache size", P_INTEGER, P_GLOBAL, &Globals.stat_cache_size, NULL, NULL, 0}, + {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, FLAG_DEVELOPER}, + {"stat cache size", P_INTEGER, P_GLOBAL, &Globals.stat_cache_size, NULL, NULL, FLAG_DEVELOPER}, {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_SHARE}, {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_SHARE}, {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_SHARE}, - {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, 0}, - {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, 0}, + {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER}, +#ifdef WITH_SENDFILE + {"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_SHARE}, +#endif + {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_SHARE}, - {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, 0}, + {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"Printing Options", P_SEP, P_SEPARATOR}, {"total print jobs", P_INTEGER, P_GLOBAL, &Globals.iTotalPrintJobs, NULL, NULL, FLAG_PRINT}, {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT}, {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT}, - {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT}, - {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0}, + {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER}, + {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE}, {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT}, - {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0}, + {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE}, {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL, NULL, FLAG_PRINT | FLAG_DEPRECATED}, {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL}, {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL}, @@ -861,14 +896,14 @@ static struct parm_struct parm_table[] = { {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL}, {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL}, - {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, 0}, - {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, 0}, - {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, 0}, - {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, 0}, - {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, 0}, + {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT}, - {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, 0}, + {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE}, {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_PRINT}, {"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_PRINT}, {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, FLAG_PRINT | FLAG_DEPRECATED}, @@ -876,18 +911,19 @@ static struct parm_struct parm_table[] = { {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL | FLAG_DEPRECATED}, {"Filename Handling", P_SEP, P_SEPARATOR}, - {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, 0}, - {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, 0}, + {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, 0}, + {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_SHARE}, {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, - {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, 0}, + {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_HIDE}, {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"hide special files", P_BOOL, P_LOCAL, &sDefault.bHideSpecialFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, {"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, @@ -899,52 +935,53 @@ static struct parm_struct parm_table[] = { {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, - {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, 0}, + {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_DEVELOPER}, {"Domain Options", P_SEP, P_SEPARATOR}, - {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, 0}, + {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, {"Logon Options", P_SEP, P_SEPARATOR}, - {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, 0}, - {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, 0}, - {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, 0}, - {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, 0}, - {"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, 0}, - {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, 0}, - {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, 0}, - {"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, 0}, - {"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, 0}, - - {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, 0}, - {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, 0}, - {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, 0}, - {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, 0}, - {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, 0}, + {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"set primary group script", P_STRING, P_GLOBAL, &Globals.szSetPrimaryGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + + {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"Browse Options", P_SEP, P_SEPARATOR}, - {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC}, - {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, 0}, - {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, 0}, - {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC}, + {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER}, + {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER}, {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE}, - {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC}, - {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC}, - {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, 0}, - {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT}, - {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0}, - {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL}, + {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER}, + {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER}, + {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER}, + {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE}, + {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED}, {"WINS Options", P_SEP, P_SEPARATOR}, - {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, 0}, - {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, 0}, + {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC}, - {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC}, - {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, 0}, - {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, 0}, + {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, + {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, + {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, {"Locking Options", P_SEP, P_SEPARATOR}, @@ -966,57 +1003,58 @@ static struct parm_struct parm_table[] = { {"Ldap Options", P_SEP, P_SEPARATOR}, - {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, handle_ldap_suffix, NULL, 0}, - {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, handle_ldap_machine_suffix, NULL, 0}, - {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, handle_ldap_user_suffix, NULL, 0}, - {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, 0}, - {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, 0}, - {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, 0}, + {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, handle_ldap_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, handle_ldap_machine_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, handle_ldap_user_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED | FLAG_DEVELOPER}, {"Miscellaneous Options", P_SEP, P_SEPARATOR}, - {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, 0}, - {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, 0}, - {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, 0}, + {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE}, - {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0}, - {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0}, - {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0}, - {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0}, - {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, 0}, + {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE}, + {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, #ifdef WITH_UTMP - {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, 0}, - {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, 0}, - {"utmp", P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, 0}, + {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"utmp", P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, #endif - {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0}, - {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0}, - {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, 0}, - {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, 0}, - {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, 0}, - {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, 0}, - {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, 0}, - {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, 0}, - {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, 0}, - {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, 0}, + {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DEVELOPER}, + {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER}, + {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE}, {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE}, {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE}, {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT}, - {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0}, + {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_SHARE}, {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT}, {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT}, {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_SHARE}, {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT}, - {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT}, + {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE }, {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE}, {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_SHARE}, - {"source environment", P_STRING, P_GLOBAL, &Globals.szSourceEnv, handle_source_env, NULL, 0}, + {"source environment", P_STRING, P_GLOBAL, &Globals.szSourceEnv, handle_source_env, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_SHARE}, @@ -1028,9 +1066,8 @@ static struct parm_struct parm_table[] = { {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, - {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, 0}, - {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, - NULL, 0}, + {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"VFS module options", P_SEP, P_SEPARATOR}, @@ -1040,19 +1077,19 @@ static struct parm_struct parm_table[] = { {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE}, - {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, 0}, + {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"Winbind options", P_SEP, P_SEPARATOR}, - {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, 0}, - {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, 0}, - {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, 0}, - {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, 0}, - {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, 0}, - {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, 0}, - {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, 0}, - {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, 0}, - {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, 0}, + {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0} }; @@ -1250,7 +1287,6 @@ static void init_globals(void) Globals.bAlgorithmicRidBase = BASE_RID; Globals.bLoadPrinters = True; - Globals.max_packet = 65535; Globals.mangled_stack = 50; Globals.max_xmit = 65535; Globals.max_mux = 50; /* This is *needed* for profile support. */ @@ -1279,7 +1315,6 @@ static void init_globals(void) Globals.bStripDot = False; Globals.syslog = 1; Globals.bSyslogOnly = False; - Globals.bAdminLog = False; Globals.bTimestampLogs = True; string_set(&Globals.szLogLevel, "0"); Globals.bDebugHiresTimestamp = False; @@ -1339,6 +1374,7 @@ static void init_globals(void) string_set(&Globals.szLdapFilter, "(&(uid=%u)(objectclass=sambaAccount))"); string_set(&Globals.szLdapAdminDn, ""); Globals.ldap_ssl = LDAP_SSL_ON; + Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF; /* these parameters are set to defaults that are more appropriate for the increasing samba install base: @@ -1521,6 +1557,7 @@ FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName) static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion) FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases) FN_GLOBAL_LIST(lp_passdb_backend, &Globals.szPassdbBackend) +FN_GLOBAL_LIST(lp_sam_backend, &Globals.szSamBackend) FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction) FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript) FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript) @@ -1530,6 +1567,7 @@ FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript) FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript) FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript) FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript) +FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript) FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript) @@ -1550,6 +1588,7 @@ FN_GLOBAL_STRING(lp_ldap_user_suffix, &Globals.szLdapUserSuffix) FN_GLOBAL_STRING(lp_ldap_filter, &Globals.szLdapFilter) FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn) FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl) +FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync) FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand) FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand) FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand) @@ -1574,7 +1613,6 @@ FN_GLOBAL_BOOL(lp_strip_dot, &Globals.bStripDot) FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords) FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt) FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly) -FN_GLOBAL_BOOL(lp_admin_log, &Globals.bAdminLog) FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs) FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp) FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid) @@ -1686,6 +1724,7 @@ FN_LOCAL_BOOL(lp_preservecase, bCasePreserve) FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve) FN_LOCAL_BOOL(lp_casemangle, bCaseMangle) FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles) +FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles) FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable) FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles) FN_LOCAL_BOOL(lp_browseable, bBrowseable) @@ -1724,6 +1763,10 @@ FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS) FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver) FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode) FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport) +#ifdef WITH_SENDFILE +FN_LOCAL_BOOL(lp_use_sendfile, bUseSendfile) +#endif +FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls) FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask) FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode) FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask) @@ -3507,32 +3550,46 @@ static void set_server_role(void) case SEC_SHARE: if (lp_domain_logons()) DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n")); - DEBUG(10,("set_server_role: ROLE_STANDALONE\n")); break; case SEC_SERVER: case SEC_DOMAIN: case SEC_ADS: if (lp_domain_logons()) { server_role = ROLE_DOMAIN_PDC; - DEBUG(10,("set_server_role:ROLE_DOMAIN_PDC\n")); break; } server_role = ROLE_DOMAIN_MEMBER; - DEBUG(10,("set_server_role: ROLE_DOMAIN_MEMBER\n")); break; case SEC_USER: if (lp_domain_logons()) { - server_role = ROLE_DOMAIN_PDC; - DEBUG(10,("set_server_role: ROLE_DOMAIN_PDC\n")); - break; + + if (Globals.bDomainMaster) /* auto or yes */ + server_role = ROLE_DOMAIN_PDC; + else + server_role = ROLE_DOMAIN_BDC; } - DEBUG(10,("set_server_role: ROLE_STANDALONE\n")); break; default: DEBUG(0, ("Server's Role undefined due to unknown security mode\n")); - DEBUG(10,("set_server_role: ROLE_STANDALONE\n")); break; } + + DEBUG(10, ("set_server_role: role = ")); + + switch(server_role) { + case ROLE_STANDALONE: + DEBUGADD(10, ("ROLE_STANDALONE\n")); + break; + case ROLE_DOMAIN_MEMBER: + DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n")); + break; + case ROLE_DOMAIN_BDC: + DEBUGADD(10, ("ROLE_DOMAIN_BDC\n")); + break; + case ROLE_DOMAIN_PDC: + DEBUGADD(10, ("ROLE_DOMAIN_PDC\n")); + break; + } } @@ -3555,12 +3612,13 @@ BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults, bRetval = False; - DEBUG(3, ("lp_load: refreshing parmaters\n")); + DEBUG(3, ("lp_load: refreshing parameters\n")); bInGlobalSection = True; bGlobalOnly = global_only; init_globals(); + debug_init(); if (save_defaults) { diff --git a/source3/passdb/machine_sid.c b/source3/passdb/machine_sid.c index e1f7dec2a9b..e1a1de83a60 100644 --- a/source3/passdb/machine_sid.c +++ b/source3/passdb/machine_sid.c @@ -80,7 +80,6 @@ static BOOL pdb_generate_sam_sid(void) { char *fname = NULL; extern pstring global_myname; - extern fstring global_myworkgroup; BOOL is_dc = False; if(global_sam_sid==NULL) @@ -106,11 +105,11 @@ static BOOL pdb_generate_sam_sid(void) if (!is_dc) return True; - if (!secrets_fetch_domain_sid(global_myworkgroup, &domain_sid)) { + if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) { /* No domain sid and we're a pdc/bdc. Store it */ - if (!secrets_store_domain_sid(global_myworkgroup, global_sam_sid)) { + if (!secrets_store_domain_sid(lp_workgroup(), global_sam_sid)) { DEBUG(0,("pdb_generate_sam_sid: Can't store domain SID as a pdc/bdc.\n")); return False; } @@ -122,7 +121,7 @@ static BOOL pdb_generate_sam_sid(void) /* Domain name sid doesn't match global sam sid. Re-store global sam sid as domain sid. */ DEBUG(0,("pdb_generate_sam_sid: Mismatched SIDs as a pdc/bdc.\n")); - if (!secrets_store_domain_sid(global_myworkgroup, global_sam_sid)) { + if (!secrets_store_domain_sid(lp_workgroup(), global_sam_sid)) { DEBUG(0,("pdb_generate_sam_sid: Can't re-store domain SID as a pdc/bdc.\n")); return False; } @@ -145,7 +144,7 @@ static BOOL pdb_generate_sam_sid(void) } unlink(fname); if (is_dc) { - if (!secrets_store_domain_sid(global_myworkgroup, global_sam_sid)) { + if (!secrets_store_domain_sid(lp_workgroup(), global_sam_sid)) { DEBUG(0,("pdb_generate_sam_sid: Failed to store domain SID from file.\n")); SAFE_FREE(fname); return False; @@ -168,7 +167,7 @@ static BOOL pdb_generate_sam_sid(void) return False; } if (is_dc) { - if (!secrets_store_domain_sid(global_myworkgroup, global_sam_sid)) { + if (!secrets_store_domain_sid(lp_workgroup(), global_sam_sid)) { DEBUG(0,("pdb_generate_sam_sid: Failed to store generated domain SID.\n")); return False; } diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index a9c6f0729bd..b78f26a8e81 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -75,11 +75,19 @@ static void pdb_fill_default_sam(SAM_ACCOUNT *user) user->private.workstations = ""; user->private.unknown_str = ""; user->private.munged_dial = ""; + + user->private.plaintext_pw = NULL; + } static void destroy_pdb_talloc(SAM_ACCOUNT **user) { if (*user) { + data_blob_clear_free(&((*user)->private.lm_pw)); + data_blob_clear_free(&((*user)->private.nt_pw)); + + if((*user)->private.plaintext_pw!=NULL) + memset((*user)->private.plaintext_pw,'\0',strlen((*user)->private.plaintext_pw)); talloc_destroy((*user)->mem_ctx); *user = NULL; } @@ -251,6 +259,15 @@ NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd) pwd->pw_name, global_myname, pwd->pw_uid, pwd->pw_gid), False); + if (!pdb_set_acct_ctrl(sam_account, ACB_NORMAL)) { + DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n", pwd->pw_name)); + return NT_STATUS_UNSUCCESSFUL; + } + } else { + if (!pdb_set_acct_ctrl(sam_account, ACB_WSTRUST)) { + DEBUG(1, ("Failed to set 'trusted workstation account' flags for user %s.\n", pwd->pw_name)); + return NT_STATUS_UNSUCCESSFUL; + } } return NT_STATUS_OK; } @@ -301,7 +318,8 @@ static void pdb_free_sam_contents(SAM_ACCOUNT *user) data_blob_clear_free(&(user->private.lm_pw)); data_blob_clear_free(&(user->private.nt_pw)); - data_blob_clear_free(&(user->private.plaintext_pw)); + if (user->private.plaintext_pw!=NULL) + memset(user->private.plaintext_pw,'\0',strlen(user->private.plaintext_pw)); } @@ -823,11 +841,14 @@ BOOL local_sid_to_uid(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE *name_ return False; if (pdb_getsampwsid(sam_user, psid)) { - *puid = pdb_get_uid(sam_user); - if (*puid == -1) { + + if (!(pdb_get_init_flag(sam_user) & FLAG_SAM_UID)) { pdb_free_sam(&sam_user); return False; } + + *puid = pdb_get_uid(sam_user); + DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_to_string( str, psid), (unsigned int)*puid, pdb_get_username(sam_user))); pdb_free_sam(&sam_user); @@ -982,6 +1003,7 @@ BOOL local_password_change(const char *user_name, int local_flags, { struct passwd *pwd = NULL; SAM_ACCOUNT *sam_pass=NULL; + uint16 other_acb; *err_str = '\0'; *msg_str = '\0'; @@ -1021,31 +1043,33 @@ BOOL local_password_change(const char *user_name, int local_flags, return False; } } - if (local_flags & LOCAL_TRUST_ACCOUNT) { - if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST)) { - slprintf(err_str, err_str_len - 1, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name); - pdb_free_sam(&sam_pass); - return False; - } - } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) { - if (!pdb_set_acct_ctrl(sam_pass, ACB_DOMTRUST)) { - slprintf(err_str, err_str_len - 1, "Failed to set 'domain trust account' flags for user %s.\n", user_name); - pdb_free_sam(&sam_pass); - return False; - } - } else { - if (!pdb_set_acct_ctrl(sam_pass, ACB_NORMAL)) { - slprintf(err_str, err_str_len - 1, "Failed to set 'normal account' flags for user %s.\n", user_name); - pdb_free_sam(&sam_pass); - return False; - } - } - } else { /* the entry already existed */ local_flags &= ~LOCAL_ADD_USER; } + /* the 'other' acb bits not being changed here */ + other_acb = (pdb_get_acct_ctrl(sam_pass) & (!(ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST|ACB_NORMAL))); + if (local_flags & LOCAL_TRUST_ACCOUNT) { + if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST | other_acb) ) { + slprintf(err_str, err_str_len - 1, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name); + pdb_free_sam(&sam_pass); + return False; + } + } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) { + if (!pdb_set_acct_ctrl(sam_pass, ACB_DOMTRUST | other_acb)) { + slprintf(err_str, err_str_len - 1, "Failed to set 'domain trust account' flags for user %s.\n", user_name); + pdb_free_sam(&sam_pass); + return False; + } + } else { + if (!pdb_set_acct_ctrl(sam_pass, ACB_NORMAL | other_acb)) { + slprintf(err_str, err_str_len - 1, "Failed to set 'normal account' flags for user %s.\n", user_name); + pdb_free_sam(&sam_pass); + return False; + } + } + /* * We are root - just write the new password * and the valid last change time. diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c index 2da6de72701..0c338f317ec 100644 --- a/source3/passdb/pdb_get_set.c +++ b/source3/passdb/pdb_get_set.c @@ -151,7 +151,7 @@ const uint8* pdb_get_lanman_passwd (const SAM_ACCOUNT *sampass) const char* pdb_get_plaintext_passwd (const SAM_ACCOUNT *sampass) { if (sampass) { - return ((char*)sampass->private.plaintext_pw.data); + return (sampass->private.plaintext_pw); } else return (NULL); @@ -956,14 +956,24 @@ BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[16]) below) ********************************************************************/ -BOOL pdb_set_plaintext_pw_only (SAM_ACCOUNT *sampass, const uint8 *password, size_t len) +BOOL pdb_set_plaintext_pw_only (SAM_ACCOUNT *sampass, const char *password) { if (!sampass) return False; - data_blob_clear_free(&sampass->private.plaintext_pw); - - sampass->private.plaintext_pw = data_blob(password, len); + if (password) { + if (sampass->private.plaintext_pw!=NULL) + memset(sampass->private.plaintext_pw,'\0',strlen(sampass->private.plaintext_pw)+1); + sampass->private.plaintext_pw = talloc_strdup(sampass->mem_ctx, password); + + if (!sampass->private.plaintext_pw) { + DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n")); + return False; + } + + } else { + sampass->private.plaintext_pw = NULL; + } return True; } @@ -1062,7 +1072,10 @@ BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext) if (!pdb_set_lanman_passwd (sampass, new_lanman_p16)) return False; - + + if (!pdb_set_plaintext_pw_only (sampass, plaintext)) + return False; + if (!pdb_set_pass_changed_now (sampass)) return False; diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index f311223d772..f965dd727cc 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -34,13 +34,14 @@ const struct pdb_init_function_entry builtin_pdb_init_functions[] = { { "ldapsam", pdb_init_ldapsam }, { "ldapsam_nua", pdb_init_ldapsam_nua }, { "unixsam", pdb_init_unixsam }, + { "nisplussam", pdb_init_nisplussam }, { "plugin", pdb_init_plugin }, { NULL, NULL} }; static BOOL context_setsampwent(struct pdb_context *context, BOOL update) { - if ((!context) || (!context->pdb_methods) || (!context->pdb_methods->setsampwent)) { + if (!context) { DEBUG(0, ("invalid pdb_context specified!\n")); return False; } @@ -52,7 +53,7 @@ static BOOL context_setsampwent(struct pdb_context *context, BOOL update) return True; } - while (!(context->pwent_methods->setsampwent(context->pwent_methods, update))) { + while (!(context->pwent_methods->setsampwent) || !(context->pwent_methods->setsampwent(context->pwent_methods, update))) { context->pwent_methods = context->pwent_methods->next; if (context->pwent_methods == NULL) return False; diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index f82cb4488fc..71a8c256a3a 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -1,11 +1,11 @@ /* Unix SMB/CIFS implementation. LDAP protocol helper functions for SAMBA - Copyright (C) Jean François Micouleau 1998 - Copyright (C) Gerald Carter 2001 - Copyright (C) Shahms King 2001 - Copyright (C) Andrew Bartlett 2002 - Copyright (C) Stefan (metze) Metzmacher 2002 + Copyright (C) Jean François Micouleau 1998 + Copyright (C) Gerald Carter 2001 + Copyright (C) Shahms King 2001 + Copyright (C) Andrew Bartlett 2002 + Copyright (C) Stefan (metze) Metzmacher 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -273,7 +273,8 @@ static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP * a rebind function for authenticated referrals This version takes a void* that we can shove useful stuff in :-) ******************************************************************/ - +#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) +#else static int rebindproc_with_state (LDAP * ld, char **whop, char **credp, int *methodp, int freeit, void *arg) { @@ -304,13 +305,14 @@ static int rebindproc_with_state (LDAP * ld, char **whop, char **credp, } return 0; } +#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ /******************************************************************* a rebind function for authenticated referrals This version takes a void* that we can shove useful stuff in :-) and actually does the connection. ******************************************************************/ - +#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) static int rebindproc_connect_with_state (LDAP *ldap_struct, LDAP_CONST char *url, ber_tag_t request, @@ -329,11 +331,14 @@ static int rebindproc_connect_with_state (LDAP *ldap_struct, return rc; } +#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ /******************************************************************* Add a rebind function for authenticated referrals ******************************************************************/ - +#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) +#else +# if LDAP_SET_REBIND_PROC_ARGS == 2 static int rebindproc (LDAP *ldap_struct, char **whop, char **credp, int *method, int freeit ) { @@ -341,19 +346,23 @@ static int rebindproc (LDAP *ldap_struct, char **whop, char **credp, method, freeit, static_ldap_state); } +# endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/ +#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ /******************************************************************* a rebind function for authenticated referrals this also does the connection, but no void*. ******************************************************************/ - +#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) +# if LDAP_SET_REBIND_PROC_ARGS == 2 static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request, ber_int_t msgid) { return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid, static_ldap_state); } - +# endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/ +#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ /******************************************************************* connect to the ldap server under system privilege. @@ -391,18 +400,18 @@ static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * l # if LDAP_SET_REBIND_PROC_ARGS == 3 ldap_set_rebind_proc(ldap_struct, &rebindproc_connect_with_state, (void *)ldap_state); # endif -#else +#else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ # if LDAP_SET_REBIND_PROC_ARGS == 2 ldap_set_rebind_proc(ldap_struct, &rebindproc); # endif # if LDAP_SET_REBIND_PROC_ARGS == 3 ldap_set_rebind_proc(ldap_struct, &rebindproc_with_state, (void *)ldap_state); # endif -#endif +#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ + rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret); - if (rc != LDAP_SUCCESS) - { + if (rc != LDAP_SUCCESS) { DEBUG(0, ("Bind failed: %s\n", ldap_err2string(rc))); return False; } @@ -421,7 +430,7 @@ static int ldapsam_search_one_user (struct ldapsam_privates *ldap_state, LDAP * DEBUG(2, ("ldapsam_search_one_user: searching for:[%s]\n", filter)); - rc = ldap_search_s(ldap_struct, lp_ldap_suffix (), scope, filter, attr, 0, result); + rc = ldap_search_s(ldap_struct, lp_ldap_suffix (), scope, filter, (char **)attr, 0, result); if (rc != LDAP_SUCCESS) { DEBUG(0,("ldapsam_search_one_user: Problem during the LDAP search: %s\n", @@ -944,9 +953,6 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, slprintf(temp, sizeof(temp) - 1, "%i", rid); make_a_mod(mods, ldap_op, "primaryGroupID", temp); - slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass)); - make_a_mod(mods, ldap_op, "pwdLastSet", temp); - /* displayName, cn, and gecos should all be the same * most easily accomplished by giving them the same OID * gecos isn't set here b/c it should be handled by the @@ -989,6 +995,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, make_a_mod(mods, ldap_op, "kickoffTime", temp); } + if (IS_SAM_SET(sampass, FLAG_SAM_CANCHANGETIME)) { slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_can_change_time(sampass)); make_a_mod(mods, ldap_op, "pwdCanChange", temp); @@ -999,13 +1006,22 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, make_a_mod(mods, ldap_op, "pwdMustChange", temp); } - /* FIXME: Hours stuff goes in LDAP */ - pdb_sethexpwd (temp, pdb_get_lanman_passwd(sampass), pdb_get_acct_ctrl(sampass)); - make_a_mod (mods, ldap_op, "lmPassword", temp); + if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))|| + (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) { + + pdb_sethexpwd (temp, pdb_get_lanman_passwd(sampass), pdb_get_acct_ctrl(sampass)); + make_a_mod (mods, ldap_op, "lmPassword", temp); - pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass), pdb_get_acct_ctrl(sampass)); - make_a_mod (mods, ldap_op, "ntPassword", temp); + pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass), pdb_get_acct_ctrl(sampass)); + make_a_mod (mods, ldap_op, "ntPassword", temp); + slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass)); + make_a_mod(mods, ldap_op, "pwdLastSet", temp); + + } + + /* FIXME: Hours stuff goes in LDAP */ + make_a_mod (mods, ldap_op, "acctFlags", pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass), NEW_PW_FORMAT_SPACE_PADDED_LEN)); @@ -1030,18 +1046,18 @@ static uint32 check_nua_rid_is_avail(struct ldapsam_privates *ldap_state, uint32 if (ldapsam_search_one_user_by_rid(ldap_state, ldap_struct, final_rid, &result) != LDAP_SUCCESS) { DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the confirmation search failed!\n", final_rid, final_rid)); - final_rid = 0; ldap_msgfree(result); + return 0; } - if (ldap_count_entries(ldap_struct, result) != 0) - { + if (ldap_count_entries(ldap_struct, result) != 0) { DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the RID is already in use!!\n", final_rid, final_rid)); - final_rid = 0; ldap_msgfree(result); + return 0; } DEBUG(5, ("NUA RID %d (0x%x), declared valid\n", final_rid, final_rid)); + ldap_msgfree(result); return final_rid; } @@ -1093,12 +1109,10 @@ static uint32 search_top_nua_rid(struct ldapsam_privates *ldap_state, LDAP *ldap DEBUG(2, ("ldapsam_get_next_available_nua_rid: searching for:[%s]\n", final_filter)); rc = ldap_search_s(ldap_struct, lp_ldap_suffix(), - LDAP_SCOPE_SUBTREE, final_filter, attr, 0, + LDAP_SCOPE_SUBTREE, final_filter, (char **)attr, 0, &result); - if (rc != LDAP_SUCCESS) - { - + if (rc != LDAP_SUCCESS) { DEBUG(3, ("LDAP search failed! cannot find base for NUA RIDs: %s\n", ldap_err2string(rc))); DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter)); @@ -1149,12 +1163,10 @@ static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_s uint32 next_nua_rid; uint32 top_nua_rid; - if (!ldapsam_open_connection(ldap_state, &ldap_struct)) - { + if (!ldapsam_open_connection(ldap_state, &ldap_struct)) { return 0; } - if (!ldapsam_connect_system(ldap_state, ldap_struct)) - { + if (!ldapsam_connect_system(ldap_state, ldap_struct)) { ldap_unbind(ldap_struct); return 0; } @@ -1177,12 +1189,10 @@ static BOOL ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update) int rc; pstring filter; - if (!ldapsam_open_connection(ldap_state, &ldap_state->ldap_struct)) - { + if (!ldapsam_open_connection(ldap_state, &ldap_state->ldap_struct)) { return False; } - if (!ldapsam_connect_system(ldap_state, ldap_state->ldap_struct)) - { + if (!ldapsam_connect_system(ldap_state, ldap_state->ldap_struct)) { ldap_unbind(ldap_state->ldap_struct); return False; } @@ -1191,11 +1201,10 @@ static BOOL ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update) all_string_sub(filter, "%u", "*", sizeof(pstring)); rc = ldap_search_s(ldap_state->ldap_struct, lp_ldap_suffix(), - LDAP_SCOPE_SUBTREE, filter, attr, 0, + LDAP_SCOPE_SUBTREE, filter, (char **)attr, 0, &ldap_state->result); - if (rc != LDAP_SUCCESS) - { + if (rc != LDAP_SUCCESS) { DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc))); DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter)); ldap_msgfree(ldap_state->result); @@ -1222,8 +1231,7 @@ End enumeration of the LDAP password list static void ldapsam_endsampwent(struct pdb_methods *my_methods) { struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; - if (ldap_state->ldap_struct && ldap_state->result) - { + if (ldap_state->ldap_struct && ldap_state->result) { ldap_msgfree(ldap_state->result); ldap_unbind(ldap_state->ldap_struct); ldap_state->ldap_struct = NULL; @@ -1234,7 +1242,7 @@ static void ldapsam_endsampwent(struct pdb_methods *my_methods) /********************************************************************** Get the next entry in the LDAP password database *********************************************************************/ -static BOOL ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT * user) +static BOOL ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user) { struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; BOOL ret = False; @@ -1252,8 +1260,7 @@ static BOOL ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT * us ldap_state->entry); ldap_state->entry = ldap_next_entry(ldap_state->ldap_struct, - ldap_state->entry); - + ldap_state->entry); } return True; @@ -1262,7 +1269,7 @@ static BOOL ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT * us /********************************************************************** Get SAM_ACCOUNT entry from LDAP by username *********************************************************************/ -static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const char *sname) +static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname) { struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; LDAP *ldap_struct; @@ -1271,18 +1278,15 @@ static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT * us if (!ldapsam_open_connection(ldap_state, &ldap_struct)) return False; - if (!ldapsam_connect_system(ldap_state, ldap_struct)) - { + if (!ldapsam_connect_system(ldap_state, ldap_struct)) { ldap_unbind(ldap_struct); return False; } - if (ldapsam_search_one_user_by_name(ldap_state, ldap_struct, sname, &result) != LDAP_SUCCESS) - { + if (ldapsam_search_one_user_by_name(ldap_state, ldap_struct, sname, &result) != LDAP_SUCCESS) { ldap_unbind(ldap_struct); return False; } - if (ldap_count_entries(ldap_struct, result) < 1) - { + if (ldap_count_entries(ldap_struct, result) < 1) { DEBUG(4, ("We don't find this user [%s] count=%d\n", sname, ldap_count_entries(ldap_struct, result))); @@ -1290,8 +1294,7 @@ static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT * us return False; } entry = ldap_first_entry(ldap_struct, result); - if (entry) - { + if (entry) { if (!init_sam_from_ldap(ldap_state, user, ldap_struct, entry)) { DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname)); ldap_msgfree(result); @@ -1301,9 +1304,7 @@ static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT * us ldap_msgfree(result); ldap_unbind(ldap_struct); return True; - } - else - { + } else { ldap_msgfree(result); ldap_unbind(ldap_struct); return False; @@ -1313,7 +1314,7 @@ static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT * us /********************************************************************** Get SAM_ACCOUNT entry from LDAP by rid *********************************************************************/ -static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, uint32 rid) +static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *user, uint32 rid) { struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; LDAP *ldap_struct; @@ -1323,20 +1324,17 @@ static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * us if (!ldapsam_open_connection(ldap_state, &ldap_struct)) return False; - if (!ldapsam_connect_system(ldap_state, ldap_struct)) - { + if (!ldapsam_connect_system(ldap_state, ldap_struct)) { ldap_unbind(ldap_struct); return False; } if (ldapsam_search_one_user_by_rid(ldap_state, ldap_struct, rid, &result) != - LDAP_SUCCESS) - { + LDAP_SUCCESS) { ldap_unbind(ldap_struct); return False; } - if (ldap_count_entries(ldap_struct, result) < 1) - { + if (ldap_count_entries(ldap_struct, result) < 1) { DEBUG(4, ("We don't find this rid [%i] count=%d\n", rid, ldap_count_entries(ldap_struct, result))); @@ -1345,8 +1343,7 @@ static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * us } entry = ldap_first_entry(ldap_struct, result); - if (entry) - { + if (entry) { if (!init_sam_from_ldap(ldap_state, user, ldap_struct, entry)) { DEBUG(1,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n")); ldap_msgfree(result); @@ -1356,9 +1353,7 @@ static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * us ldap_msgfree(result); ldap_unbind(ldap_struct); return True; - } - else - { + } else { ldap_msgfree(result); ldap_unbind(ldap_struct); return False; @@ -1373,6 +1368,95 @@ static BOOL ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * us return ldapsam_getsampwrid(my_methods, user, rid); } +static BOOL ldapsam_modify_entry(LDAP *ldap_struct,SAM_ACCOUNT *newpwd,char *dn,LDAPMod **mods,int ldap_op) +{ + int version; + int rc; + + switch(ldap_op) + { + case LDAP_MOD_ADD: + make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "account"); + if((rc = ldap_add_s(ldap_struct,dn,mods))!=LDAP_SUCCESS) { + char *ld_error; + ldap_get_option(ldap_struct, LDAP_OPT_ERROR_STRING, + &ld_error); + DEBUG(0, + ("failed to add user with uid = %s with: %s\n\t%s\n", + pdb_get_username(newpwd), ldap_err2string(rc), + ld_error)); + free(ld_error); + return False; + } + break; + case LDAP_MOD_REPLACE: + if((rc = ldap_modify_s(ldap_struct,dn,mods))!=LDAP_SUCCESS) { + char *ld_error; + ldap_get_option(ldap_struct, LDAP_OPT_ERROR_STRING, + &ld_error); + DEBUG(0, + ("failed to modify user with uid = %s with: %s\n\t%s\n", + pdb_get_username(newpwd), ldap_err2string(rc), + ld_error)); + free(ld_error); + return False; + } + break; + default: + DEBUG(0,("Wrong LDAP operation type: %d!\n",ldap_op)); + return False; + } + +#ifdef LDAP_EXOP_X_MODIFY_PASSWD + if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))&& + (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_OFF)&& + (pdb_get_plaintext_passwd(newpwd)!=NULL)) { + BerElement *ber; + struct berval *bv; + char *retoid; + struct berval *retdata; + + if (ldap_get_option(ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) { + if (version != LDAP_VERSION3) { + version = LDAP_VERSION3; + ldap_set_option (ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version); + } + } + + if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) { + DEBUG(0,("ber_alloc_t returns NULL\n")); + return False; + } + ber_printf (ber, "{"); + ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID,dn); + ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, pdb_get_plaintext_passwd(newpwd)); + ber_printf (ber, "N}"); + + if ((rc = ber_flatten (ber, &bv))<0) { + DEBUG(0,("ber_flatten returns a value <0\n")); + return False; + } + + ber_free(ber,1); + + if ((rc = ldap_extended_operation_s(ldap_struct, LDAP_EXOP_X_MODIFY_PASSWD, + bv, NULL, NULL, &retoid, &retdata))!=LDAP_SUCCESS) { + DEBUG(0,("LDAP Password could not be changed for user %s: %s\n", + pdb_get_username(newpwd),ldap_err2string(rc))); + } else { + DEBUG(3,("LDAP Password changed for user %s\n",pdb_get_username(newpwd))); + + ber_bvfree(retdata); + ber_memfree(retoid); + } + ber_bvfree(bv); + } +#else + DEBUG(10,("LDAP PASSWORD SYNC is not supported!\n")); +#endif /* LDAP_EXOP_X_MODIFY_PASSWD */ + return True; +} + /********************************************************************** Delete entry from LDAP for username *********************************************************************/ @@ -1414,7 +1498,8 @@ static BOOL ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOU entry = ldap_first_entry (ldap_struct, result); dn = ldap_get_dn (ldap_struct, entry); - + ldap_msgfree(result); + rc = ldap_delete_s (ldap_struct, dn); ldap_memfree (dn); @@ -1449,8 +1534,7 @@ static BOOL ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOU if (!ldapsam_open_connection(ldap_state, &ldap_struct)) /* open a connection to the server */ return False; - if (!ldapsam_connect_system(ldap_state, ldap_struct)) /* connect as system account */ - { + if (!ldapsam_connect_system(ldap_state, ldap_struct)) { /* connect as system account */ ldap_unbind(ldap_struct); return False; } @@ -1458,8 +1542,7 @@ static BOOL ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOU rc = ldapsam_search_one_user_by_name(ldap_state, ldap_struct, pdb_get_username(newpwd), &result); - if (ldap_count_entries(ldap_struct, result) == 0) - { + if (ldap_count_entries(ldap_struct, result) == 0) { DEBUG(0, ("No user to modify!\n")); ldap_msgfree(result); ldap_unbind(ldap_struct); @@ -1475,23 +1558,17 @@ static BOOL ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOU entry = ldap_first_entry(ldap_struct, result); dn = ldap_get_dn(ldap_struct, entry); - - rc = ldap_modify_s(ldap_struct, dn, mods); - - if (rc != LDAP_SUCCESS) - { - char *ld_error; - ldap_get_option(ldap_struct, LDAP_OPT_ERROR_STRING, - &ld_error); - DEBUG(0, - ("failed to modify user with uid = %s with: %s\n\t%s\n", - pdb_get_username(newpwd), ldap_err2string(rc), - ld_error)); - free(ld_error); + ldap_msgfree(result); + + if (!ldapsam_modify_entry(ldap_struct,newpwd,dn,mods,LDAP_MOD_REPLACE)) { + DEBUG(0,("failed to modify user with uid = %s\n", + pdb_get_username(newpwd))); + ldap_mods_free(mods,1); ldap_unbind(ldap_struct); return False; } + DEBUG(2, ("successfully modified uid = %s in the LDAP database\n", pdb_get_username(newpwd))); @@ -1514,7 +1591,7 @@ static BOOL ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT LDAPMod **mods = NULL; int ldap_op; uint32 num_result; - + const char *username = pdb_get_username(newpwd); if (!username || !*username) { DEBUG(0, ("Cannot add user without a username!\n")); @@ -1522,20 +1599,16 @@ static BOOL ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT } if (!ldapsam_open_connection(ldap_state, &ldap_struct)) /* open a connection to the server */ - { return False; - } - if (!ldapsam_connect_system(ldap_state, ldap_struct)) /* connect as system account */ - { + if (!ldapsam_connect_system(ldap_state, ldap_struct)) { /* connect as system account */ ldap_unbind(ldap_struct); return False; } rc = ldapsam_search_one_user_by_name (ldap_state, ldap_struct, username, &result); - if (ldap_count_entries(ldap_struct, result) != 0) - { + if (ldap_count_entries(ldap_struct, result) != 0) { DEBUG(0,("User already in the base, with samba properties\n")); ldap_msgfree(result); ldap_unbind(ldap_struct); @@ -1564,8 +1637,7 @@ static BOOL ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT tmp = ldap_get_dn (ldap_struct, entry); slprintf (dn, sizeof (dn) - 1, "%s", tmp); ldap_memfree (tmp); - } - else { + } else { /* Check if we need to add an entry */ DEBUG(3,("Adding new user\n")); ldap_op = LDAP_MOD_ADD; @@ -1586,26 +1658,14 @@ static BOOL ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT } make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "sambaAccount"); - if (ldap_op == LDAP_MOD_REPLACE) { - rc = ldap_modify_s(ldap_struct, dn, mods); - } - else { - rc = ldap_add_s(ldap_struct, dn, mods); - } - - if (rc != LDAP_SUCCESS) - { - char *ld_error; - - ldap_get_option (ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); - DEBUG(0,("failed to modify/add user with uid = %s (dn = %s) with: %s\n\t%s\n", - pdb_get_username(newpwd), dn, ldap_err2string (rc), ld_error)); - free(ld_error); - ldap_mods_free(mods, 1); + if (!ldapsam_modify_entry(ldap_struct,newpwd,dn,mods,ldap_op)) { + DEBUG(0,("failed to modify/add user with uid = %s (dn = %s)\n", + pdb_get_username(newpwd),dn)); + ldap_mods_free(mods,1); ldap_unbind(ldap_struct); return False; } - + DEBUG(2,("added: uid = %s in the LDAP database\n", pdb_get_username(newpwd))); ldap_mods_free(mods, 1); ldap_unbind(ldap_struct); diff --git a/source3/passdb/pdb_nisplus.c b/source3/passdb/pdb_nisplus.c index 2d37c3b8fbb..484e8986e42 100644 --- a/source3/passdb/pdb_nisplus.c +++ b/source3/passdb/pdb_nisplus.c @@ -1,10 +1,11 @@ + /* - * Unix SMB/CIFS implementation. - * SMB parameters and setup + * NIS+ Passdb Backend * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995. * Copyright (C) Benny Holmgren 1998 * Copyright (C) Luke Kenneth Casson Leighton 1996-1998. * Copyright (C) Toomas Soome 2001 + * Copyright (C) Jelmer Vernooij 2002 * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free @@ -35,6 +36,7 @@ * an enum in /usr/include/rpcsvc/nis.h. */ + #if defined(GROUP) #undef GROUP #endif @@ -47,31 +49,20 @@ #include -extern int DEBUGLEVEL; - -struct nisp_enum_info -{ - nis_result *result; - int enum_entry; -}; - -static struct nisp_enum_info global_nisp_ent; -static SIG_ATOMIC_T gotalarm; - /*************************************************************** the fields for the NIS+ table, generated from mknissmbpwtbl.sh, are: - name=S,nogw=r - uid=S,nogw=r + name=S,nogw=r + uid=S,nogw=r user_rid=S,nogw=r smb_grpid=,nw+r group_rid=,nw+r acb=,nw+r - - lmpwd=C,nw=,g=r,o=rm - ntpwd=C,nw=,g=r,o=rm - + + lmpwd=C,nw=,g=r,o=rm + ntpwd=C,nw=,g=r,o=rm + logon_t=,nw+r logoff_t=,nw+r kick_t=,nw+r @@ -114,59 +105,576 @@ static SIG_ATOMIC_T gotalarm; #define NPF_WORKSTATIONS 20 #define NPF_HOURS 21 +struct nisplus_private_info { + nis_result *result; + int enum_entry; + char *location; +}; + +static char *make_nisname_from_user_rid (uint32 rid, char *pfile); +static char *make_nisname_from_name (const char *user_name, char *pfile); +static void get_single_attribute (const nis_object * new_obj, int col, + char *val, int len);; +static BOOL make_sam_from_nisp_object (SAM_ACCOUNT * pw_buf, + const nis_object * obj); +static BOOL make_sam_from_nisresult (SAM_ACCOUNT * pw_buf, + const nis_result * result);; +static void set_single_attribute (nis_object * new_obj, int col, + const char *val, int len, int flags); +static BOOL init_nisp_from_sam (nis_object * obj, const SAM_ACCOUNT * sampass, + nis_object * old); +static nis_result *nisp_get_nis_list (const char *nisname, + unsigned int flags); -/******************************************************************* - Converts NT user RID to a UNIX uid. - ********************************************************************/ +/*************************************************************** + Start enumeration of the passwd list. +****************************************************************/ -static uid_t pdb_user_rid_to_uid(uint32 user_rid) +static BOOL nisplussam_setsampwent (struct pdb_methods *methods, BOOL update) { - return (uid_t)(((user_rid & (~USER_RID_TYPE))- 1000)/RID_MULTIPLIER); -} + struct nisplus_private_info *private = + (struct nisplus_private_info *) methods->private_data; -/******************************************************************* - converts UNIX uid to an NT User RID. - ********************************************************************/ + char *sp; + pstring pfiletmp; -static uint32 pdb_uid_to_user_rid(uid_t uid) -{ - return (((((uint32)uid)*RID_MULTIPLIER) + 1000) | USER_RID_TYPE); + if ((sp = strrchr (private->location, '/'))) + safe_strcpy (pfiletmp, sp + 1, sizeof (pfiletmp) - 1); + else + safe_strcpy (pfiletmp, p, sizeof (pfiletmp) - 1); + safe_strcat (pfiletmp, ".org_dir", + sizeof (pfiletmp) - strlen (pfiletmp) - 1); + + pdb_endsampwent (); /* just in case */ + global_nisp_ent->result = nisp_get_nis_list (pfiletmp, 0); + global_nisp_ent->enum_entry = 0; + return global_nisp_ent->result != NULL ? True : False; } /*************************************************************** - Signal function to tell us we timed out. + End enumeration of the passwd list. ****************************************************************/ -static void gotalarm_sig(void) + +static void nisplussam_endsampwent (struct pdb_methods *methods) { - gotalarm = 1; + struct nisplus_private_info *global_nisp_ent = + (struct nisplus_private_info *) methods->private_data; + if (global_nisp_ent->result) + nis_freeresult (global_nisp_ent->result); + global_nisp_ent->result = NULL; + global_nisp_ent->enum_entry = 0; } -/*************************************************************** - make_nisname_from_user_rid - ****************************************************************/ -static char *make_nisname_from_user_rid(uint32 rid, char *pfile) +/***************************************************************** + Get one SAM_ACCOUNT from the list (next in line) +*****************************************************************/ + +static BOOL nisplussam_getsampwent (struct pdb_methods *methods, + SAM_ACCOUNT * user) { - static pstring nisname; - safe_strcpy(nisname, "[user_rid=", sizeof(nisname)-1); - slprintf(nisname, sizeof(nisname)-1, "%s%d", nisname, rid); - safe_strcat(nisname, "],", sizeof(nisname)-strlen(nisname)-1); - safe_strcat(nisname, pfile, sizeof(nisname)-strlen(nisname)-1); + struct nisplus_private_info *global_nisp_ent = + (struct nisplus_private_info *) methods->private_data; + int enum_entry = (int) (global_nisp_ent->enum_entry); + nis_result *result = global_nisp_ent->result; - return nisname; + if (user == NULL) { + DEBUG (0, ("SAM_ACCOUNT is NULL.\n")); + return False; + } + + if (result == NULL || + enum_entry < 0 || enum_entry >= (NIS_RES_NUMOBJ (result) - 1)) { + return False; + } + + if (!make_sam_from_nisp_object + (user, &NIS_RES_OBJECT (result)[enum_entry])) { + DEBUG (0, ("Bad SAM_ACCOUNT entry returned from NIS+!\n")); + return False; + } + (int) (global_nisp_ent->enum_entry)++; + return True; + DEBUG (10, ("nisplussam_getsampwent called\n")); + return False; +} + +/****************************************************************** + Lookup a name in the SAM database +******************************************************************/ + +static BOOL nisplussam_getsampwnam (struct pdb_methods *methods, + SAM_ACCOUNT * user, const char *sname) +{ + /* Static buffers we will return. */ + nis_result *result = NULL; + pstring nisname; + BOOL ret; + struct nisplus_private_info *private = + (struct nisplus_private_info *) methods->private_data; + + if (!private->location || !(*private->location)) { + DEBUG (0, ("No SMB password file set\n")); + return False; + } + if (strrchr (private->location, '/')) + private->location = strrchr (private->location, '/') + 1; + + slprintf (nisname, sizeof (nisname) - 1, "[name=%s],%s.org_dir", + sname, private->location); + DEBUG (10, ("search by nisname: %s\n", nisname)); + + /* Search the table. */ + + if (!(result = nisp_get_nis_list (nisname, 0))) { + return False; + } + + ret = make_sam_from_nisresult (user, result); + nis_freeresult (result); + + return ret; + + DEBUG (10, ("nisplussam_getsampwnam called\n")); + return False; +} + +/*************************************************************************** + Search by sid + **************************************************************************/ + +static BOOL nisplussam_getsampwrid (struct pdb_methods *methods, + SAM_ACCOUNT * user, uint32 rid) +{ + nis_result *result; + char *nisname; + BOOL ret; + char *sp; + pstring pfiletmp; + struct nisplus_private_info *private = + (struct nisplus_private_info *) methods->private_data; + + if (!private->location || !(*private->location)) { + DEBUG (0, ("no SMB password file set\n")); + return False; + } + + if ((sp = strrchr (private->location, '/'))) + safe_strcpy (pfiletmp, sp + 1, sizeof (pfiletmp) - 1); + else + safe_strcpy (pfiletmp, private->location, sizeof (pfiletmp) - 1); + safe_strcat (pfiletmp, ".org_dir", + sizeof (pfiletmp) - strlen (pfiletmp) - 1); + + nisname = make_nisname_from_user_rid (rid, pfiletmp); + + DEBUG (10, ("search by rid: %s\n", nisname)); + + /* Search the table. */ + + if (!(result = nisp_get_nis_list (nisname, 0))) { + return False; + } + + ret = make_sam_from_nisresult (user, result); + nis_freeresult (result); + + return ret; +} + +static BOOL nisplussam_getsampwsid (struct pdb_methods *methods, + SAM_ACCOUNT * user, const DOM_SID * sid) +{ + uint32 rid; + + if (!sid_peek_check_rid (get_global_sam_sid (), sid, &rid)) + return False; + return nisplussam_getsampwrid (methods, user, rid); +} + + + +/*************************************************************************** + Delete a SAM_ACCOUNT +****************************************************************************/ + +static BOOL nisplussam_delete_sam_account (struct pdb_methods *methods, + SAM_ACCOUNT * user) +{ + const char *sname; + pstring nisname; + nis_result *result, *delresult; + nis_object *obj; + struct nisplus_private_info *private = + (struct nisplus_private_info *) methods->private_data; + + if (!user) { + DEBUG (0, ("no SAM_ACCOUNT specified!\n")); + return False; + } + + sname = pdb_get_username (user); + + if (!private->location || !(*private->location)) { + DEBUG (0, ("no SMB password file set\n")); + return False; + } + + if (strrchr (private->location, '/')) + private->location = strrchr (private->location, '/') + 1; + + slprintf (nisname, sizeof (nisname) - 1, "[name=%s],%s.org_dir", + sname, private->location); + + /* Search the table. */ + + if (!(result = nisp_get_nis_list (nisname, + MASTER_ONLY | FOLLOW_LINKS | + FOLLOW_PATH | EXPAND_NAME | + HARD_LOOKUP))) { + return False; + } + + if (result->status != NIS_SUCCESS || NIS_RES_NUMOBJ (result) <= 0) { + /* User not found. */ + DEBUG (0, ("user not found in NIS+\n")); + nis_freeresult (result); + return False; + } + + obj = NIS_RES_OBJECT (result); + slprintf (nisname, sizeof (nisname) - 1, "[name=%s],%s.%s", sname, + obj->zo_name, obj->zo_domain); + + DEBUG (10, ("removing name: %s\n", nisname)); + delresult = nis_remove_entry (nisname, obj, + MASTER_ONLY | REM_MULTIPLE | ALL_RESULTS + | FOLLOW_PATH | EXPAND_NAME | + HARD_LOOKUP); + + nis_freeresult (result); + + if (delresult->status != NIS_SUCCESS) { + DEBUG (0, ("NIS+ table update failed: %s %s\n", + nisname, nis_sperrno (delresult->status))); + nis_freeresult (delresult); + return False; + } + nis_freeresult (delresult); + return True; + DEBUG (10, ("nisplussam_delete_sam_account called\n")); + return False; +} + +/*************************************************************************** + Modifies an existing SAM_ACCOUNT +****************************************************************************/ + +static BOOL nisplussam_update_sam_account (struct pdb_methods *methods, + SAM_ACCOUNT * newpwd) +{ + nis_result *result, *addresult; + nis_object *obj; + nis_object new_obj; + entry_col *ecol; + int ta_maxcol; + struct nisplus_private_info *private = + (struct nisplus_private_info *) methods->private_data; + pstring nisname; + + if (!private->location || !(*private->location)) { + DEBUG (0, ("no SMB password file set\n")); + return False; + } + if (strrchr (private->location, '/')) + private->location = strrchr (private->location, '/') + 1; + + slprintf (nisname, sizeof (nisname) - 1, "[name=%s],%s.org_dir", + pdb_get_username (newpwd), private->location); + + DEBUG (10, ("search by name: %s\n", nisname)); + + /* Search the table. */ + + if (! + (result = + nisp_get_nis_list (nisname, + MASTER_ONLY | FOLLOW_LINKS | FOLLOW_PATH | + EXPAND_NAME | HARD_LOOKUP))) { + return False; + } + + if (result->status != NIS_SUCCESS || NIS_RES_NUMOBJ (result) <= 0) { + /* User not found. */ + DEBUG (0, ("user not found in NIS+\n")); + nis_freeresult (result); + return False; + } + + obj = NIS_RES_OBJECT (result); + DEBUG (6, ("entry found in %s\n", obj->zo_domain)); + + /* we must create new stub object with EN_MODIFIED flag. + this is because obj from result is going to be freed and + we do not want to break it or cause memory leaks or corruption. + */ + + memmove ((char *) &new_obj, obj, sizeof (new_obj)); + ta_maxcol = obj->TA_data.ta_maxcol; + + if (!(ecol = (entry_col *) malloc (ta_maxcol * sizeof (entry_col)))) { + DEBUG (0, ("memory allocation failure\n")); + nis_freeresult (result); + return False; + } + + memmove ((char *) ecol, obj->EN_data.en_cols.en_cols_val, + ta_maxcol * sizeof (entry_col)); + new_obj.EN_data.en_cols.en_cols_val = ecol; + new_obj.EN_data.en_cols.en_cols_len = ta_maxcol; + + if (init_nisp_from_sam (&new_obj, newpwd, obj) == True) { + slprintf (nisname, sizeof (nisname) - 1, "[name=%s],%s.%s", + pdb_get_username (newpwd), private->location, obj->zo_domain); + + DEBUG (10, ("NIS+ table update: %s\n", nisname)); + addresult = + nis_modify_entry (nisname, &new_obj, + MOD_SAMEOBJ | FOLLOW_PATH | + EXPAND_NAME | HARD_LOOKUP); + + if (addresult->status != NIS_SUCCESS) { + DEBUG (0, ("NIS+ table update failed: %s %s\n", + nisname, nis_sperrno (addresult->status))); + nis_freeresult (addresult); + nis_freeresult (result); + free (ecol); + return False; + } + + DEBUG (6, ("password changed\n")); + nis_freeresult (addresult); + } else { + DEBUG (6, ("nothing to change!\n")); + } + + free (ecol); + nis_freeresult (result); + + return True; +} + +/*************************************************************************** + Adds an existing SAM_ACCOUNT +****************************************************************************/ + +static BOOL nisplussam_add_sam_account (struct pdb_methods *methods, + SAM_ACCOUNT * newpwd) +{ + int local_user = 0; + char *pfile; + pstring pfiletmp; + char *nisname; + nis_result *result = NULL, *tblresult = NULL; + nis_object new_obj; + entry_col *ecol; + int ta_maxcol; + + /* + * 1. find user domain. + * a. try nis search in passwd.org_dir - if found use domain from result. + * b. try getpwnam. this may be needed if user is defined + * in /etc/passwd file (or elsewere) and not in passwd.org_dir. + * if found, use host default domain. + * c. exit with False - no such user. + * + * 2. add user + * a. find smbpasswd table + * search pfile in user domain if not found, try host default + * domain. + * b. smbpasswd domain is found, fill data and add entry. + * + * pfile should contain ONLY table name, org_dir will be concated. + * so, at first we will clear path prefix from pfile, and + * then we will use pfiletmp as playground to put together full + * nisname string. + * such approach will make it possible to specify samba private dir + * AND still use NIS+ table. as all domain related data is normally + * stored in org_dir.DOMAIN, this should be ok do do. + */ + + pfile = private->location; + if (strrchr (pfile, '/')) + pfile = strrchr (pfile, '/') + 1; + + /* + * Check if user is already there. + */ + safe_strcpy (pfiletmp, pfile, sizeof (pfiletmp) - 1); + safe_strcat (pfiletmp, ".org_dir", + sizeof (pfiletmp) - strlen (pfiletmp) - 1); + + if (pdb_get_username (newpwd) != NULL) { + nisname = make_nisname_from_name (pdb_get_username (newpwd), + pfiletmp); + } else { + return False; + } + + if (! + (result = + nisp_get_nis_list (nisname, + MASTER_ONLY | FOLLOW_LINKS | FOLLOW_PATH | + EXPAND_NAME | HARD_LOOKUP))) { + return False; + } + if (result->status != NIS_SUCCESS && result->status != NIS_NOTFOUND) { + DEBUG (3, ("nis_list failure: %s: %s\n", + nisname, nis_sperrno (result->status))); + nis_freeresult (result); + return False; + } + + if (result->status == NIS_SUCCESS && NIS_RES_NUMOBJ (result) > 0) { + DEBUG (3, ("User already exists in NIS+ password db: %s\n", + pfile)); + nis_freeresult (result); + return False; + } + + nis_freeresult (result); /* no such user, free results */ + + /* + * check for user in unix password database. we need this to get + * domain, where smbpasswd entry should be stored. + */ + + nisname = make_nisname_from_name (pdb_get_username (newpwd), + "passwd.org_dir"); + + result = nisp_get_nis_list (nisname, + MASTER_ONLY | FOLLOW_LINKS | FOLLOW_PATH | + EXPAND_NAME | HARD_LOOKUP); + + if (result->status != NIS_SUCCESS || NIS_RES_NUMOBJ (result) <= 0) { + struct passwd *passwd; + + DEBUG (3, ("nis_list failure: %s: %s\n", + nisname, nis_sperrno (result->status))); + nis_freeresult (result); + + if (!(passwd = getpwnam_alloc (pdb_get_username (newpwd)))) { + /* no such user in system! */ + return False; + } + passwd_free (&passwd); + + /* + * user is defined, but not in passwd.org_dir. + */ + local_user = 1; + } else { + safe_strcpy (pfiletmp, pfile, sizeof (pfiletmp) - 1); + safe_strcat (pfiletmp, ".", + sizeof (pfiletmp) - strlen (pfiletmp) - 1); + safe_strcat (pfiletmp, NIS_RES_OBJECT (result)->zo_domain, + sizeof (pfiletmp) - strlen (pfiletmp) - 1); + nis_freeresult (result); /* not needed any more */ + + tblresult = nisp_get_nis_list (pfiletmp, + MASTER_ONLY | FOLLOW_LINKS | + FOLLOW_PATH | EXPAND_NAME | + HARD_LOOKUP); + } + + if (local_user || tblresult->status != NIS_SUCCESS) { + /* + * no user domain or + * smbpasswd table not found in user domain, fallback to + * default domain. + */ + if (!local_user) /* free previous failed search result */ + nis_freeresult (tblresult); + + safe_strcpy (pfiletmp, pfile, sizeof (pfiletmp) - 1); + safe_strcat (pfiletmp, ".org_dir", + sizeof (pfiletmp) - strlen (pfiletmp) - 1); + tblresult = nis_lookup (pfiletmp, MASTER_ONLY | FOLLOW_LINKS | + FOLLOW_PATH | EXPAND_NAME | + HARD_LOOKUP); + if (tblresult->status != NIS_SUCCESS) { + /* still nothing. bail out */ + nis_freeresult (tblresult); + DEBUG (3, ("nis_lookup failure: %s\n", + nis_sperrno (tblresult->status))); + return False; + } + /* we need full name for nis_add_entry() */ + safe_strcpy (pfiletmp, pfile, sizeof (pfiletmp) - 1); + safe_strcat (pfiletmp, ".", + sizeof (pfiletmp) - strlen (pfiletmp) - 1); + safe_strcat (pfiletmp, NIS_RES_OBJECT (tblresult)->zo_domain, + sizeof (pfiletmp) - strlen (pfiletmp) - 1); + } + + memset ((char *) &new_obj, 0, sizeof (new_obj)); + /* fill entry headers */ + /* we do not free these. */ + new_obj.zo_name = NIS_RES_OBJECT (tblresult)->zo_name; + new_obj.zo_owner = NIS_RES_OBJECT (tblresult)->zo_owner; + new_obj.zo_group = NIS_RES_OBJECT (tblresult)->zo_group; + new_obj.zo_domain = NIS_RES_OBJECT (tblresult)->zo_domain; + /* uints */ + new_obj.zo_access = NIS_RES_OBJECT (tblresult)->zo_access; + new_obj.zo_ttl = NIS_RES_OBJECT (tblresult)->zo_ttl; + + new_obj.zo_data.zo_type = ENTRY_OBJ; + new_obj.EN_data.en_type = NIS_RES_OBJECT (tblresult)->TA_data.ta_type; + + ta_maxcol = NIS_RES_OBJECT (tblresult)->TA_data.ta_maxcol; + + if (!(ecol = (entry_col *) malloc (ta_maxcol * sizeof (entry_col)))) { + DEBUG (0, ("memory allocation failure\n")); + nis_freeresult (tblresult); + return False; + } + + memset ((char *) ecol, 0, ta_maxcol * sizeof (entry_col)); + new_obj.EN_data.en_cols.en_cols_val = ecol; + new_obj.EN_data.en_cols.en_cols_len = ta_maxcol; + + init_nisp_from_sam (&new_obj, newpwd, NULL); + + DEBUG (10, ("add NIS+ entry: %s\n", nisname)); + result = nis_add_entry (pfiletmp, &new_obj, 0); + + free (ecol); /* free allocated entry space */ + + if (result->status != NIS_SUCCESS) { + DEBUG (3, ("NIS+ table update failed: %s,%s\n", + nisname, nis_sperrno (result->status))); + nis_freeresult (tblresult); + nis_freeresult (result); + return False; + } + + nis_freeresult (tblresult); + nis_freeresult (result); + + return True; } /*************************************************************** - make_nisname_from_uid + make_nisname_from_user_rid ****************************************************************/ -static char *make_nisname_from_uid(int uid, char *pfile) +static char *make_nisname_from_user_rid (uint32 rid, char *pfile) { static pstring nisname; - safe_strcpy(nisname, "[uid=", sizeof(nisname)-1); - slprintf(nisname, sizeof(nisname)-1, "%s%d", nisname, uid); - safe_strcat(nisname, "],", sizeof(nisname)-strlen(nisname)-1); - safe_strcat(nisname, pfile, sizeof(nisname)-strlen(nisname)-1); + safe_strcpy (nisname, "[user_rid=", sizeof (nisname) - 1); + slprintf (nisname, sizeof (nisname) - 1, "%s%d", nisname, rid); + safe_strcat (nisname, "],", sizeof (nisname) - strlen (nisname) - 1); + safe_strcat (nisname, pfile, sizeof (nisname) - strlen (nisname) - 1); return nisname; } @@ -174,14 +682,15 @@ static char *make_nisname_from_uid(int uid, char *pfile) /*************************************************************** make_nisname_from_name ****************************************************************/ -static char *make_nisname_from_name(const char *user_name, char *pfile) +static char *make_nisname_from_name (const char *user_name, char *pfile) { static pstring nisname; - safe_strcpy(nisname, "[name=", sizeof(nisname)-1); - safe_strcat(nisname, user_name, sizeof(nisname) - strlen(nisname) - 1); - safe_strcat(nisname, "],", sizeof(nisname)-strlen(nisname)-1); - safe_strcat(nisname, pfile, sizeof(nisname)-strlen(nisname)-1); + safe_strcpy (nisname, "[name=", sizeof (nisname) - 1); + safe_strcat (nisname, user_name, + sizeof (nisname) - strlen (nisname) - 1); + safe_strcat (nisname, "],", sizeof (nisname) - strlen (nisname) - 1); + safe_strcat (nisname, pfile, sizeof (nisname) - strlen (nisname) - 1); return nisname; } @@ -189,297 +698,323 @@ static char *make_nisname_from_name(const char *user_name, char *pfile) /************************************************************************* gets a NIS+ attribute *************************************************************************/ -static void get_single_attribute(const nis_object *new_obj, int col, - char *val, int len) +static void get_single_attribute (const nis_object * new_obj, int col, + char *val, int len) { int entry_len; - if (new_obj == NULL || val == NULL) return; - - entry_len = ENTRY_LEN(new_obj, col); - if (len > entry_len) - { + if (new_obj == NULL || val == NULL) + return; + + entry_len = ENTRY_LEN (new_obj, col); + if (len > entry_len) { len = entry_len; } - safe_strcpy(val, ENTRY_VAL(new_obj, col), len-1); + safe_strcpy (val, ENTRY_VAL (new_obj, col), len - 1); } /************************************************************************ makes a struct sam_passwd from a NIS+ object. ************************************************************************/ -static BOOL make_sam_from_nisp_object(SAM_ACCOUNT *pw_buf, const nis_object *obj) +static BOOL make_sam_from_nisp_object (SAM_ACCOUNT * pw_buf, + const nis_object * obj) { - char *ptr; - pstring full_name; /* this must be translated to dos code page */ - pstring acct_desc; /* this must be translated to dos code page */ - pstring home_dir; /* set default value from smb.conf for user */ - pstring home_drive; /* set default value from smb.conf for user */ - pstring logon_script; /* set default value from smb.conf for user */ - pstring profile_path; /* set default value from smb.conf for user */ - pstring hours; - int hours_len; - unsigned char smbpwd[16]; - unsigned char smbntpwd[16]; - - - /* - * time values. note: this code assumes 32bit time_t! - */ - - /* Don't change these timestamp settings without a good reason. They are - important for NT member server compatibility. */ - - pdb_set_logon_time(pw_buf, (time_t)0, True); - ptr = (uchar *)ENTRY_VAL(obj, NPF_LOGON_T); - if(ptr && *ptr && (StrnCaseCmp(ptr, "LNT-", 4)==0)) { - int i; - ptr += 4; - for(i = 0; i < 8; i++) { - if(ptr[i] == '\0' || !isxdigit(ptr[i])) - break; - } - if(i == 8) { - pdb_set_logon_time(pw_buf, (time_t)strtol(ptr, NULL, 16), True); - } - } - - pdb_set_logoff_time(pw_buf, get_time_t_max(), True); - ptr = (uchar *)ENTRY_VAL(obj, NPF_LOGOFF_T); - if(ptr && *ptr && (StrnCaseCmp(ptr, "LOT-", 4)==0)) { - int i; - ptr += 4; - for(i = 0; i < 8; i++) { - if(ptr[i] == '\0' || !isxdigit(ptr[i])) - break; - } - if(i == 8) { - pdb_set_logoff_time(pw_buf, (time_t)strtol(ptr, NULL, 16), True); - } - } - - pdb_set_kickoff_time(pw_buf, get_time_t_max(), True); - ptr = (uchar *)ENTRY_VAL(obj, NPF_KICK_T); - if(ptr && *ptr && (StrnCaseCmp(ptr, "KOT-", 4)==0)) { - int i; - ptr += 4; - for(i = 0; i < 8; i++) { - if(ptr[i] == '\0' || !isxdigit(ptr[i])) - break; - } - if(i == 8) { - pdb_set_kickoff_time(pw_buf, (time_t)strtol(ptr, NULL, 16), True); - } - } - - pdb_set_pass_last_set_time(pw_buf, (time_t)0); - ptr = (uchar *)ENTRY_VAL(obj, NPF_PWDLSET_T); - if(ptr && *ptr && (StrnCaseCmp(ptr, "LCT-", 4)==0)) { - int i; - ptr += 4; - for(i = 0; i < 8; i++) { - if(ptr[i] == '\0' || !isxdigit(ptr[i])) - break; - } - if(i == 8) { - pdb_set_pass_last_set_time(pw_buf, (time_t)strtol(ptr, NULL, 16)); - } - } - - pdb_set_pass_can_change_time(pw_buf, (time_t)0, True); - ptr = (uchar *)ENTRY_VAL(obj, NPF_PWDCCHG_T); - if(ptr && *ptr && (StrnCaseCmp(ptr, "CCT-", 4)==0)) { - int i; - ptr += 4; - for(i = 0; i < 8; i++) { - if(ptr[i] == '\0' || !isxdigit(ptr[i])) - break; - } - if(i == 8) { - pdb_set_pass_can_change_time(pw_buf, (time_t)strtol(ptr, NULL, 16), True); - } - } - - pdb_set_pass_must_change_time(pw_buf, get_time_t_max(), True); /* Password never expires. */ - ptr = (uchar *)ENTRY_VAL(obj, NPF_PWDMCHG_T); - if(ptr && *ptr && (StrnCaseCmp(ptr, "MCT-", 4)==0)) { - int i; - ptr += 4; - for(i = 0; i < 8; i++) { - if(ptr[i] == '\0' || !isxdigit(ptr[i])) - break; - } - if(i == 8) { - pdb_set_pass_must_change_time(pw_buf, (time_t)strtol(ptr, NULL, 16), True); - } - } - - /* string values */ - pdb_set_username(pw_buf, ENTRY_VAL(obj, NPF_NAME)); - pdb_set_domain(pw_buf, lp_workgroup()); - /* pdb_set_nt_username() -- cant set it here... */ - - get_single_attribute(obj, NPF_FULL_NAME, full_name, sizeof(pstring)); + char *ptr; + pstring full_name; /* this must be translated to dos code page */ + pstring acct_desc; /* this must be translated to dos code page */ + pstring home_dir; /* set default value from smb.conf for user */ + pstring home_drive; /* set default value from smb.conf for user */ + pstring logon_script; /* set default value from smb.conf for user */ + pstring profile_path; /* set default value from smb.conf for user */ + pstring hours; + int hours_len; + unsigned char smbpwd[16]; + unsigned char smbntpwd[16]; + + + /* + * time values. note: this code assumes 32bit time_t! + */ + + /* Don't change these timestamp settings without a good reason. They are + important for NT member server compatibility. */ + + pdb_set_logon_time (pw_buf, (time_t) 0, True); + ptr = (uchar *) ENTRY_VAL (obj, NPF_LOGON_T); + if (ptr && *ptr && (StrnCaseCmp (ptr, "LNT-", 4) == 0)) { + int i; + + ptr += 4; + for (i = 0; i < 8; i++) { + if (ptr[i] == '\0' || !isxdigit (ptr[i])) + break; + } + if (i == 8) { + pdb_set_logon_time (pw_buf, + (time_t) strtol (ptr, NULL, 16), + True); + } + } + + pdb_set_logoff_time (pw_buf, get_time_t_max (), True); + ptr = (uchar *) ENTRY_VAL (obj, NPF_LOGOFF_T); + if (ptr && *ptr && (StrnCaseCmp (ptr, "LOT-", 4) == 0)) { + int i; + + ptr += 4; + for (i = 0; i < 8; i++) { + if (ptr[i] == '\0' || !isxdigit (ptr[i])) + break; + } + if (i == 8) { + pdb_set_logoff_time (pw_buf, + (time_t) strtol (ptr, NULL, 16), + True); + } + } + + pdb_set_kickoff_time (pw_buf, get_time_t_max (), True); + ptr = (uchar *) ENTRY_VAL (obj, NPF_KICK_T); + if (ptr && *ptr && (StrnCaseCmp (ptr, "KOT-", 4) == 0)) { + int i; + + ptr += 4; + for (i = 0; i < 8; i++) { + if (ptr[i] == '\0' || !isxdigit (ptr[i])) + break; + } + if (i == 8) { + pdb_set_kickoff_time (pw_buf, + (time_t) strtol (ptr, NULL, 16), + True); + } + } + + pdb_set_pass_last_set_time (pw_buf, (time_t) 0); + ptr = (uchar *) ENTRY_VAL (obj, NPF_PWDLSET_T); + if (ptr && *ptr && (StrnCaseCmp (ptr, "LCT-", 4) == 0)) { + int i; + + ptr += 4; + for (i = 0; i < 8; i++) { + if (ptr[i] == '\0' || !isxdigit (ptr[i])) + break; + } + if (i == 8) { + pdb_set_pass_last_set_time (pw_buf, + (time_t) strtol (ptr, + NULL, + 16)); + } + } + + pdb_set_pass_can_change_time (pw_buf, (time_t) 0, True); + ptr = (uchar *) ENTRY_VAL (obj, NPF_PWDCCHG_T); + if (ptr && *ptr && (StrnCaseCmp (ptr, "CCT-", 4) == 0)) { + int i; + + ptr += 4; + for (i = 0; i < 8; i++) { + if (ptr[i] == '\0' || !isxdigit (ptr[i])) + break; + } + if (i == 8) { + pdb_set_pass_can_change_time (pw_buf, + (time_t) strtol (ptr, + NULL, + 16), + True); + } + } + + pdb_set_pass_must_change_time (pw_buf, get_time_t_max (), True); /* Password never expires. */ + ptr = (uchar *) ENTRY_VAL (obj, NPF_PWDMCHG_T); + if (ptr && *ptr && (StrnCaseCmp (ptr, "MCT-", 4) == 0)) { + int i; + + ptr += 4; + for (i = 0; i < 8; i++) { + if (ptr[i] == '\0' || !isxdigit (ptr[i])) + break; + } + if (i == 8) { + pdb_set_pass_must_change_time (pw_buf, + (time_t) strtol (ptr, + NULL, + 16), + True); + } + } + + /* string values */ + pdb_set_username (pw_buf, ENTRY_VAL (obj, NPF_NAME)); + pdb_set_domain (pw_buf, lp_workgroup ()); + /* pdb_set_nt_username() -- cant set it here... */ + + get_single_attribute (obj, NPF_FULL_NAME, full_name, + sizeof (pstring)); #if 0 - unix_to_dos(full_name, True); + unix_to_dos (full_name, True); #endif - pdb_set_fullname(pw_buf, full_name); + pdb_set_fullname (pw_buf, full_name); - pdb_set_acct_ctrl(pw_buf, pdb_decode_acct_ctrl(ENTRY_VAL(obj, - NPF_ACB))); + pdb_set_acct_ctrl (pw_buf, pdb_decode_acct_ctrl (ENTRY_VAL (obj, + NPF_ACB))); - get_single_attribute(obj, NPF_ACCT_DESC, acct_desc, sizeof(pstring)); + get_single_attribute (obj, NPF_ACCT_DESC, acct_desc, + sizeof (pstring)); #if 0 - unix_to_dos(acct_desc, True); + unix_to_dos (acct_desc, True); #endif - pdb_set_acct_desc(pw_buf, acct_desc); - - pdb_set_workstations(pw_buf, ENTRY_VAL(obj, NPF_WORKSTATIONS)); - pdb_set_munged_dial(pw_buf, NULL); - - pdb_set_uid(pw_buf, atoi(ENTRY_VAL(obj, NPF_UID))); - pdb_set_gid(pw_buf, atoi(ENTRY_VAL(obj, NPF_SMB_GRPID))); - pdb_set_user_sid_from_rid(pw_buf, atoi(ENTRY_VAL(obj, NPF_USER_RID))); - pdb_set_group_sid_from_rid(pw_buf, atoi(ENTRY_VAL(obj, NPF_GROUP_RID))); - - /* values, must exist for user */ - if( !(pdb_get_acct_ctrl(pw_buf) & ACB_WSTRUST) ) { - - get_single_attribute(obj, NPF_HOME_DIR, home_dir, sizeof(pstring)); - if( !(home_dir && *home_dir) ) { - pstrcpy(home_dir, lp_logon_home()); - pdb_set_homedir(pw_buf, home_dir, False); - } - else - pdb_set_homedir(pw_buf, home_dir, True); - - get_single_attribute(obj, NPF_DIR_DRIVE, home_drive, sizeof(pstring)); - if( !(home_drive && *home_drive) ) { - pstrcpy(home_drive, lp_logon_drive()); - pdb_set_dir_drive(pw_buf, home_drive, False); - } - else - pdb_set_dir_drive(pw_buf, home_drive, True); - - get_single_attribute(obj, NPF_LOGON_SCRIPT, logon_script, - sizeof(pstring)); - if( !(logon_script && *logon_script) ) { - pstrcpy(logon_script, lp_logon_script()); - } - else - pdb_set_logon_script(pw_buf, logon_script, True); - - get_single_attribute(obj, NPF_PROFILE_PATH, profile_path, sizeof(pstring)); - if( !(profile_path && *profile_path) ) { - pstrcpy(profile_path, lp_logon_path()); - pdb_set_profile_path(pw_buf, profile_path, False); - } - else - pdb_set_profile_path(pw_buf, profile_path, True); - - } - else - { - /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */ - pdb_set_group_sid_from_rid (pw_buf, DOMAIN_GROUP_RID_USERS); - } - - /* Check the lanman password column. */ - ptr = (char *)ENTRY_VAL(obj, NPF_LMPWD); - if (!pdb_set_lanman_passwd(pw_buf, NULL)) - return False; + pdb_set_acct_desc (pw_buf, acct_desc); + + pdb_set_workstations (pw_buf, ENTRY_VAL (obj, NPF_WORKSTATIONS)); + pdb_set_munged_dial (pw_buf, NULL); + + pdb_set_uid (pw_buf, atoi (ENTRY_VAL (obj, NPF_UID))); + pdb_set_gid (pw_buf, atoi (ENTRY_VAL (obj, NPF_SMB_GRPID))); + pdb_set_user_sid_from_rid (pw_buf, + atoi (ENTRY_VAL (obj, NPF_USER_RID))); + pdb_set_group_sid_from_rid (pw_buf, + atoi (ENTRY_VAL (obj, NPF_GROUP_RID))); + + /* values, must exist for user */ + if (!(pdb_get_acct_ctrl (pw_buf) & ACB_WSTRUST)) { + + get_single_attribute (obj, NPF_HOME_DIR, home_dir, + sizeof (pstring)); + if (!(home_dir && *home_dir)) { + pstrcpy (home_dir, lp_logon_home ()); + pdb_set_homedir (pw_buf, home_dir, False); + } else + pdb_set_homedir (pw_buf, home_dir, True); + + get_single_attribute (obj, NPF_DIR_DRIVE, home_drive, + sizeof (pstring)); + if (!(home_drive && *home_drive)) { + pstrcpy (home_drive, lp_logon_drive ()); + pdb_set_dir_drive (pw_buf, home_drive, False); + } else + pdb_set_dir_drive (pw_buf, home_drive, True); + + get_single_attribute (obj, NPF_LOGON_SCRIPT, logon_script, + sizeof (pstring)); + if (!(logon_script && *logon_script)) { + pstrcpy (logon_script, lp_logon_script ()); + } else + pdb_set_logon_script (pw_buf, logon_script, True); + + get_single_attribute (obj, NPF_PROFILE_PATH, profile_path, + sizeof (pstring)); + if (!(profile_path && *profile_path)) { + pstrcpy (profile_path, lp_logon_path ()); + pdb_set_profile_path (pw_buf, profile_path, False); + } else + pdb_set_profile_path (pw_buf, profile_path, True); + + } else { + /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */ + pdb_set_group_sid_from_rid (pw_buf, DOMAIN_GROUP_RID_USERS); + } - if (!strncasecmp(ptr, "NO PASSWORD", 11)) { - pdb_set_acct_ctrl(pw_buf, pdb_get_acct_ctrl(pw_buf) | ACB_PWNOTREQ); - } else { - if (strlen(ptr) != 32 || !pdb_gethexpwd(ptr, smbpwd)) { - DEBUG(0, ("malformed LM pwd entry: %s.\n", - pdb_get_username(pw_buf))); - return False; - } - if (!pdb_set_lanman_passwd(pw_buf, smbpwd)) + /* Check the lanman password column. */ + ptr = (char *) ENTRY_VAL (obj, NPF_LMPWD); + if (!pdb_set_lanman_passwd (pw_buf, NULL)) return False; - } - - /* Check the NT password column. */ - ptr = ENTRY_VAL(obj, NPF_NTPWD); - if (!pdb_set_nt_passwd(pw_buf, NULL)) - return False; - - if (!(pdb_get_acct_ctrl(pw_buf) & ACB_PWNOTREQ) && - strncasecmp(ptr, "NO PASSWORD", 11)) { - if (strlen(ptr) != 32 || !pdb_gethexpwd(ptr, smbntpwd)) { - DEBUG(0, ("malformed NT pwd entry:\ - uid = %d.\n", - pdb_get_uid(pw_buf))); - return False; - } - if (!pdb_set_nt_passwd(pw_buf, smbntpwd)) + + if (!strncasecmp (ptr, "NO PASSWORD", 11)) { + pdb_set_acct_ctrl (pw_buf, + pdb_get_acct_ctrl (pw_buf) | ACB_PWNOTREQ); + } else { + if (strlen (ptr) != 32 || !pdb_gethexpwd (ptr, smbpwd)) { + DEBUG (0, ("malformed LM pwd entry: %s.\n", + pdb_get_username (pw_buf))); + return False; + } + if (!pdb_set_lanman_passwd (pw_buf, smbpwd)) + return False; + } + + /* Check the NT password column. */ + ptr = ENTRY_VAL (obj, NPF_NTPWD); + if (!pdb_set_nt_passwd (pw_buf, NULL)) return False; - } - - pdb_set_unknown_3(pw_buf, 0xffffff); /* don't know */ - pdb_set_logon_divs(pw_buf, 168); /* hours per week */ - - if( (hours_len = ENTRY_LEN(obj, NPF_HOURS)) == 21 ) { - memcpy(hours, ENTRY_VAL(obj, NPF_HOURS), hours_len); - } else { - hours_len = 21; /* 21 times 8 bits = 168 */ - /* available at all hours */ - memset(hours, 0xff, hours_len); - } - pdb_set_hours_len(pw_buf, hours_len); - pdb_set_hours(pw_buf, hours); - - pdb_set_unknown_5(pw_buf, 0x00020000); /* don't know */ - pdb_set_unknown_6(pw_buf, 0x000004ec); /* don't know */ - - return True; + + if (!(pdb_get_acct_ctrl (pw_buf) & ACB_PWNOTREQ) && + strncasecmp (ptr, "NO PASSWORD", 11)) { + if (strlen (ptr) != 32 || !pdb_gethexpwd (ptr, smbntpwd)) { + DEBUG (0, ("malformed NT pwd entry:\ + uid = %d.\n", pdb_get_uid (pw_buf))); + return False; + } + if (!pdb_set_nt_passwd (pw_buf, smbntpwd)) + return False; + } + + pdb_set_unknown_3 (pw_buf, 0xffffff); /* don't know */ + pdb_set_logon_divs (pw_buf, 168); /* hours per week */ + + if ((hours_len = ENTRY_LEN (obj, NPF_HOURS)) == 21) { + memcpy (hours, ENTRY_VAL (obj, NPF_HOURS), hours_len); + } else { + hours_len = 21; /* 21 times 8 bits = 168 */ + /* available at all hours */ + memset (hours, 0xff, hours_len); + } + pdb_set_hours_len (pw_buf, hours_len); + pdb_set_hours (pw_buf, hours); + + pdb_set_unknown_5 (pw_buf, 0x00020000); /* don't know */ + pdb_set_unknown_6 (pw_buf, 0x000004ec); /* don't know */ + + return True; } /************************************************************************ makes a struct sam_passwd from a NIS+ result. ************************************************************************/ -static BOOL make_sam_from_nisresult(SAM_ACCOUNT *pw_buf, const nis_result *result) +static BOOL make_sam_from_nisresult (SAM_ACCOUNT * pw_buf, + const nis_result * result) { - if (pw_buf == NULL || result == NULL) return False; + if (pw_buf == NULL || result == NULL) + return False; - if (result->status != NIS_SUCCESS && result->status != NIS_NOTFOUND) - { - DEBUG(0, ("NIS+ lookup failure: %s\n", - nis_sperrno(result->status))); + if (result->status != NIS_SUCCESS && result->status != NIS_NOTFOUND) { + DEBUG (0, ("NIS+ lookup failure: %s\n", + nis_sperrno (result->status))); return False; } /* User not found. */ - if (NIS_RES_NUMOBJ(result) <= 0) - { - DEBUG(10, ("user not found in NIS+\n")); + if (NIS_RES_NUMOBJ (result) <= 0) { + DEBUG (10, ("user not found in NIS+\n")); return False; } - if (NIS_RES_NUMOBJ(result) > 1) - { - DEBUG(10, ("WARNING: Multiple entries for user in NIS+ table!\n")); + if (NIS_RES_NUMOBJ (result) > 1) { + DEBUG (10, + ("WARNING: Multiple entries for user in NIS+ table!\n")); } /* Grab the first hit. */ - return make_sam_from_nisp_object(pw_buf, &NIS_RES_OBJECT(result)[0]); + return make_sam_from_nisp_object (pw_buf, + &NIS_RES_OBJECT (result)[0]); } /************************************************************************* sets a NIS+ attribute *************************************************************************/ -static void set_single_attribute(nis_object *new_obj, int col, - const char *val, int len, int flags) +static void set_single_attribute (nis_object * new_obj, int col, + const char *val, int len, int flags) { - if (new_obj == NULL) return; + if (new_obj == NULL) + return; - ENTRY_VAL(new_obj, col) = val; - ENTRY_LEN(new_obj, col) = len+1; + ENTRY_VAL (new_obj, col) = val; + ENTRY_LEN (new_obj, col) = len + 1; - if (flags != 0) - { + if (flags != 0) { new_obj->EN_data.en_cols.en_cols_val[col].ec_flags = flags; } } @@ -488,951 +1023,523 @@ static void set_single_attribute(nis_object *new_obj, int col, copy or modify nis object. this object is used to add or update nisplus table entry. ****************************************************************/ -static BOOL init_nisp_from_sam(nis_object *obj, const SAM_ACCOUNT *sampass, - nis_object *old) +static BOOL init_nisp_from_sam (nis_object * obj, const SAM_ACCOUNT * sampass, + nis_object * old) { - /* - * Fill nis_object for entry add or update. - * if we are updateing, we have to find out differences and set - * EN_MODIFIED flag. also set need_to_modify to trigger - * nis_modify_entry() call in pdb_update_sam_account(). - * - * TODO: - * get data from SAM - * if (modify) get data from nis_object, compare and store if - * different + set EN_MODIFIED and need_to_modify - * else - * store - */ - BOOL need_to_modify = False; - const char *name = pdb_get_username(sampass); /* from SAM */ - /* these must be static or allocate and free entry columns! */ - static fstring uid; /* from SAM */ - static fstring user_rid; /* from SAM */ - static fstring gid; /* from SAM */ - static fstring group_rid; /* from SAM */ - char *acb; /* from SAM */ - static fstring smb_passwd; /* from SAM */ - static fstring smb_nt_passwd; /* from SAM */ - static fstring logon_t; /* from SAM */ - static fstring logoff_t; /* from SAM */ - static fstring kickoff_t; /* from SAM */ - static fstring pwdlset_t; /* from SAM */ - static fstring pwdlchg_t; /* from SAM */ - static fstring pwdmchg_t; /* from SAM */ - static fstring full_name; /* from SAM */ - static fstring acct_desc; /* from SAM */ - static char empty[1]; /* just an empty string */ - - slprintf(uid, sizeof(uid)-1, "%u", pdb_get_uid(sampass)); - slprintf(user_rid, sizeof(user_rid)-1, "%u", - pdb_get_user_rid(sampass)? pdb_get_user_rid(sampass): - pdb_uid_to_user_rid(pdb_get_uid(sampass))); - slprintf(gid, sizeof(gid)-1, "%u", pdb_get_gid(sampass)); + /* + * Fill nis_object for entry add or update. + * if we are updateing, we have to find out differences and set + * EN_MODIFIED flag. also set need_to_modify to trigger + * nis_modify_entry() call in pdb_update_sam_account(). + * + * TODO: + * get data from SAM + * if (modify) get data from nis_object, compare and store if + * different + set EN_MODIFIED and need_to_modify + * else + * store + */ + BOOL need_to_modify = False; + const char *name = pdb_get_username (sampass); /* from SAM */ + + /* these must be static or allocate and free entry columns! */ + static fstring uid; /* from SAM */ + static fstring user_rid; /* from SAM */ + static fstring gid; /* from SAM */ + static fstring group_rid; /* from SAM */ + char *acb; /* from SAM */ + static fstring smb_passwd; /* from SAM */ + static fstring smb_nt_passwd; /* from SAM */ + static fstring logon_t; /* from SAM */ + static fstring logoff_t; /* from SAM */ + static fstring kickoff_t; /* from SAM */ + static fstring pwdlset_t; /* from SAM */ + static fstring pwdlchg_t; /* from SAM */ + static fstring pwdmchg_t; /* from SAM */ + static fstring full_name; /* from SAM */ + static fstring acct_desc; /* from SAM */ + static char empty[1]; /* just an empty string */ + + slprintf (uid, sizeof (uid) - 1, "%u", pdb_get_uid (sampass)); + slprintf (user_rid, sizeof (user_rid) - 1, "%u", + pdb_get_user_rid (sampass) ? pdb_get_user_rid (sampass) : + fallback_pdb_uid_to_user_rid (pdb_get_uid (sampass))); + slprintf (gid, sizeof (gid) - 1, "%u", pdb_get_gid (sampass)); { uint32 rid; GROUP_MAP map; - - rid=pdb_get_group_rid(sampass); - if (rid==0) { - if (get_group_map_from_gid(pdb_get_gid(sampass), &map, MAPPING_WITHOUT_PRIV)) { - if (!sid_peek_check_rid(get_global_sam_sid(), &map.sid, &rid)) + rid = pdb_get_group_rid (sampass); + + if (rid == 0) { + if (get_group_map_from_gid + (pdb_get_gid (sampass), &map, + MAPPING_WITHOUT_PRIV)) { + if (!sid_peek_check_rid + (get_global_sam_sid (), &map.sid, &rid)) return False; - } else - rid=pdb_gid_to_group_rid(pdb_get_gid(sampass)); + } else + rid = pdb_gid_to_group_rid (pdb_get_gid + (sampass)); } - slprintf(group_rid, sizeof(group_rid)-1, "%u", rid); + slprintf (group_rid, sizeof (group_rid) - 1, "%u", rid); } - - acb = pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sampass), - NEW_PW_FORMAT_SPACE_PADDED_LEN); - pdb_sethexpwd (smb_passwd, pdb_get_lanman_passwd(sampass), - pdb_get_acct_ctrl(sampass)); - pdb_sethexpwd (smb_nt_passwd, pdb_get_nt_passwd(sampass), - pdb_get_acct_ctrl(sampass)); - slprintf(logon_t, 13, "LNT-%08X", - (uint32)pdb_get_logon_time(sampass)); - slprintf(logoff_t, 13, "LOT-%08X", - (uint32)pdb_get_logoff_time(sampass)); - slprintf(kickoff_t, 13, "KOT-%08X", - (uint32)pdb_get_kickoff_time(sampass)); - slprintf(pwdlset_t, 13, "LCT-%08X", - (uint32)pdb_get_pass_last_set_time(sampass)); - slprintf(pwdlchg_t, 13, "CCT-%08X", - (uint32)pdb_get_pass_can_change_time(sampass)); - slprintf(pwdmchg_t, 13, "MCT-%08X", - (uint32)pdb_get_pass_must_change_time(sampass)); - safe_strcpy(full_name, pdb_get_fullname(sampass), sizeof(full_name)-1); - safe_strcpy(acct_desc, pdb_get_acct_desc(sampass), sizeof(acct_desc)-1); + + acb = pdb_encode_acct_ctrl (pdb_get_acct_ctrl (sampass), + NEW_PW_FORMAT_SPACE_PADDED_LEN); + pdb_sethexpwd (smb_passwd, pdb_get_lanman_passwd (sampass), + pdb_get_acct_ctrl (sampass)); + pdb_sethexpwd (smb_nt_passwd, pdb_get_nt_passwd (sampass), + pdb_get_acct_ctrl (sampass)); + slprintf (logon_t, 13, "LNT-%08X", + (uint32) pdb_get_logon_time (sampass)); + slprintf (logoff_t, 13, "LOT-%08X", + (uint32) pdb_get_logoff_time (sampass)); + slprintf (kickoff_t, 13, "KOT-%08X", + (uint32) pdb_get_kickoff_time (sampass)); + slprintf (pwdlset_t, 13, "LCT-%08X", + (uint32) pdb_get_pass_last_set_time (sampass)); + slprintf (pwdlchg_t, 13, "CCT-%08X", + (uint32) pdb_get_pass_can_change_time (sampass)); + slprintf (pwdmchg_t, 13, "MCT-%08X", + (uint32) pdb_get_pass_must_change_time (sampass)); + safe_strcpy (full_name, pdb_get_fullname (sampass), + sizeof (full_name) - 1); + safe_strcpy (acct_desc, pdb_get_acct_desc (sampass), + sizeof (acct_desc) - 1); #if 0 - /* Not sure what to do with these guys. -tpot */ + /* Not sure what to do with these guys. -tpot */ - dos_to_unix(full_name, True); - dos_to_unix(acct_desc, True); + dos_to_unix (full_name, True); + dos_to_unix (acct_desc, True); #endif - if( old ) { - /* name */ - if(strcmp(ENTRY_VAL(old, NPF_NAME), name)) - { - need_to_modify = True; - set_single_attribute(obj, NPF_NAME, name, strlen(name), - EN_MODIFIED); - } + if (old) { + /* name */ + if (strcmp (ENTRY_VAL (old, NPF_NAME), name)) { + need_to_modify = True; + set_single_attribute (obj, NPF_NAME, name, + strlen (name), EN_MODIFIED); + } - /* uid */ - if(pdb_get_uid(sampass) != -1) { - if(!ENTRY_VAL(old, NPF_UID) || strcmp(ENTRY_VAL(old, NPF_UID), uid)) - { - need_to_modify = True; - set_single_attribute(obj, NPF_UID, uid, - strlen(uid), EN_MODIFIED); - } - } - - /* user_rid */ - if (pdb_get_user_rid(sampass)) { - if(!ENTRY_VAL(old, NPF_USER_RID) || - strcmp(ENTRY_VAL(old, NPF_USER_RID), user_rid) ) { - need_to_modify = True; - set_single_attribute(obj, NPF_USER_RID, user_rid, - strlen(user_rid), EN_MODIFIED); - } - } - - /* smb_grpid */ - if (pdb_get_gid(sampass) != -1) { - if(!ENTRY_VAL(old, NPF_SMB_GRPID) || - strcmp(ENTRY_VAL(old, NPF_SMB_GRPID), gid) ) { - need_to_modify = True; - set_single_attribute(obj, NPF_SMB_GRPID, gid, - strlen(gid), EN_MODIFIED); - } - } - - /* group_rid */ - if (pdb_get_group_rid(sampass)) { - if(!ENTRY_VAL(old, NPF_GROUP_RID) || - strcmp(ENTRY_VAL(old, NPF_GROUP_RID), group_rid) ) { - need_to_modify = True; - set_single_attribute(obj, NPF_GROUP_RID, group_rid, - strlen(group_rid), EN_MODIFIED); - } - } - - /* acb */ - if (!ENTRY_VAL(old, NPF_ACB) || - strcmp(ENTRY_VAL(old, NPF_ACB), acb)) { - need_to_modify = True; - set_single_attribute(obj, NPF_ACB, acb, strlen(acb), EN_MODIFIED); - } - - /* lmpwd */ - if(!ENTRY_VAL(old, NPF_LMPWD) || - strcmp(ENTRY_VAL(old, NPF_LMPWD), smb_passwd) ) { - need_to_modify = True; - set_single_attribute(obj, NPF_LMPWD, smb_passwd, - strlen(smb_passwd), EN_CRYPT|EN_MODIFIED); - } - - /* ntpwd */ - if(!ENTRY_VAL(old, NPF_NTPWD) || - strcmp(ENTRY_VAL(old, NPF_NTPWD), smb_nt_passwd) ) { - need_to_modify = True; - set_single_attribute(obj, NPF_NTPWD, smb_nt_passwd, - strlen(smb_nt_passwd), EN_CRYPT|EN_MODIFIED); - } - - /* logon_t */ - if( pdb_get_logon_time(sampass) && - (!ENTRY_VAL(old, NPF_LOGON_T) || - strcmp(ENTRY_VAL(old, NPF_LOGON_T), logon_t ))) { - need_to_modify = True; - set_single_attribute(obj, NPF_LOGON_T, logon_t, - strlen(logon_t), EN_MODIFIED); - } - - /* logoff_t */ - if( pdb_get_logoff_time(sampass) && - (!ENTRY_VAL(old, NPF_LOGOFF_T) || - strcmp(ENTRY_VAL(old, NPF_LOGOFF_T), logoff_t))) { - need_to_modify = True; - set_single_attribute(obj, NPF_LOGOFF_T, logoff_t, - strlen(logoff_t), EN_MODIFIED); - } - - /* kick_t */ - if( pdb_get_kickoff_time(sampass) && - (!ENTRY_VAL(old, NPF_KICK_T) || - strcmp(ENTRY_VAL(old, NPF_KICK_T), kickoff_t))) { - need_to_modify = True; - set_single_attribute(obj, NPF_KICK_T, kickoff_t, - strlen(kickoff_t), EN_MODIFIED); - } - - /* pwdlset_t */ - if( pdb_get_pass_last_set_time(sampass) && - (!ENTRY_VAL(old, NPF_PWDLSET_T) || - strcmp(ENTRY_VAL(old, NPF_PWDLSET_T), pwdlset_t))) { - need_to_modify = True; - set_single_attribute(obj, NPF_PWDLSET_T, pwdlset_t, - strlen(pwdlset_t), EN_MODIFIED); - } - - /* pwdlchg_t */ - if( pdb_get_pass_can_change_time(sampass) && - (!ENTRY_VAL(old, NPF_PWDCCHG_T) || - strcmp(ENTRY_VAL(old, NPF_PWDCCHG_T), pwdlchg_t))) { - need_to_modify = True; - set_single_attribute(obj, NPF_PWDCCHG_T, pwdlchg_t, - strlen(pwdlchg_t), EN_MODIFIED); - } - - /* pwdmchg_t */ - if( pdb_get_pass_must_change_time(sampass) && - (!ENTRY_VAL(old, NPF_PWDMCHG_T) || - strcmp(ENTRY_VAL(old, NPF_PWDMCHG_T), pwdmchg_t))) { - need_to_modify = True; - set_single_attribute(obj, NPF_PWDMCHG_T, pwdmchg_t, - strlen(pwdmchg_t), EN_MODIFIED); - } - - /* full_name */ - /* must support set, unset and change */ - if ( (pdb_get_fullname(sampass) && - !ENTRY_VAL(old, NPF_FULL_NAME)) || - (ENTRY_VAL(old, NPF_FULL_NAME) && - !pdb_get_fullname(sampass)) || - (ENTRY_VAL(old, NPF_FULL_NAME) && - pdb_get_fullname(sampass) && - strcmp( ENTRY_VAL(old, NPF_FULL_NAME), full_name ))) { - need_to_modify = True; - set_single_attribute(obj, NPF_FULL_NAME, full_name, - strlen(full_name), EN_MODIFIED); - } - - /* home_dir */ - /* must support set, unset and change */ - if( (pdb_get_homedir(sampass) && - !ENTRY_VAL(old, NPF_HOME_DIR)) || - (ENTRY_VAL(old, NPF_HOME_DIR) && - !pdb_get_homedir(sampass)) || - (ENTRY_VAL(old, NPF_HOME_DIR) && - pdb_get_homedir(sampass) && - strcmp( ENTRY_VAL(old, NPF_HOME_DIR), - pdb_get_homedir(sampass)))) { - need_to_modify = True; - set_single_attribute(obj, NPF_HOME_DIR, pdb_get_homedir(sampass), - strlen(pdb_get_homedir(sampass)), EN_MODIFIED); - } - - /* dir_drive */ - /* must support set, unset and change */ - if( (pdb_get_dir_drive(sampass) && - !ENTRY_VAL(old, NPF_DIR_DRIVE)) || - (ENTRY_VAL(old, NPF_DIR_DRIVE) && - !pdb_get_dir_drive(sampass)) || - (ENTRY_VAL(old, NPF_DIR_DRIVE) && - pdb_get_dir_drive(sampass) && - strcmp( ENTRY_VAL(old, NPF_DIR_DRIVE), - pdb_get_dir_drive(sampass)))) { - need_to_modify = True; - set_single_attribute(obj, NPF_DIR_DRIVE, pdb_get_dir_drive(sampass), - strlen(pdb_get_dir_drive(sampass)), EN_MODIFIED); - } - - /* logon_script */ - /* must support set, unset and change */ - if( (pdb_get_logon_script(sampass) && - !ENTRY_VAL(old, NPF_LOGON_SCRIPT) || - (ENTRY_VAL(old, NPF_LOGON_SCRIPT) && - !pdb_get_logon_script(sampass)) || - ( ENTRY_VAL(old, NPF_LOGON_SCRIPT) && - pdb_get_logon_script(sampass) && - strcmp( ENTRY_VAL(old, NPF_LOGON_SCRIPT), - pdb_get_logon_script(sampass))))) { - need_to_modify = True; - set_single_attribute(obj, NPF_LOGON_SCRIPT, - pdb_get_logon_script(sampass), - strlen(pdb_get_logon_script(sampass)), - EN_MODIFIED); - } - - /* profile_path */ - /* must support set, unset and change */ - if( (pdb_get_profile_path(sampass) && - !ENTRY_VAL(old, NPF_PROFILE_PATH)) || - (ENTRY_VAL(old, NPF_PROFILE_PATH) && - !pdb_get_profile_path(sampass)) || - (ENTRY_VAL(old, NPF_PROFILE_PATH) && - pdb_get_profile_path(sampass) && - strcmp( ENTRY_VAL(old, NPF_PROFILE_PATH), - pdb_get_profile_path(sampass) ) )) { - need_to_modify = True; - set_single_attribute(obj, NPF_PROFILE_PATH, - pdb_get_profile_path(sampass), - strlen(pdb_get_profile_path(sampass)), - EN_MODIFIED); - } - - /* acct_desc */ - /* must support set, unset and change */ - if( (pdb_get_acct_desc(sampass) && - !ENTRY_VAL(old, NPF_ACCT_DESC)) || - (ENTRY_VAL(old, NPF_ACCT_DESC) && - !pdb_get_acct_desc(sampass)) || - (ENTRY_VAL(old, NPF_ACCT_DESC) && - pdb_get_acct_desc(sampass) && - strcmp( ENTRY_VAL(old, NPF_ACCT_DESC), acct_desc ) )) { - need_to_modify = True; - set_single_attribute(obj, NPF_ACCT_DESC, acct_desc, - strlen(acct_desc), EN_MODIFIED); - } - - /* workstations */ - /* must support set, unset and change */ - if ( (pdb_get_workstations(sampass) && - !ENTRY_VAL(old, NPF_WORKSTATIONS) ) || - (ENTRY_VAL(old, NPF_WORKSTATIONS) && - !pdb_get_workstations(sampass)) || - (ENTRY_VAL(old, NPF_WORKSTATIONS) && - pdb_get_workstations(sampass)) && - strcmp( ENTRY_VAL(old, NPF_WORKSTATIONS), - pdb_get_workstations(sampass))) { - need_to_modify = True; - set_single_attribute(obj, NPF_WORKSTATIONS, - pdb_get_workstations(sampass), - strlen(pdb_get_workstations(sampass)), - EN_MODIFIED); - } - - /* hours */ - if ((pdb_get_hours_len(sampass) != ENTRY_LEN(old, NPF_HOURS)) || - memcmp(pdb_get_hours(sampass), ENTRY_VAL(old, NPF_HOURS), - ENTRY_LEN(old, NPF_HOURS))) { - need_to_modify = True; - /* set_single_attribute will add 1 for len ... */ - set_single_attribute(obj, NPF_HOURS, pdb_get_hours(sampass), - pdb_get_hours_len(sampass)-1, EN_MODIFIED); - } - } else { - const char *homedir, *dirdrive, *logon_script, *profile_path, *workstations; - - *empty = '\0'; /* empty string */ - - set_single_attribute(obj, NPF_NAME, name, strlen(name), 0); - set_single_attribute(obj, NPF_UID, uid, strlen(uid), 0); - set_single_attribute(obj, NPF_USER_RID, user_rid, - strlen(user_rid), 0); - set_single_attribute(obj, NPF_SMB_GRPID, gid, strlen(gid), 0); - set_single_attribute(obj, NPF_GROUP_RID, group_rid, - strlen(group_rid), 0); - set_single_attribute(obj, NPF_ACB, acb, strlen(acb), 0); - set_single_attribute(obj, NPF_LMPWD, smb_passwd, - strlen(smb_passwd), EN_CRYPT); - set_single_attribute(obj, NPF_NTPWD, smb_nt_passwd, - strlen(smb_nt_passwd), EN_CRYPT); - set_single_attribute(obj, NPF_LOGON_T, logon_t, - strlen(logon_t), 0); - set_single_attribute(obj, NPF_LOGOFF_T, logoff_t, - strlen(logoff_t), 0); - set_single_attribute(obj, NPF_KICK_T, kickoff_t, - strlen(kickoff_t),0); - set_single_attribute(obj, NPF_PWDLSET_T, pwdlset_t, - strlen(pwdlset_t), 0); - set_single_attribute(obj, NPF_PWDCCHG_T, pwdlchg_t, - strlen(pwdlchg_t), 0); - set_single_attribute(obj, NPF_PWDMCHG_T, pwdmchg_t, - strlen(pwdmchg_t), 0); - set_single_attribute(obj, NPF_FULL_NAME , - full_name, strlen(full_name), 0); - - if(!(homedir = pdb_get_homedir(sampass))) - homedir = empty; - - set_single_attribute(obj, NPF_HOME_DIR, - homedir, strlen(homedir), 0); - - if(!(dirdrive = pdb_get_dir_drive(sampass))) - dirdrive = empty; - - set_single_attribute(obj, NPF_DIR_DRIVE, - dirdrive, strlen(dirdrive), 0); - - if(!(logon_script = pdb_get_logon_script(sampass))) - logon_script = empty; - - set_single_attribute(obj, NPF_LOGON_SCRIPT, - logon_script, strlen(logon_script), 0); - - if(!(profile_path = pdb_get_profile_path(sampass))) - profile_path = empty; - - set_single_attribute(obj, NPF_PROFILE_PATH, - profile_path, strlen(profile_path), 0); - - set_single_attribute(obj, NPF_ACCT_DESC, - acct_desc, strlen(acct_desc), 0); - - if(!(workstations = pdb_get_workstations(sampass))) - workstations = empty; - - set_single_attribute(obj, NPF_WORKSTATIONS, - workstations, strlen(workstations), 0); - - /* set_single_attribute will add 1 for len ... */ - set_single_attribute(obj, NPF_HOURS, - pdb_get_hours(sampass), - pdb_get_hours_len(sampass)-1, 0); - } - - return need_to_modify; -} + /* uid */ + if (pdb_get_uid (sampass) != -1) { + if (!ENTRY_VAL (old, NPF_UID) + || strcmp (ENTRY_VAL (old, NPF_UID), uid)) { + need_to_modify = True; + set_single_attribute (obj, NPF_UID, uid, + strlen (uid), + EN_MODIFIED); + } + } -/*************************************************************** - calls nis_list, returns results. - ****************************************************************/ -static nis_result *nisp_get_nis_list(const char *nis_name, unsigned int flags) -{ - nis_result *result; - int i; + /* user_rid */ + if (pdb_get_user_rid (sampass)) { + if (!ENTRY_VAL (old, NPF_USER_RID) || + strcmp (ENTRY_VAL (old, NPF_USER_RID), + user_rid)) { + need_to_modify = True; + set_single_attribute (obj, NPF_USER_RID, + user_rid, + strlen (user_rid), + EN_MODIFIED); + } + } - if( ! flags) - flags = FOLLOW_LINKS|FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP; - - for(i = 0; i<2;i++ ) { - alarm(60); /* hopefully ok for long searches */ - result = nis_list(nis_name, flags,NULL,NULL); - - alarm(0); - CatchSignal(SIGALRM, SIGNAL_CAST SIG_DFL); - - if (gotalarm) - { - DEBUG(0,("NIS+ lookup time out\n")); - nis_freeresult(result); - return NULL; - } - if( !(flags & MASTER_ONLY) && NIS_RES_NUMOBJ(result) <= 0 ) { - /* nis replicas are not in sync perhaps? - * this can happen, if account was just added. - */ - DEBUG(10,("will try master only\n")); - nis_freeresult(result); - flags |= MASTER_ONLY; - } else - break; - } - return result; -} + /* smb_grpid */ + if (pdb_get_gid (sampass) != -1) { + if (!ENTRY_VAL (old, NPF_SMB_GRPID) || + strcmp (ENTRY_VAL (old, NPF_SMB_GRPID), gid)) { + need_to_modify = True; + set_single_attribute (obj, NPF_SMB_GRPID, gid, + strlen (gid), + EN_MODIFIED); + } + } -/*************************************************************** - Start to enumerate the nisplus passwd list. - ****************************************************************/ -BOOL pdb_setsampwent(BOOL update) -{ - char *sp, * p = lp_smb_passwd_file(); - pstring pfiletmp; + /* group_rid */ + if (pdb_get_group_rid (sampass)) { + if (!ENTRY_VAL (old, NPF_GROUP_RID) || + strcmp (ENTRY_VAL (old, NPF_GROUP_RID), + group_rid)) { + need_to_modify = True; + set_single_attribute (obj, NPF_GROUP_RID, + group_rid, + strlen (group_rid), + EN_MODIFIED); + } + } - if( (sp = strrchr( p, '/' )) ) - safe_strcpy(pfiletmp, sp+1, sizeof(pfiletmp)-1); - else - safe_strcpy(pfiletmp, p, sizeof(pfiletmp)-1); - safe_strcat(pfiletmp, ".org_dir", sizeof(pfiletmp)-strlen(pfiletmp)-1); + /* acb */ + if (!ENTRY_VAL (old, NPF_ACB) || + strcmp (ENTRY_VAL (old, NPF_ACB), acb)) { + need_to_modify = True; + set_single_attribute (obj, NPF_ACB, acb, strlen (acb), + EN_MODIFIED); + } - pdb_endsampwent(); /* just in case */ - global_nisp_ent.result = nisp_get_nis_list( pfiletmp, 0 ); - global_nisp_ent.enum_entry = 0; - return global_nisp_ent.result != NULL ? True : False; -} + /* lmpwd */ + if (!ENTRY_VAL (old, NPF_LMPWD) || + strcmp (ENTRY_VAL (old, NPF_LMPWD), smb_passwd)) { + need_to_modify = True; + set_single_attribute (obj, NPF_LMPWD, smb_passwd, + strlen (smb_passwd), + EN_CRYPT | EN_MODIFIED); + } -/*************************************************************** - End enumeration of the nisplus passwd list. -****************************************************************/ -void pdb_endsampwent(void) -{ - if( global_nisp_ent.result ) - nis_freeresult(global_nisp_ent.result); - global_nisp_ent.result = NULL; - global_nisp_ent.enum_entry = 0; -} + /* ntpwd */ + if (!ENTRY_VAL (old, NPF_NTPWD) || + strcmp (ENTRY_VAL (old, NPF_NTPWD), smb_nt_passwd)) { + need_to_modify = True; + set_single_attribute (obj, NPF_NTPWD, smb_nt_passwd, + strlen (smb_nt_passwd), + EN_CRYPT | EN_MODIFIED); + } -/************************************************************************* - Routine to return the next entry in the nisplus passwd list. - *************************************************************************/ -BOOL pdb_getsampwent(SAM_ACCOUNT *user) -{ - int enum_entry = (int)(global_nisp_ent.enum_entry); - nis_result *result = global_nisp_ent.result; - - if (user==NULL) { - DEBUG(0,("SAM_ACCOUNT is NULL.\n")); - return False; - } + /* logon_t */ + if (pdb_get_logon_time (sampass) && + (!ENTRY_VAL (old, NPF_LOGON_T) || + strcmp (ENTRY_VAL (old, NPF_LOGON_T), logon_t))) { + need_to_modify = True; + set_single_attribute (obj, NPF_LOGON_T, logon_t, + strlen (logon_t), EN_MODIFIED); + } - if (result == NULL || - enum_entry < 0 || enum_entry >= (NIS_RES_NUMOBJ(result) - 1)) - { - return False; - } + /* logoff_t */ + if (pdb_get_logoff_time (sampass) && + (!ENTRY_VAL (old, NPF_LOGOFF_T) || + strcmp (ENTRY_VAL (old, NPF_LOGOFF_T), logoff_t))) { + need_to_modify = True; + set_single_attribute (obj, NPF_LOGOFF_T, logoff_t, + strlen (logoff_t), EN_MODIFIED); + } - if(!make_sam_from_nisp_object(user, &NIS_RES_OBJECT(result)[enum_entry]) ) - { - DEBUG(0,("Bad SAM_ACCOUNT entry returned from NIS+!\n")); - return False; - } - (int)(global_nisp_ent.enum_entry)++; - return True; -} + /* kick_t */ + if (pdb_get_kickoff_time (sampass) && + (!ENTRY_VAL (old, NPF_KICK_T) || + strcmp (ENTRY_VAL (old, NPF_KICK_T), kickoff_t))) { + need_to_modify = True; + set_single_attribute (obj, NPF_KICK_T, kickoff_t, + strlen (kickoff_t), + EN_MODIFIED); + } -/************************************************************************* - Routine to search the nisplus passwd file for an entry matching the username - *************************************************************************/ -BOOL pdb_getsampwnam(SAM_ACCOUNT * user, const char *sname) -{ - /* Static buffers we will return. */ - nis_result *result = NULL; - pstring nisname; - BOOL ret; - char *pfile = lp_smb_passwd_file(); - int i; + /* pwdlset_t */ + if (pdb_get_pass_last_set_time (sampass) && + (!ENTRY_VAL (old, NPF_PWDLSET_T) || + strcmp (ENTRY_VAL (old, NPF_PWDLSET_T), pwdlset_t))) { + need_to_modify = True; + set_single_attribute (obj, NPF_PWDLSET_T, pwdlset_t, + strlen (pwdlset_t), + EN_MODIFIED); + } - if (!*pfile) - { - DEBUG(0, ("No SMB password file set\n")); - return False; - } - if( strrchr( pfile, '/') ) - pfile = strrchr( pfile, '/') + 1; + /* pwdlchg_t */ + if (pdb_get_pass_can_change_time (sampass) && + (!ENTRY_VAL (old, NPF_PWDCCHG_T) || + strcmp (ENTRY_VAL (old, NPF_PWDCCHG_T), pwdlchg_t))) { + need_to_modify = True; + set_single_attribute (obj, NPF_PWDCCHG_T, pwdlchg_t, + strlen (pwdlchg_t), + EN_MODIFIED); + } - slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.org_dir", sname, pfile); - DEBUG(10, ("search by nisname: %s\n", nisname)); + /* pwdmchg_t */ + if (pdb_get_pass_must_change_time (sampass) && + (!ENTRY_VAL (old, NPF_PWDMCHG_T) || + strcmp (ENTRY_VAL (old, NPF_PWDMCHG_T), pwdmchg_t))) { + need_to_modify = True; + set_single_attribute (obj, NPF_PWDMCHG_T, pwdmchg_t, + strlen (pwdmchg_t), + EN_MODIFIED); + } - /* Search the table. */ + /* full_name */ + /* must support set, unset and change */ + if ((pdb_get_fullname (sampass) && + !ENTRY_VAL (old, NPF_FULL_NAME)) || + (ENTRY_VAL (old, NPF_FULL_NAME) && + !pdb_get_fullname (sampass)) || + (ENTRY_VAL (old, NPF_FULL_NAME) && + pdb_get_fullname (sampass) && + strcmp (ENTRY_VAL (old, NPF_FULL_NAME), full_name))) { + need_to_modify = True; + set_single_attribute (obj, NPF_FULL_NAME, full_name, + strlen (full_name), + EN_MODIFIED); + } - if(!(result = nisp_get_nis_list(nisname, 0))) - { - return False; - } + /* home_dir */ + /* must support set, unset and change */ + if ((pdb_get_homedir (sampass) && + !ENTRY_VAL (old, NPF_HOME_DIR)) || + (ENTRY_VAL (old, NPF_HOME_DIR) && + !pdb_get_homedir (sampass)) || + (ENTRY_VAL (old, NPF_HOME_DIR) && + pdb_get_homedir (sampass) && + strcmp (ENTRY_VAL (old, NPF_HOME_DIR), + pdb_get_homedir (sampass)))) { + need_to_modify = True; + set_single_attribute (obj, NPF_HOME_DIR, + pdb_get_homedir (sampass), + strlen (pdb_get_homedir + (sampass)), + EN_MODIFIED); + } - ret = make_sam_from_nisresult(user, result); - nis_freeresult(result); + /* dir_drive */ + /* must support set, unset and change */ + if ((pdb_get_dir_drive (sampass) && + !ENTRY_VAL (old, NPF_DIR_DRIVE)) || + (ENTRY_VAL (old, NPF_DIR_DRIVE) && + !pdb_get_dir_drive (sampass)) || + (ENTRY_VAL (old, NPF_DIR_DRIVE) && + pdb_get_dir_drive (sampass) && + strcmp (ENTRY_VAL (old, NPF_DIR_DRIVE), + pdb_get_dir_drive (sampass)))) { + need_to_modify = True; + set_single_attribute (obj, NPF_DIR_DRIVE, + pdb_get_dir_drive (sampass), + strlen (pdb_get_dir_drive + (sampass)), + EN_MODIFIED); + } - return ret; -} + /* logon_script */ + /* must support set, unset and change */ + if (((pdb_get_logon_script (sampass) && + !ENTRY_VAL (old, NPF_LOGON_SCRIPT)) || + ((ENTRY_VAL (old, NPF_LOGON_SCRIPT) && + (!pdb_get_logon_script (sampass)))) || + ((ENTRY_VAL (old, NPF_LOGON_SCRIPT) && + pdb_get_logon_script (sampass) && + strcmp (ENTRY_VAL (old, NPF_LOGON_SCRIPT), + pdb_get_logon_script (sampass)))))) { + need_to_modify = True; + set_single_attribute (obj, NPF_LOGON_SCRIPT, + pdb_get_logon_script (sampass), + strlen (pdb_get_logon_script + (sampass)), + EN_MODIFIED); + } -/************************************************************************* - Routine to search the nisplus passwd file for an entry matching the username - *************************************************************************/ + /* profile_path */ + /* must support set, unset and change */ + if ((pdb_get_profile_path (sampass) && + !ENTRY_VAL (old, NPF_PROFILE_PATH)) || + (ENTRY_VAL (old, NPF_PROFILE_PATH) && + !pdb_get_profile_path (sampass)) || + (ENTRY_VAL (old, NPF_PROFILE_PATH) && + pdb_get_profile_path (sampass) && + strcmp (ENTRY_VAL (old, NPF_PROFILE_PATH), + pdb_get_profile_path (sampass)))) { + need_to_modify = True; + set_single_attribute (obj, NPF_PROFILE_PATH, + pdb_get_profile_path (sampass), + strlen (pdb_get_profile_path + (sampass)), + EN_MODIFIED); + } -BOOL pdb_getsampwsid(SAM_ACCOUNT * user, const DOM_SID *sid) -{ - uint32 rid; - if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) - return False; - return pdb_getsampwrid(user, rid); + /* acct_desc */ + /* must support set, unset and change */ + if ((pdb_get_acct_desc (sampass) && + !ENTRY_VAL (old, NPF_ACCT_DESC)) || + (ENTRY_VAL (old, NPF_ACCT_DESC) && + !pdb_get_acct_desc (sampass)) || + (ENTRY_VAL (old, NPF_ACCT_DESC) && + pdb_get_acct_desc (sampass) && + strcmp (ENTRY_VAL (old, NPF_ACCT_DESC), acct_desc))) { + need_to_modify = True; + set_single_attribute (obj, NPF_ACCT_DESC, acct_desc, + strlen (acct_desc), + EN_MODIFIED); + } + + /* workstations */ + /* must support set, unset and change */ + if ((pdb_get_workstations (sampass) && + !ENTRY_VAL (old, NPF_WORKSTATIONS)) || + (ENTRY_VAL (old, NPF_WORKSTATIONS) && + !pdb_get_workstations (sampass)) || + (ENTRY_VAL (old, NPF_WORKSTATIONS) && + (pdb_get_workstations (sampass)) && + strcmp (ENTRY_VAL (old, NPF_WORKSTATIONS), + pdb_get_workstations (sampass)))) { + need_to_modify = True; + set_single_attribute (obj, NPF_WORKSTATIONS, + pdb_get_workstations (sampass), + strlen (pdb_get_workstations + (sampass)), + EN_MODIFIED); + } + + /* hours */ + if ((pdb_get_hours_len (sampass) != + ENTRY_LEN (old, NPF_HOURS)) + || memcmp (pdb_get_hours (sampass), + ENTRY_VAL (old, NPF_HOURS), ENTRY_LEN (old, + NPF_HOURS))) + { + need_to_modify = True; + /* set_single_attribute will add 1 for len ... */ + set_single_attribute (obj, NPF_HOURS, + pdb_get_hours (sampass), + pdb_get_hours_len (sampass) - 1, + EN_MODIFIED); + } + } else { + const char *homedir, *dirdrive, *logon_script, *profile_path, + *workstations; + + *empty = '\0'; /* empty string */ + + set_single_attribute (obj, NPF_NAME, name, strlen (name), 0); + set_single_attribute (obj, NPF_UID, uid, strlen (uid), 0); + set_single_attribute (obj, NPF_USER_RID, user_rid, + strlen (user_rid), 0); + set_single_attribute (obj, NPF_SMB_GRPID, gid, strlen (gid), + 0); + set_single_attribute (obj, NPF_GROUP_RID, group_rid, + strlen (group_rid), 0); + set_single_attribute (obj, NPF_ACB, acb, strlen (acb), 0); + set_single_attribute (obj, NPF_LMPWD, smb_passwd, + strlen (smb_passwd), EN_CRYPT); + set_single_attribute (obj, NPF_NTPWD, smb_nt_passwd, + strlen (smb_nt_passwd), EN_CRYPT); + set_single_attribute (obj, NPF_LOGON_T, logon_t, + strlen (logon_t), 0); + set_single_attribute (obj, NPF_LOGOFF_T, logoff_t, + strlen (logoff_t), 0); + set_single_attribute (obj, NPF_KICK_T, kickoff_t, + strlen (kickoff_t), 0); + set_single_attribute (obj, NPF_PWDLSET_T, pwdlset_t, + strlen (pwdlset_t), 0); + set_single_attribute (obj, NPF_PWDCCHG_T, pwdlchg_t, + strlen (pwdlchg_t), 0); + set_single_attribute (obj, NPF_PWDMCHG_T, pwdmchg_t, + strlen (pwdmchg_t), 0); + set_single_attribute (obj, NPF_FULL_NAME, + full_name, strlen (full_name), 0); + + if (!(homedir = pdb_get_homedir (sampass))) + homedir = empty; + + set_single_attribute (obj, NPF_HOME_DIR, + homedir, strlen (homedir), 0); + + if (!(dirdrive = pdb_get_dir_drive (sampass))) + dirdrive = empty; + + set_single_attribute (obj, NPF_DIR_DRIVE, + dirdrive, strlen (dirdrive), 0); + + if (!(logon_script = pdb_get_logon_script (sampass))) + logon_script = empty; + + set_single_attribute (obj, NPF_LOGON_SCRIPT, + logon_script, strlen (logon_script), 0); + + if (!(profile_path = pdb_get_profile_path (sampass))) + profile_path = empty; + + set_single_attribute (obj, NPF_PROFILE_PATH, + profile_path, strlen (profile_path), 0); + + set_single_attribute (obj, NPF_ACCT_DESC, + acct_desc, strlen (acct_desc), 0); + + if (!(workstations = pdb_get_workstations (sampass))) + workstations = empty; + + set_single_attribute (obj, NPF_WORKSTATIONS, + workstations, strlen (workstations), 0); + + /* set_single_attribute will add 1 for len ... */ + set_single_attribute (obj, NPF_HOURS, + pdb_get_hours (sampass), + pdb_get_hours_len (sampass) - 1, 0); + } + + return need_to_modify; } -static BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid) +/*************************************************************** + calls nis_list, returns results. + ****************************************************************/ +static nis_result *nisp_get_nis_list (const char *nisname, unsigned int flags) { nis_result *result; - char *nisname; - BOOL ret; - char *sp, *p = lp_smb_passwd_file(); - pstring pfiletmp; + int i; - if (!*p) - { - DEBUG(0, ("no SMB password file set\n")); - return False; + if (!flags) + flags = FOLLOW_LINKS | FOLLOW_PATH | EXPAND_NAME | + HARD_LOOKUP; + + for (i = 0; i < 2; i++) { + alarm (60); /* hopefully ok for long searches */ + result = nis_list (nisname, flags, NULL, NULL); + + alarm (0); + CatchSignal (SIGALRM, SIGNAL_CAST SIG_DFL); + + if (!(flags & MASTER_ONLY) && NIS_RES_NUMOBJ (result) <= 0) { + /* nis replicas are not in sync perhaps? + * this can happen, if account was just added. + */ + DEBUG (10, ("will try master only\n")); + nis_freeresult (result); + flags |= MASTER_ONLY; + } else + break; } + return result; +} - if( (sp = strrchr( p, '/' )) ) - safe_strcpy(pfiletmp, sp+1, sizeof(pfiletmp)-1); - else - safe_strcpy(pfiletmp, p, sizeof(pfiletmp)-1); - safe_strcat(pfiletmp, ".org_dir", sizeof(pfiletmp)-strlen(pfiletmp)-1); - - nisname = make_nisname_from_user_rid(rid, pfiletmp); - - DEBUG(10, ("search by rid: %s\n", nisname)); +NTSTATUS pdb_init_nisplussam (PDB_CONTEXT * pdb_context, + PDB_METHODS ** pdb_method, const char *location) +{ + NTSTATUS nt_status; + struct nisplus_private_info *private = malloc (sizeof (struct nisplus_private_info)); - /* Search the table. */ + ZERO_STRUCT(private); + p->location = talloc_strdup(pdb_context->mem_ctx, location); - if(!(result = nisp_get_nis_list(nisname, 0))) - { - return False; + if (!NT_STATUS_IS_OK + (nt_status = + make_pdb_methods (pdb_context->mem_ctx, pdb_method))) { + return nt_status; } - ret = make_sam_from_nisresult(user, result); - nis_freeresult(result); + (*pdb_method)->name = "nisplussam"; - return ret; -} - -/************************************************************************* - Routine to remove entry from the nisplus smbpasswd table - *************************************************************************/ -BOOL pdb_delete_sam_account(SAM_ACCOUNT * user) -{ - const char *sname; - char *pfile = lp_smb_passwd_file(); - pstring nisname; - nis_result *result, *delresult; - nis_object *obj; - int i; - - if (!user) { - DEBUG(0, ("no SAM_ACCOUNT specified!\n")); - return False; - } - - sname = pdb_get_username(user); - - if (!*pfile) - { - DEBUG(0, ("no SMB password file set\n")); - return False; - } - if( strrchr( pfile, '/') ) - pfile = strrchr( pfile, '/') + 1; - - slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.org_dir", sname, pfile); - - /* Search the table. */ - - if( !(result = nisp_get_nis_list(nisname, - MASTER_ONLY|FOLLOW_LINKS|FOLLOW_PATH|\ - EXPAND_NAME|HARD_LOOKUP))) { - return False; - } - - if(result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0) { - /* User not found. */ - DEBUG(0,("user not found in NIS+\n")); - nis_freeresult(result); - return False; - } - - obj = NIS_RES_OBJECT(result); - slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.%s", sname, obj->zo_name, - obj->zo_domain); - - DEBUG(10, ("removing name: %s\n", nisname)); - delresult = nis_remove_entry(nisname, obj, - MASTER_ONLY|REM_MULTIPLE|ALL_RESULTS|FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP); - - nis_freeresult(result); - - if(delresult->status != NIS_SUCCESS) { - DEBUG(0, ("NIS+ table update failed: %s %s\n", - nisname, nis_sperrno(delresult->status))); - nis_freeresult(delresult); - return False; - } - nis_freeresult(delresult); - return True; -} + /* Functions your pdb module doesn't provide should be set + * to NULL */ -/************************************************************************ - Routine to add an entry to the nisplus passwd file. -*************************************************************************/ -BOOL pdb_add_sam_account(SAM_ACCOUNT * newpwd) -{ - int local_user = 0; - char *pfile; - pstring pfiletmp; - char *nisname; - nis_result *result = NULL, - *tblresult = NULL; - nis_object new_obj; - entry_col *ecol; - int ta_maxcol; - - /* - * 1. find user domain. - * a. try nis search in passwd.org_dir - if found use domain from result. - * b. try getpwnam. this may be needed if user is defined - * in /etc/passwd file (or elsewere) and not in passwd.org_dir. - * if found, use host default domain. - * c. exit with False - no such user. - * - * 2. add user - * a. find smbpasswd table - * search pfile in user domain if not found, try host default - * domain. - * b. smbpasswd domain is found, fill data and add entry. - * - * pfile should contain ONLY table name, org_dir will be concated. - * so, at first we will clear path prefix from pfile, and - * then we will use pfiletmp as playground to put together full - * nisname string. - * such approach will make it possible to specify samba private dir - * AND still use NIS+ table. as all domain related data is normally - * stored in org_dir.DOMAIN, this should be ok do do. - */ - - pfile = lp_smb_passwd_file(); - if( strrchr( pfile, '/') ) - pfile = strrchr( pfile, '/') + 1; - - /* - * Check if user is already there. - */ - safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1); - safe_strcat(pfiletmp, ".org_dir", - sizeof(pfiletmp)-strlen(pfiletmp)-1); - - if(pdb_get_username(newpwd) != NULL) { - nisname = make_nisname_from_name(pdb_get_username(newpwd), - pfiletmp); - } else { - return False; - } - - if(!(result = nisp_get_nis_list(nisname, MASTER_ONLY|FOLLOW_LINKS|\ - FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP))) { - return False; - } - if (result->status != NIS_SUCCESS && - result->status != NIS_NOTFOUND) { - DEBUG(3, ( "nis_list failure: %s: %s\n", - nisname, nis_sperrno(result->status))); - nis_freeresult(result); - return False; - } - - if (result->status == NIS_SUCCESS && NIS_RES_NUMOBJ(result) > 0) - { - DEBUG(3, ("User already exists in NIS+ password db: %s\n", - pfile)); - nis_freeresult(result); - return False; - } - - nis_freeresult(result); /* no such user, free results */ - - /* - * check for user in unix password database. we need this to get - * domain, where smbpasswd entry should be stored. - */ - - nisname = make_nisname_from_name(pdb_get_username(newpwd), - "passwd.org_dir"); - - result = nisp_get_nis_list(nisname, - MASTER_ONLY|FOLLOW_LINKS|FOLLOW_PATH|\ - EXPAND_NAME|HARD_LOOKUP); - - if (result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0) - { - struct passwd *passwd; - DEBUG(3, ("nis_list failure: %s: %s\n", - nisname, nis_sperrno(result->status))); - nis_freeresult(result); - - if (!(passwd = getpwnam_alloc(pdb_get_username(newpwd)))) { - /* no such user in system! */ - return False; - } - passwd_free(&passwd); + (*pdb_method)->setsampwent = nisplussam_setsampwent; + (*pdb_method)->endsampwent = nisplussam_endsampwent; + (*pdb_method)->getsampwent = nisplussam_getsampwent; + (*pdb_method)->getsampwnam = nisplussam_getsampwnam; + (*pdb_method)->getsampwsid = nisplussam_getsampwsid; + (*pdb_method)->add_sam_account = nisplussam_add_sam_account; + (*pdb_method)->update_sam_account = nisplussam_update_sam_account; + (*pdb_method)->delete_sam_account = nisplussam_delete_sam_account; + (*pdb_method)->private_data = private; - /* - * user is defined, but not in passwd.org_dir. - */ - local_user = 1; - } else { - safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1); - safe_strcat(pfiletmp, ".", sizeof(pfiletmp)-strlen(pfiletmp)-1); - safe_strcat(pfiletmp, NIS_RES_OBJECT(result)->zo_domain, - sizeof(pfiletmp)-strlen(pfiletmp)-1); - nis_freeresult(result); /* not needed any more */ - - tblresult = nisp_get_nis_list(pfiletmp, - MASTER_ONLY|FOLLOW_LINKS|\ - FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP); - } - - if (local_user || tblresult->status != NIS_SUCCESS) - { - /* - * no user domain or - * smbpasswd table not found in user domain, fallback to - * default domain. - */ - if (!local_user) /* free previous failed search result */ - nis_freeresult(tblresult); - - safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1); - safe_strcat(pfiletmp, ".org_dir", - sizeof(pfiletmp)-strlen(pfiletmp)-1); - tblresult = nis_lookup(pfiletmp, MASTER_ONLY|FOLLOW_LINKS|\ - FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP); - if (tblresult->status != NIS_SUCCESS) - { - /* still nothing. bail out */ - nis_freeresult(tblresult); - DEBUG(3, ( "nis_lookup failure: %s\n", - nis_sperrno(tblresult->status))); - return False; - } - /* we need full name for nis_add_entry() */ - safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1); - safe_strcat(pfiletmp, ".", sizeof(pfiletmp)-strlen(pfiletmp)-1); - safe_strcat(pfiletmp, NIS_RES_OBJECT(tblresult)->zo_domain, - sizeof(pfiletmp)-strlen(pfiletmp)-1); - } - - memset((char *)&new_obj, 0, sizeof (new_obj)); - /* fill entry headers */ - /* we do not free these. */ - new_obj.zo_name = NIS_RES_OBJECT(tblresult)->zo_name; - new_obj.zo_owner = NIS_RES_OBJECT(tblresult)->zo_owner; - new_obj.zo_group = NIS_RES_OBJECT(tblresult)->zo_group; - new_obj.zo_domain = NIS_RES_OBJECT(tblresult)->zo_domain; - /* uints */ - new_obj.zo_access = NIS_RES_OBJECT(tblresult)->zo_access; - new_obj.zo_ttl = NIS_RES_OBJECT(tblresult)->zo_ttl; - - new_obj.zo_data.zo_type = ENTRY_OBJ; - new_obj.EN_data.en_type = - NIS_RES_OBJECT(tblresult)->TA_data.ta_type; - - ta_maxcol = NIS_RES_OBJECT(tblresult)->TA_data.ta_maxcol; - - if(!(ecol = (entry_col*)malloc(ta_maxcol*sizeof(entry_col)))) { - DEBUG(0, ("memory allocation failure\n")); - nis_freeresult(tblresult); - return False; - } - - memset((char *)ecol, 0, ta_maxcol*sizeof (entry_col)); - new_obj.EN_data.en_cols.en_cols_val = ecol; - new_obj.EN_data.en_cols.en_cols_len = ta_maxcol; - - init_nisp_from_sam(&new_obj, newpwd, NULL); - - DEBUG(10, ( "add NIS+ entry: %s\n", nisname)); - result = nis_add_entry(pfiletmp, &new_obj, 0); - - free(ecol); /* free allocated entry space */ - - if (result->status != NIS_SUCCESS) - { - DEBUG(3, ( "NIS+ table update failed: %s\n", - nisname, nis_sperrno(result->status))); - nis_freeresult(tblresult); - nis_freeresult(result); - return False; - } - - nis_freeresult(tblresult); - nis_freeresult(result); - - return True; + return NT_STATUS_OK; } -/************************************************************************ - Routine to modify the nisplus passwd entry. -************************************************************************/ -BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd) +#else +NTSTATUS pdb_init_nisplussam (PDB_CONTEXT * c, PDB_METHODS ** m, + const char *l) { - nis_result *result, *addresult; - nis_object *obj; - nis_object new_obj; - entry_col *ecol; - int ta_maxcol; - char *pfile = lp_smb_passwd_file(); - pstring nisname; - int i; - - if (!*pfile) - { - DEBUG(0, ("no SMB password file set\n")); - return False; - } - if( strrchr( pfile, '/') ) - pfile = strrchr( pfile, '/') + 1; - - slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.org_dir", - pdb_get_username(newpwd), pfile); - - DEBUG(10, ("search by name: %s\n", nisname)); - - /* Search the table. */ - - if( !(result = nisp_get_nis_list(nisname, MASTER_ONLY|FOLLOW_LINKS|\ - FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP))) { - return False; - } - - if(result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0) { - /* User not found. */ - DEBUG(0,("user not found in NIS+\n")); - nis_freeresult(result); - return False; - } - - obj = NIS_RES_OBJECT(result); - DEBUG(6,("entry found in %s\n", obj->zo_domain)); - - /* we must create new stub object with EN_MODIFIED flag. - this is because obj from result is going to be freed and - we do not want to break it or cause memory leaks or corruption. - */ - - memmove((char *)&new_obj, obj, sizeof (new_obj)); - ta_maxcol = obj->TA_data.ta_maxcol; - - if(!(ecol = (entry_col*)malloc(ta_maxcol*sizeof(entry_col)))) { - DEBUG(0, ("memory allocation failure\n")); - nis_freeresult(result); - return False; - } - - memmove((char *)ecol, obj->EN_data.en_cols.en_cols_val, - ta_maxcol*sizeof (entry_col)); - new_obj.EN_data.en_cols.en_cols_val = ecol; - new_obj.EN_data.en_cols.en_cols_len = ta_maxcol; - - if ( init_nisp_from_sam(&new_obj, newpwd, obj) == True ) { - slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.%s", - pdb_get_username(newpwd), pfile, obj->zo_domain); - - DEBUG(10, ("NIS+ table update: %s\n", nisname)); - addresult = - nis_modify_entry(nisname, &new_obj, - MOD_SAMEOBJ | FOLLOW_PATH | EXPAND_NAME | HARD_LOOKUP); - - if(addresult->status != NIS_SUCCESS) { - DEBUG(0, ("NIS+ table update failed: %s %s\n", - nisname, nis_sperrno(addresult->status))); - nis_freeresult(addresult); - nis_freeresult(result); - free(ecol); - return False; - } - - DEBUG(6,("password changed\n")); - nis_freeresult(addresult); - } else { - DEBUG(6,("nothing to change!\n")); - } - - free(ecol); - nis_freeresult(result); - - return True; + DEBUG (0, ("nisplus sam not compiled in!\n")); + return NT_STATUS_UNSUCCESSFUL; } - -#else - void nisplus_dummy_function(void); - void nisplus_dummy_function(void) { } /* stop some compilers complaining */ -#endif /* WITH_NISPLUSSAM */ +#endif /* WITH_NISPLUS_SAM */ diff --git a/source3/passdb/pdb_plugin.c b/source3/passdb/pdb_plugin.c index 1a246631fe7..ea67da23a55 100644 --- a/source3/passdb/pdb_plugin.c +++ b/source3/passdb/pdb_plugin.c @@ -46,7 +46,7 @@ NTSTATUS pdb_init_plugin(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, con trim_string(plugin_name, " ", " "); DEBUG(5, ("Trying to load sam plugin %s\n", plugin_name)); - dl_handle = sys_dlopen(plugin_name, RTLD_NOW | RTLD_GLOBAL ); + dl_handle = sys_dlopen(plugin_name, RTLD_NOW ); if (!dl_handle) { DEBUG(0, ("Failed to load sam plugin %s using sys_dlopen (%s)\n", plugin_name, sys_dlerror())); return NT_STATUS_UNSUCCESSFUL; @@ -59,7 +59,7 @@ NTSTATUS pdb_init_plugin(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, con return NT_STATUS_UNSUCCESSFUL; } - if (plugin_version()!=PASSDB_INTERFACE_VERSION) { + if (plugin_version() != PASSDB_INTERFACE_VERSION) { sys_dlclose(dl_handle); DEBUG(0, ("Wrong PASSDB_INTERFACE_VERSION! sam plugin has version %d and version %d is needed! Please update!\n", plugin_version(),PASSDB_INTERFACE_VERSION)); diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c index d40ea03511c..04c0d333e43 100644 --- a/source3/passdb/pdb_smbpasswd.c +++ b/source3/passdb/pdb_smbpasswd.c @@ -1327,7 +1327,8 @@ static BOOL smbpasswd_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *u call getpwnam() for unix account information until we have found the correct entry ***************************************************************/ -static BOOL smbpasswd_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *sam_acct, const char *username) +static BOOL smbpasswd_getsampwnam(struct pdb_methods *my_methods, + SAM_ACCOUNT *sam_acct, const char *username) { struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data; struct smb_passwd *smb_pw; @@ -1381,6 +1382,16 @@ static BOOL smbpasswd_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *s DEBUG(10, ("pdb_getsampwrid: search by rid: %d\n", rid)); + /* More special case 'guest account' hacks... */ + if (rid == DOMAIN_USER_RID_GUEST) { + const char *guest_account = lp_guestaccount(); + if (!(guest_account && *guest_account)) { + DEBUG(1, ("Guest account not specfied!\n")); + return False; + } + return smbpasswd_getsampwnam(my_methods, sam_acct, guest_account); + } + /* Open the sam password file - not for update. */ fp = startsmbfilepwent(smbpasswd_state->smbpasswd_file, PWF_READ, &(smbpasswd_state->pw_file_lock_depth)); diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c index ec67b743900..08a0e9c9acf 100644 --- a/source3/passdb/secrets.c +++ b/source3/passdb/secrets.c @@ -68,7 +68,7 @@ void *secrets_fetch(const char *key, size_t *size) /* store a secrets entry */ -BOOL secrets_store(const char *key, void *data, size_t size) +BOOL secrets_store(const char *key, const void *data, size_t size) { TDB_DATA kbuf, dbuf; secrets_init(); @@ -95,7 +95,7 @@ BOOL secrets_delete(const char *key) return tdb_delete(tdb, kbuf) == 0; } -BOOL secrets_store_domain_sid(char *domain, DOM_SID *sid) +BOOL secrets_store_domain_sid(char *domain, const DOM_SID *sid) { fstring key; @@ -148,7 +148,7 @@ BOOL secrets_fetch_domain_guid(char *domain, GUID *guid) strupper(key); dyn_guid = (GUID *)secrets_fetch(key, &size); - DEBUG(6,("key is %s, guid is at %x, size is %d\n", key, dyn_guid, size)); + DEBUG(6,("key is %s, size is %d\n", key, (int)size)); if ((NULL == dyn_guid) && (ROLE_DOMAIN_PDC == lp_server_role())) { uuid_generate_random(&new_guid); @@ -206,8 +206,27 @@ char *trustdom_keystr(const char *domain) } /************************************************************************ - Routine to get the machine trust account password for a domain. + Lock the trust password entry. ************************************************************************/ + +BOOL secrets_lock_trust_account_password(char *domain, BOOL dolock) +{ + if (!tdb) + return False; + + if (dolock) + return (tdb_lock_bystring(tdb, trust_keystr(domain)) == 0); + else + tdb_unlock_bystring(tdb, trust_keystr(domain)); + return True; +} + +/************************************************************************ + Routine to get the trust account password for a domain. + The user of this function must have locked the trust password file using + the above call. +************************************************************************/ + BOOL secrets_fetch_trust_account_password(char *domain, uint8 ret_pwd[16], time_t *pass_last_set_time) { @@ -243,6 +262,7 @@ BOOL secrets_fetch_trust_account_password(char *domain, uint8 ret_pwd[16], /************************************************************************ Routine to get account password to trusted domain ************************************************************************/ + BOOL secrets_fetch_trusted_domain_password(char *domain, char** pwd, DOM_SID *sid, time_t *pass_last_set_time) { @@ -559,3 +579,69 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, int max_num return status; } +static SIG_ATOMIC_T gotalarm; + +/*************************************************************** + Signal function to tell us we timed out. +****************************************************************/ + +static void gotalarm_sig(void) +{ + gotalarm = 1; +} + +/* + lock the secrets tdb based on a string - this is used as a primitive form of mutex + between smbd instances. +*/ +BOOL secrets_named_mutex(const char *name, unsigned int timeout) +{ + TDB_DATA key; + int ret; + + if (!message_init()) + return False; + + key.dptr = (char *)name; + key.dsize = strlen(name)+1; + + /* Allow tdb_chainlock to be interrupted by an alarm. */ + gotalarm = 0; + tdb_set_lock_alarm(&gotalarm); + + if (timeout) { + CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); + alarm(timeout); + } + + ret = tdb_chainlock(tdb, key); + + /* Prevent tdb_chainlock from being interrupted by an alarm. */ + tdb_set_lock_alarm(NULL); + + if (timeout) { + alarm(0); + CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN); + if (gotalarm) + return False; + } + + if (ret == 0) + DEBUG(10,("secrets_named_mutex: got mutex for %s\n", name )); + + return (ret == 0); +} + +/* + unlock a named mutex +*/ +void secrets_named_mutex_release(char *name) +{ + TDB_DATA key; + + key.dptr = name; + key.dsize = strlen(name)+1; + + tdb_chainunlock(tdb, key); + DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name )); +} diff --git a/source3/printing/notify.c b/source3/printing/notify.c index 925d49a21d6..003718ed724 100644 --- a/source3/printing/notify.c +++ b/source3/printing/notify.c @@ -22,21 +22,99 @@ #include "printing.h" -/* - * Print notification routines - */ +static TALLOC_CTX *send_ctx; + +static struct notify_queue { + struct notify_queue *next, *prev; + void *buf; + size_t buflen; +} *notify_queue_head = NULL; + +/******************************************************************* + Used to decide if we need a short select timeout. +*******************************************************************/ + +BOOL print_notify_messages_pending(void) +{ + return (notify_queue_head != NULL); +} + +/******************************************************************* + Actually send the batched messages. +*******************************************************************/ + +void print_notify_send_messages(void) +{ + TDB_CONTEXT *tdb; + char *buf; + struct notify_queue *pq; + size_t msg_count = 0, offset = 0; + + if (!print_notify_messages_pending()) + return; + + if (!send_ctx) + return; + + tdb = conn_tdb_ctx(); + + if (!tdb) { + DEBUG(3, ("Failed to open connections database in send_spoolss_notify2_msg\n")); + return; + } + + /* Count the space needed to send the messages. */ + for (pq = notify_queue_head; pq; pq = pq->next, msg_count++) + offset += (pq->buflen + 4); + + offset += 4; /* For count. */ + + buf = talloc(send_ctx, offset); + if (!buf) { + DEBUG(0,("print_notify_send_messages: Out of memory\n")); + talloc_destroy_pool(send_ctx); + return; + } + + offset = 0; + SIVAL(buf,offset,msg_count); + offset += 4; + for (pq = notify_queue_head; pq; pq = pq->next) { + SIVAL(buf,offset,pq->buflen); + offset += 4; + memcpy(buf + offset, pq->buf, pq->buflen); + offset += pq->buflen; + } + + DEBUG(5, ("print_notify_send_messages: sending %d print notify message%s\n", + msg_count, msg_count != 1 ? "s" : "")); + + message_send_all(tdb, MSG_PRINTER_NOTIFY2, buf, offset, False, NULL); + talloc_destroy_pool(send_ctx); + notify_queue_head = NULL; +} + +/******************************************************************* + Batch up print notify messages. +*******************************************************************/ static void send_spoolss_notify2_msg(struct spoolss_notify_msg *msg) { char *buf = NULL; - int buflen = 0, len; - TDB_CONTEXT *tdb; + size_t buflen = 0, len; + struct notify_queue *pnqueue, *tmp_ptr; /* Let's not waste any time with this */ if (lp_disable_spoolss()) return; + if (!send_ctx) + send_ctx = talloc_init_named("print notify queue"); + + if (!send_ctx) + goto fail; + /* Flatten data into a message */ again: @@ -59,24 +137,34 @@ again: msg->len, msg->notify.data); if (buflen != len) { - buf = Realloc(buf, len); + buf = talloc_realloc(send_ctx, buf, len); + if (!buf) + goto fail; buflen = len; goto again; } - /* Send message */ + /* Store the message on the pending queue. */ - tdb = conn_tdb_ctx(); + pnqueue = talloc(send_ctx, sizeof(*pnqueue)); + if (!pnqueue) + goto fail; - if (!tdb) { - DEBUG(3, ("Failed to open connections database in send_spoolss_notify2_msg\n")); - goto done; - } - - message_send_all(tdb, MSG_PRINTER_NOTIFY2, buf, buflen, False, NULL); + pnqueue->buf = buf; + pnqueue->buflen = buflen; + + DEBUG(5, ("send_spoolss_notify2_msg: appending message 0x%02x/0x%02x to notify_queue_head\n", msg->type, msg->field)); + + /* Note we add to the end of the list to ensure + * the messages are sent in the order they were received. JRA. + */ + DLIST_ADD_END(notify_queue_head, pnqueue, tmp_ptr); + + return; + + fail: -done: - SAFE_FREE(buf); + DEBUG(0,("send_spoolss_notify2_msg: Out of memory.\n")); } static void send_notify_field_values(const char *printer_name, uint32 type, diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 3b85fce0200..58eba9d87e8 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -1745,7 +1745,7 @@ static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, dbuf = tdb_fetch(tdb_drivers, kbuf); if (!dbuf.dptr) - return WERR_ACCESS_DENIED; + return WERR_UNKNOWN_PRINTER_DRIVER; len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff", &driver.cversion, @@ -1864,7 +1864,7 @@ static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3; int i; - DEBUG(106,("Dumping printer driver at level [%d]\n", level)); + DEBUG(20,("Dumping printer driver at level [%d]\n", level)); switch (level) { @@ -1905,7 +1905,7 @@ static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 /**************************************************************************** ****************************************************************************/ -static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen) +int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen) { int len = 0; @@ -2282,7 +2282,7 @@ static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr) /**************************************************************************** ****************************************************************************/ -static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen) +int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen) { int len = 0; int extra_len = 0; @@ -2407,7 +2407,7 @@ int lookup_printerkey( NT_PRINTER_DATA *data, char *name ) for ( i=0; inum_keys; i++ ) { - if ( strcmp(data->keys[i].name, name) == 0 ) { + if ( strequal(data->keys[i].name, name) ) { DEBUG(12,("lookup_printerkey: Found [%s]!\n", name)); key_index = i; break; @@ -2420,32 +2420,169 @@ int lookup_printerkey( NT_PRINTER_DATA *data, char *name ) /**************************************************************************** ***************************************************************************/ + +uint32 get_printer_subkeys( NT_PRINTER_DATA *data, char* key, fstring **subkeys ) +{ + int i, j; + int key_len; + int num_subkeys = 0; + char *p; + fstring *ptr, *subkeys_ptr = NULL; + fstring subkeyname; + + if ( !data ) + return 0; + + for ( i=0; inum_keys; i++ ) + { + if ( StrnCaseCmp(data->keys[i].name, key, strlen(key)) == 0 ) + { + /* match sure it is a subkey and not the key itself */ + + key_len = strlen( key ); + if ( strlen(data->keys[i].name) == key_len ) + continue; + + /* get subkey path */ + + p = data->keys[i].name + key_len; + if ( *p == '\\' ) + p++; + fstrcpy( subkeyname, p ); + if ( (p = strchr( subkeyname, '\\' )) ) + *p = '\0'; + + /* don't add a key more than once */ + + for ( j=0; jdata; + empty_slot = data->num_keys; + + if ( !key ) + return WERR_INVALID_PARAM; - for ( i=0; inum_keys; i++ ) + /* remove all keys */ + + if ( !strlen(key) ) { - DEBUG(8,("delete_all_printer_data: Removed all Printer Data from key [%s]\n", - data->keys[i].name)); + for ( i=0; inum_keys; i++ ) + { + DEBUG(8,("delete_all_printer_data: Removed all Printer Data from key [%s]\n", + data->keys[i].name)); - SAFE_FREE( data->keys[i].name ); - regval_ctr_destroy( &data->keys[i].values ); - } + SAFE_FREE( data->keys[i].name ); + regval_ctr_destroy( &data->keys[i].values ); + } - SAFE_FREE( data->keys ); + DEBUG(8,("delete_all_printer_data: Removed all Printer Data from printer [%s]\n", + p2->printername )); + + SAFE_FREE( data->keys ); + ZERO_STRUCTP( data ); - DEBUG(8,("delete_all_printer_data: Removed all Printer Data from printer [%s]\n", - p2->printername )); + return WERR_OK; + } + + /* remove a specific key (and all subkeys) */ - ZERO_STRUCTP( data ); + for ( i=0; inum_keys; i++ ) + { + if ( StrnCaseCmp( data->keys[i].name, key, strlen(key)) == 0 ) + { + DEBUG(8,("delete_all_printer_data: Removed all Printer Data from key [%s]\n", + data->keys[i].name)); + + SAFE_FREE( data->keys[i].name ); + regval_ctr_destroy( &data->keys[i].values ); + + /* mark the slot as empty */ + + ZERO_STRUCTP( &data->keys[i] ); + } + } + + /* find the first empty slot */ + + for ( i=0; inum_keys; i++ ) { + if ( !data->keys[i].name ) { + empty_slot = i; + removed_keys++; + break; + } + } + + if ( i == data->num_keys ) + /* nothing was removed */ + return WERR_INVALID_PARAM; + + /* move everything down */ - return result; + for ( i=empty_slot+1; inum_keys; i++ ) { + if ( data->keys[i].name ) { + memcpy( &data->keys[empty_slot], &data->keys[i], sizeof(NT_PRINTER_KEY) ); + ZERO_STRUCTP( &data->keys[i] ); + empty_slot++; + removed_keys++; + } + } + + /* update count */ + + data->num_keys -= removed_keys; + + /* sanity check to see if anything is left */ + + if ( !data->num_keys ) + { + DEBUG(8,("delete_all_printer_data: No keys left for printer [%s]\n", p2->printername )); + + SAFE_FREE( data->keys ); + ZERO_STRUCTP( data ); + } + + return WERR_OK; } /**************************************************************************** @@ -2465,11 +2602,8 @@ WERROR delete_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, char *key, char *value key_index = lookup_printerkey( &p2->data, key ); if ( key_index == -1 ) - key_index = add_new_printer_key( &p2->data, key ); + return WERR_OK; - if ( key_index == -1 ) - return WERR_NOMEM; - regval_ctr_delvalue( &p2->data.keys[key_index].values, value ); DEBUG(8,("delete_printer_data: Removed key => [%s], value => [%s]\n", @@ -2504,8 +2638,8 @@ WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, char *key, char *value, regval_ctr_addvalue( &p2->data.keys[key_index].values, value, type, data, real_len ); - DEBUG(8,("add_printer_data: Added key => [%s], value => [%s], size => [%d]\n", - key, value, real_len )); + DEBUG(8,("add_printer_data: Added key => [%s], value => [%s], type=> [%d], size => [%d]\n", + key, value, type, real_len )); return result; } @@ -2569,7 +2703,7 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, char *buf, int buflen) * Should only be one '\' in the string returned. */ - str = strchr( string, '\\'); + str = strrchr( string, '\\'); /* Put in "PrinterDriverData" is no key specified */ @@ -2598,7 +2732,7 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, char *buf, int buflen) regval_ctr_addvalue( &printer_data->keys[key_index].values, valuename, type, data_p, size ); - DEBUG(8,("specific: [%s\\%s], len: %d\n", keyname, valuename, size)); + DEBUG(8,("specific: [%s:%s], len: %d\n", keyname, valuename, size)); } return len; @@ -3046,7 +3180,7 @@ static BOOL set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr ) * should not be any (if there are delete them). */ - delete_all_printer_data( info_ptr ); + delete_all_printer_data( info_ptr, "" ); slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info_ptr->drivername); @@ -3074,16 +3208,17 @@ static BOOL set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr ) * the initialization save. Change it to reflect the new printer. */ + if ( info.devmode ) { ZERO_STRUCT(info.devmode->devicename); fstrcpy(info.devmode->devicename, info_ptr->printername); - + } /* * NT/2k does not change out the entire DeviceMode of a printer * when changing the driver. Only the driverextra, private, & * driverversion fields. --jerry (Thu Mar 14 08:58:43 CST 2002) * - * Later e4xamination revealed that Windows NT/2k does reset the + * Later examination revealed that Windows NT/2k does reset the * the printer's device mode, bit **only** when you change a * property of the device mode such as the page orientation. * --jerry @@ -3095,9 +3230,8 @@ static BOOL set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr ) free_nt_devicemode(&info_ptr->devmode); info_ptr->devmode = info.devmode; - - DEBUG(10,("set_driver_init_2: Set printer [%s] init DEVMODE for driver [%s]\n", - info_ptr->printername, info_ptr->drivername)); + DEBUG(10,("set_driver_init_2: Set printer [%s] init %s DEVMODE for driver [%s]\n", + info_ptr->printername, info_ptr->devmode?"VALID":"NULL", info_ptr->drivername)); /* Add the printer data 'values' to the new printer */ @@ -3232,17 +3366,162 @@ uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level) { case 2: { - result=update_driver_init_2(printer.info_2); + result = update_driver_init_2(printer.info_2); break; } default: - result=1; + result = 1; break; } return result; } +/**************************************************************************** + Convert the printer data value, a REG_BINARY array, into an initialization + DEVMODE. Note: the array must be parsed as if it was a DEVMODE in an rpc... + got to keep the endians happy :). +****************************************************************************/ + +static BOOL convert_driver_init( TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode, uint8 *data, uint32 data_len ) +{ + BOOL result = False; + prs_struct ps; + DEVICEMODE devmode; + + ZERO_STRUCT(devmode); + + prs_init(&ps, 0, ctx, UNMARSHALL); + ps.data_p = (char *)data; + ps.buffer_size = data_len; + + if (spoolss_io_devmode("phantom DEVMODE", &ps, 0, &devmode)) + result = convert_devicemode("", &devmode, &nt_devmode); + else + DEBUG(10,("convert_driver_init: error parsing DEVMODE\n")); + + return result; +} + +/**************************************************************************** + Set the DRIVER_INIT info in the tdb. Requires Win32 client code that: + + 1. Use the driver's config DLL to this UNC printername and: + a. Call DrvPrintEvent with PRINTER_EVENT_INITIALIZE + b. Call DrvConvertDevMode with CDM_DRIVER_DEFAULT to get default DEVMODE + 2. Call SetPrinterData with the 'magic' key and the DEVMODE as data. + + The last step triggers saving the "driver initialization" information for + this printer into the tdb. Later, new printers that use this driver will + have this initialization information bound to them. This simulates the + driver initialization, as if it had run on the Samba server (as it would + have done on NT). + + The Win32 client side code requirement sucks! But until we can run arbitrary + Win32 printer driver code on any Unix that Samba runs on, we are stuck with it. + + It would have been easier to use SetPrinter because all the UNMARSHALLING of + the DEVMODE is done there, but 2K/XP clients do not set the DEVMODE... think + about it and you will realize why. JRR 010720 +****************************************************************************/ + +static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, uint8 *data, uint32 data_len ) +{ + WERROR status = WERR_OK; + TALLOC_CTX *ctx = NULL; + NT_DEVICEMODE *nt_devmode = NULL; + NT_DEVICEMODE *tmp_devmode = printer->info_2->devmode; + + /* + * When the DEVMODE is already set on the printer, don't try to unpack it. + */ + DEBUG(8,("save_driver_init_2: Enter...\n")); + + if ( !printer->info_2->devmode && data_len ) + { + /* + * Set devmode on printer info, so entire printer initialization can be + * saved to tdb. + */ + + if ((ctx = talloc_init()) == NULL) + return WERR_NOMEM; + + if ((nt_devmode = (NT_DEVICEMODE*)malloc(sizeof(NT_DEVICEMODE))) == NULL) { + status = WERR_NOMEM; + goto done; + } + + ZERO_STRUCTP(nt_devmode); + + /* + * The DEVMODE is held in the 'data' component of the param in raw binary. + * Convert it to to a devmode structure + */ + if ( !convert_driver_init( ctx, nt_devmode, data, data_len )) { + DEBUG(10,("save_driver_init_2: error converting DEVMODE\n")); + status = WERR_INVALID_PARAM; + goto done; + } + + printer->info_2->devmode = nt_devmode; + } + + /* + * Pack up and add (or update) the DEVMODE and any current printer data to + * a 'driver init' element in the tdb + * + */ + + if ( update_driver_init(*printer, 2) != 0 ) { + DEBUG(10,("save_driver_init_2: error updating DEVMODE\n")); + status = WERR_NOMEM; + goto done; + } + + /* + * If driver initialization info was successfully saved, set the current + * printer to match it. This allows initialization of the current printer + * as well as the driver. + */ + status = mod_a_printer(*printer, 2); + if (!W_ERROR_IS_OK(status)) { + DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n", + printer->info_2->printername)); + } + + done: + talloc_destroy(ctx); + free_nt_devicemode( &nt_devmode ); + + printer->info_2->devmode = tmp_devmode; + + return status; +} + +/**************************************************************************** + Update the driver init info (DEVMODE and specifics) for a printer +****************************************************************************/ + +WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, uint8 *data, uint32 data_len) +{ + WERROR status = WERR_OK; + + switch (level) + { + case 2: + { + status = save_driver_init_2( printer, data, data_len ); + break; + } + default: + status = WERR_UNKNOWN_LEVEL; + break; + } + + return status; +} + /**************************************************************************** Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory. ****************************************************************************/ @@ -3445,13 +3724,13 @@ uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level) to a printer ****************************************************************************/ -BOOL printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i ) +BOOL printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3 ) { int snum; int n_services = lp_numservices(); NT_PRINTER_INFO_LEVEL *printer = NULL; - if ( !i ) + if ( !info_3 ) return False; DEBUG(5,("printer_driver_in_use: Beginning search through ntprinters.tdb...\n")); @@ -3466,7 +3745,7 @@ BOOL printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i ) if ( !W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))) ) continue; - if ( !StrCaseCmp(i->name, printer->info_2->drivername) ) { + if ( !StrCaseCmp(info_3->name, printer->info_2->drivername) ) { free_a_printer( &printer, 2 ); return True; } @@ -3488,7 +3767,7 @@ BOOL printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i ) static BOOL drv_file_in_use( char* file, NT_PRINTER_DRIVER_INFO_LEVEL_3 *info ) { - char *s; + int i = 0; if ( !info ) return False; @@ -3504,16 +3783,18 @@ static BOOL drv_file_in_use( char* file, NT_PRINTER_DRIVER_INFO_LEVEL_3 *info ) if ( strequal(file, info->helpfile) ) return True; - - s = (char*) info->dependentfiles; - if ( s ) { - while ( *s ) - { - if ( strequal(file, s) ) - return True; - s += strlen(s) + 1; - } + /* see of there are any dependent files to examine */ + + if ( !info->dependentfiles ) + return False; + + while ( *info->dependentfiles[i] ) + { + if ( strequal(file, info->dependentfiles[i]) ) + return True; + + i++; } return False; @@ -3525,27 +3806,20 @@ static BOOL drv_file_in_use( char* file, NT_PRINTER_DRIVER_INFO_LEVEL_3 *info ) input parameter from the list *********************************************************************/ -static void trim_dependent_file( char* s ) +static void trim_dependent_file( fstring files[], int idx ) { - char *p; - - /* set p to the next character string in the list */ - - p = s + strlen( s ) + 1; - - /* check to see that we have another string to copy back */ - if ( *p == '\0' ) + /* bump everything down a slot */ + + while( *files[idx+1] ) { - /* loop over s copying characters from p to s */ - while ( *p!='\0' && *(p+1)!='\0' ) - *s++ = *p++; + fstrcpy( files[idx], files[idx+1] ); + idx++; } - /* add the two trailing NULL's */ - - *s = '\0'; - *(s+1) = '\0'; + *files[idx] = '\0'; + + return; } /********************************************************************** @@ -3555,8 +3829,8 @@ static void trim_dependent_file( char* s ) static BOOL trim_overlap_drv_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *src, NT_PRINTER_DRIVER_INFO_LEVEL_3 *drv ) { - BOOL in_use = False; - char *s; + BOOL in_use = False; + int i = 0; if ( !src || !drv ) return False; @@ -3565,33 +3839,43 @@ static BOOL trim_overlap_drv_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *src, if ( drv_file_in_use(src->driverpath, drv) ) { in_use = True; + DEBUG(10,("Removing driverfile [%s] from list\n", src->driverpath)); fstrcpy( src->driverpath, "" ); } if ( drv_file_in_use(src->datafile, drv) ) { in_use = True; + DEBUG(10,("Removing datafile [%s] from list\n", src->datafile)); fstrcpy( src->datafile, "" ); } if ( drv_file_in_use(src->configfile, drv) ) { in_use = True; + DEBUG(10,("Removing configfile [%s] from list\n", src->configfile)); fstrcpy( src->configfile, "" ); } - s = (char*)src->dependentfiles; - - if ( s ) { - while ( *s ) - { - if ( drv_file_in_use(s, drv) ) { - in_use = True; - trim_dependent_file( s ); - } - else - s += strlen(s) + 1; - } + if ( drv_file_in_use(src->helpfile, drv) ) { + in_use = True; + DEBUG(10,("Removing helpfile [%s] from list\n", src->helpfile)); + fstrcpy( src->helpfile, "" ); } + + /* are there any dependentfiles to examine? */ + + if ( !src->dependentfiles ) + return in_use; + while ( *src->dependentfiles[i] ) + { + if ( drv_file_in_use(src->dependentfiles[i], drv) ) { + in_use = True; + DEBUG(10,("Removing [%s] from dependent file list\n", src->dependentfiles[i])); + trim_dependent_file( src->dependentfiles, i ); + } + else + i++; + } return in_use; } @@ -3615,59 +3899,62 @@ BOOL printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info ) fstring *list = NULL; NT_PRINTER_DRIVER_INFO_LEVEL driver; + if ( !info ) + return False; + + version = info->cversion; + /* loop over all driver versions */ DEBUG(5,("printer_driver_files_in_use: Beginning search through ntdrivers.tdb...\n")); - for ( version=0; versionenvironment, version); + list = NULL; + ndrivers = get_ntdrivers(&list, info->environment, version); - DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", - ndrivers, info->environment, version)); + DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", + ndrivers, info->environment, version)); - if (ndrivers == -1) - continue; - - /* check each driver for overlap in files */ + /* check each driver for overlap in files */ - for (i=0; ienvironment, version)) ) - { - SAFE_FREE(list); - return True; - } + if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, list[i], + info->environment, version)) ) + { + SAFE_FREE(list); + return True; + } - /* check if d2 uses any files from d1 */ - /* only if this is a different driver than the one being deleted */ + /* check if d2 uses any files from d1 */ + /* only if this is a different driver than the one being deleted */ - if ( !strequal(info->name, driver.info_3->name) - || (info->cversion != driver.info_3->cversion) ) - { - if ( trim_overlap_drv_files(info, driver.info_3) ) { - free_a_printer_driver(driver, 3); - SAFE_FREE( list ); - return True; - } + if ( !strequal(info->name, driver.info_3->name) ) + { + if ( trim_overlap_drv_files(info, driver.info_3) ) { + free_a_printer_driver(driver, 3); + SAFE_FREE( list ); + return True; } + } - free_a_printer_driver(driver, 3); - } - - SAFE_FREE(list); - } + free_a_printer_driver(driver, 3); + } + + SAFE_FREE(list); DEBUG(5,("printer_driver_files_in_use: Completed search through ntdrivers.tdb...\n")); + driver.info_3 = info; + + if ( DEBUGLEVEL >= 20 ) + dump_a_printer_driver( driver, 3 ); + return False; } @@ -3677,17 +3964,18 @@ BOOL printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info ) this. ****************************************************************************/ -static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, struct current_user *user ) +static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct current_user *user ) { + int i = 0; char *s; connection_struct *conn; DATA_BLOB null_pw; NTSTATUS nt_status; - if ( !i ) + if ( !info_3 ) return False; - DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n", i->name, i->cversion)); + DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n", info_3->name, info_3->cversion)); /* * Connect to the print$ share under the same account as the @@ -3715,49 +4003,55 @@ static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, struct curre /* now delete the files; must strip the '\print$' string from fron of path */ - if ( *i->driverpath ) { - if ( (s = strchr( &i->driverpath[1], '\\' )) != NULL ) { + if ( *info_3->driverpath ) { + if ( (s = strchr( &info_3->driverpath[1], '\\' )) != NULL ) { DEBUG(10,("deleting driverfile [%s]\n", s)); unlink_internals(conn, 0, s); } } - if ( *i->configfile ) { - if ( (s = strchr( &i->configfile[1], '\\' )) != NULL ) { + if ( *info_3->configfile ) { + if ( (s = strchr( &info_3->configfile[1], '\\' )) != NULL ) { DEBUG(10,("deleting configfile [%s]\n", s)); unlink_internals(conn, 0, s); } } - if ( *i->datafile ) { - if ( (s = strchr( &i->datafile[1], '\\' )) != NULL ) { + if ( *info_3->datafile ) { + if ( (s = strchr( &info_3->datafile[1], '\\' )) != NULL ) { DEBUG(10,("deleting datafile [%s]\n", s)); unlink_internals(conn, 0, s); } } - if ( *i->helpfile ) { - if ( (s = strchr( &i->helpfile[1], '\\' )) != NULL ) { + if ( *info_3->helpfile ) { + if ( (s = strchr( &info_3->helpfile[1], '\\' )) != NULL ) { DEBUG(10,("deleting helpfile [%s]\n", s)); unlink_internals(conn, 0, s); } } - s = (char*)i->dependentfiles; + /* check if we are done removing files */ - while ( s && *s ) { - char *file; + if ( info_3->dependentfiles ) + { + while ( *info_3->dependentfiles[i] ) { + char *file; - if ( (file = strchr( s+1, '\\' )) != NULL ) - { - DEBUG(10,("deleting dependent file [%s]\n", file)); - unlink_internals(conn, 0, file ); - file += strlen( file ) + 1; + /* bypass the "\print$" portion of the path */ + + if ( (file = strchr( info_3->dependentfiles[i]+1, '\\' )) != NULL ) + { + DEBUG(10,("deleting dependent file [%s]\n", file)); + unlink_internals(conn, 0, file ); + } + + i++; } - - s = file; } + unbecome_user(); + return True; } @@ -3766,7 +4060,7 @@ static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, struct curre previously looked up. ***************************************************************************/ -static WERROR delete_printer_driver_internal( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, struct current_user *user, +WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct current_user *user, uint32 version, BOOL delete_files ) { pstring key; @@ -3776,14 +4070,14 @@ static WERROR delete_printer_driver_internal( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, /* delete the tdb data first */ - get_short_archi(arch, i->environment); + get_short_archi(arch, info_3->environment); slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, - arch, version, i->name); + arch, version, info_3->name); DEBUG(5,("delete_printer_driver: key = [%s] delete_files = %s\n", key, delete_files ? "TRUE" : "FALSE" )); - ctr.info_3 = i; + ctr.info_3 = info_3; dump_a_printer_driver( ctr, 3 ); kbuf.dptr=key; @@ -3793,7 +4087,7 @@ static WERROR delete_printer_driver_internal( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, dbuf = tdb_fetch( tdb_drivers, kbuf ); if ( !dbuf.dptr ) { - DEBUG(8,("delete_printer_driver_internal: Driver unknown [%s]\n", key)); + DEBUG(8,("delete_printer_driver: Driver unknown [%s]\n", key)); return WERR_UNKNOWN_PRINTER_DRIVER; } @@ -3802,7 +4096,7 @@ static WERROR delete_printer_driver_internal( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, /* ok... the driver exists so the delete should return success */ if (tdb_delete(tdb_drivers, kbuf) == -1) { - DEBUG (0,("delete_printer_driver_internal: fail to delete %s!\n", key)); + DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key)); return WERR_ACCESS_DENIED; } @@ -3813,51 +4107,14 @@ static WERROR delete_printer_driver_internal( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, */ if ( delete_files ) - delete_driver_files( i, user ); - - - DEBUG(5,("delete_printer_driver_internal: driver delete successful [%s]\n", key)); - - return WERR_OK; -} - -/**************************************************************************** - Remove a printer driver from the TDB. This assumes that the the driver was - previously looked up. - ***************************************************************************/ - -WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, struct current_user *user, - uint32 version, BOOL delete_files ) -{ - WERROR err; - - /* - * see if we should delete all versions of this driver - * (DRIVER_ANY_VERSION uis only set for "Windows NT x86") - */ - - if ( version == DRIVER_ANY_VERSION ) - { - /* Windows NT 4.0 */ - - err = delete_printer_driver_internal(i, user, 2, delete_files ); - if ( !W_ERROR_IS_OK(err) && (W_ERROR_V(err) != ERRunknownprinterdriver ) ) - return err; + delete_driver_files( info_3, user ); - /* Windows 2000/XP */ - err = delete_printer_driver_internal(i, user, 3, delete_files ); - if ( !W_ERROR_IS_OK(err) && (W_ERROR_V(err) != ERRunknownprinterdriver ) ) - return err; + DEBUG(5,("delete_printer_driver: driver delete successful [%s]\n", key)); return WERR_OK; } - /* just delete what they asked for */ - - return delete_printer_driver_internal(i, user, version, delete_files ); -} - /**************************************************************************** Store a security desc for a printer. ****************************************************************************/ diff --git a/source3/printing/print_cups.c b/source3/printing/print_cups.c index 51ebb739a33..2df846aa579 100644 --- a/source3/printing/print_cups.c +++ b/source3/printing/print_cups.c @@ -73,9 +73,9 @@ cups_passwd_cb(const char *prompt) /* I - Prompt */ * system. */ -void -cups_printer_fn(void (*fn)(char *, char *)) /* I - Function to call */ +void cups_printer_fn(void (*fn)(char *, char *)) { + /* I - Function to call */ http_t *http; /* HTTP connection to server */ ipp_t *request, /* IPP Request */ *response; /* IPP Response */ @@ -665,6 +665,10 @@ cups_job_submit(int snum, struct printjob *pjob) httpClose(http); + if ( ret == 0 ) + unlink(pjob->filename); + /* else print_job_end will do it for us */ + return (ret); } diff --git a/source3/printing/printfsp.c b/source3/printing/printfsp.c index ff50ac47c49..8a4e7ea073b 100644 --- a/source3/printing/printfsp.c +++ b/source3/printing/printfsp.c @@ -46,7 +46,7 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname) fstrcat(name, p); } - jobid = print_job_start(¤t_user, SNUM(conn), name); + jobid = print_job_start(¤t_user, SNUM(conn), name, NULL); if (jobid == -1) { file_free(fsp); return NULL; diff --git a/source3/printing/printing.c b/source3/printing/printing.c index cb689c05d66..6474c92c692 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -132,11 +132,13 @@ static pid_t local_pid; static int get_queue_status(int, print_status_struct *); +/* There can be this many printing tdb's open, plus any locked ones. */ #define MAX_PRINT_DBS_OPEN 1 struct tdb_print_db { struct tdb_print_db *next, *prev; TDB_CONTEXT *tdb; + int ref_count; fstring printer_name; }; @@ -149,32 +151,45 @@ static struct tdb_print_db *print_db_head; static struct tdb_print_db *get_print_db_byname(const char *printername) { - struct tdb_print_db *p, *last_entry; + struct tdb_print_db *p = NULL, *last_entry = NULL; int num_open = 0; pstring printdb_path; for (p = print_db_head, last_entry = print_db_head; p; p = p->next) { if (p->tdb && strequal(p->printer_name, printername)) { DLIST_PROMOTE(print_db_head, p); + p->ref_count++; return p; } num_open++; last_entry = p; } + /* Not found. */ if (num_open >= MAX_PRINT_DBS_OPEN) { - /* Recycle the last entry. */ + /* Try and recycle the last entry. */ DLIST_PROMOTE(print_db_head, last_entry); - if (print_db_head->tdb) { - if (tdb_close(print_db_head->tdb)) { - DEBUG(0,("get_print_db: Failed to close tdb for printer %s\n", - print_db_head->printer_name )); - return NULL; + + for (p = print_db_head; p; p = p->next) { + if (p->ref_count) + continue; + if (p->tdb) { + if (tdb_close(print_db_head->tdb)) { + DEBUG(0,("get_print_db: Failed to close tdb for printer %s\n", + print_db_head->printer_name )); + return NULL; + } } + ZERO_STRUCTP(p); + break; } - p = print_db_head; - ZERO_STRUCTP(p); - } else { + if (p) { + DLIST_PROMOTE(print_db_head, p); + p = print_db_head; + } + } + + if (!p) { /* Create one. */ p = (struct tdb_print_db *)malloc(sizeof(struct tdb_print_db)); if (!p) { @@ -201,9 +216,16 @@ static struct tdb_print_db *get_print_db_byname(const char *printername) return NULL; } fstrcpy(p->printer_name, printername); + p->ref_count++; return p; } +static void release_print_db( struct tdb_print_db *pdb) +{ + pdb->ref_count--; + SMB_ASSERT(pdb->ref_count >= 0); +} + /**************************************************************************** Initialise the printing backend. Called once at startup. Does not survive a fork @@ -235,7 +257,10 @@ BOOL print_backend_init(void) pdb = get_print_db_byname(lp_const_servicename(snum)); if (!pdb) continue; - tdb_lock_bystring(pdb->tdb, sversion); + if (tdb_lock_bystring(pdb->tdb, sversion) == -1) { + DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) )); + return False; + } if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) { tdb_traverse(pdb->tdb, tdb_traverse_delete_fn, NULL); tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION); @@ -286,25 +311,74 @@ static TDB_DATA print_key(uint32 jobid) return ret; } +/*********************************************************************** + unpack a pjob from a tdb buffer +***********************************************************************/ + +int unpack_pjob( char* buf, int buflen, struct printjob *pjob ) +{ + int len = 0; + int used; + + if ( !buf || !pjob ) + return -1; + + len += tdb_unpack(buf+len, buflen-len, "dddddddddffff", + &pjob->pid, + &pjob->sysjob, + &pjob->fd, + &pjob->starttime, + &pjob->status, + &pjob->size, + &pjob->page_count, + &pjob->spooled, + &pjob->smbjob, + pjob->filename, + pjob->jobname, + pjob->user, + pjob->queuename); + + if ( len == -1 ) + return -1; + + if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 ) + return -1; + + len += used; + + return len; + +} + /**************************************************************************** Useful function to find a print job in the database. ****************************************************************************/ static struct printjob *print_job_find(int snum, uint32 jobid) { - static struct printjob pjob; - TDB_DATA ret; - struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum)); + static struct printjob pjob; + TDB_DATA ret; + struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum)); + if (!pdb) return NULL; ret = tdb_fetch(pdb->tdb, print_key(jobid)); - if (!ret.dptr || ret.dsize != sizeof(pjob)) - return NULL; + release_print_db(pdb); - memcpy(&pjob, ret.dptr, sizeof(pjob)); - SAFE_FREE(ret.dptr); + if (!ret.dptr) + return NULL; + + if ( pjob.nt_devmode ) + free_nt_devicemode( &pjob.nt_devmode ); + + ZERO_STRUCT( pjob ); + + if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) + return NULL; + + SAFE_FREE(ret.dptr); return &pjob; } @@ -315,9 +389,13 @@ static uint32 sysjob_to_jobid_value; static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA data, void *state) { - struct printjob *pjob = (struct printjob *)data.dptr; + struct printjob *pjob; int *sysjob = (int *)state; + if (!data.dptr || data.dsize == 0) + return 0; + + pjob = (struct printjob *)data.dptr; if (key.dsize != sizeof(uint32)) return 0; @@ -350,6 +428,7 @@ uint32 sysjob_to_jobid(int unix_jobid) pdb = get_print_db_byname(lp_const_servicename(snum)); if (pdb) tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid); + release_print_db(pdb); if (sysjob_to_jobid_value != (uint32)-1) return sysjob_to_jobid_value; } @@ -434,9 +513,12 @@ static void pjob_store_notify(int snum, uint32 jobid, struct printjob *old_data, static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob) { - TDB_DATA old_data, new_data; - BOOL ret; - struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum)); + TDB_DATA old_data, new_data; + BOOL ret = False; + struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum)); + char *buf = NULL; + int len, newlen, buflen; + if (!pdb) return False; @@ -445,20 +527,63 @@ static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob) old_data = tdb_fetch(pdb->tdb, print_key(jobid)); + /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */ + + newlen = 0; + + do { + len = 0; + buflen = newlen; + len += tdb_pack(buf+len, buflen-len, "dddddddddffff", + pjob->pid, + pjob->sysjob, + pjob->fd, + pjob->starttime, + pjob->status, + pjob->size, + pjob->page_count, + pjob->spooled, + pjob->smbjob, + pjob->filename, + pjob->jobname, + pjob->user, + pjob->queuename); + + len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len); + + if (buflen != len) + { + char *tb; + + tb = (char *)Realloc(buf, len); + if (!tb) { + DEBUG(0,("pjob_store: failed to enlarge buffer!\n")); + goto done; + } + else + buf = tb; + newlen = len; + } + } + while ( buflen != len ); + + /* Store new data */ - new_data.dptr = (void *)pjob; - new_data.dsize = sizeof(*pjob); + new_data.dptr = buf; + new_data.dsize = len; ret = (tdb_store(pdb->tdb, print_key(jobid), new_data, TDB_REPLACE) == 0); + release_print_db(pdb); + /* Send notify updates for what has changed */ - if (ret && (old_data.dsize == 0 || old_data.dsize == sizeof(*pjob))) { - pjob_store_notify( - snum, jobid, (struct printjob *)old_data.dptr, - (struct printjob *)new_data.dptr); - free(old_data.dptr); - } + if ( ret && (old_data.dsize == 0 || old_data.dsize == sizeof(*pjob)) ) + pjob_store_notify( snum, jobid, (struct printjob *)old_data.dptr, pjob ); + +done: + SAFE_FREE( old_data.dptr ); + SAFE_FREE( buf ); return ret; } @@ -479,6 +604,7 @@ static void pjob_delete(int snum, uint32 jobid) if (!pjob) { DEBUG(5, ("pjob_delete(): we were asked to delete nonexistent job %u\n", (unsigned int)jobid)); + release_print_db(pdb); return; } @@ -499,6 +625,7 @@ static void pjob_delete(int snum, uint32 jobid) /* Remove from printing.tdb */ tdb_delete(pdb->tdb, print_key(jobid)); + release_print_db(pdb); rap_jobid_delete(snum, jobid); } @@ -569,10 +696,14 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void uint32 jobid; int i; - if (data.dsize != sizeof(pjob) || key.dsize != sizeof(jobid)) + if ( key.dsize != sizeof(jobid) ) return 0; + memcpy(&jobid, key.dptr, sizeof(jobid)); - memcpy(&pjob, data.dptr, sizeof(pjob)); + if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 ) + return 0; + free_nt_devicemode( &pjob.nt_devmode ); + if (ts->snum != lp_servicenumber(pjob.queuename)) { /* this isn't for the queue we are looking at - this cannot happen with the split tdb's. JRA */ @@ -651,6 +782,7 @@ static void print_cache_flush(int snum) return; slprintf(key, sizeof(key)-1, "CACHE/%s", printername); tdb_store_int32(pdb->tdb, key, -1); + release_print_db(pdb); } /**************************************************************************** @@ -671,6 +803,7 @@ static pid_t get_updating_pid(fstring printer_name) key.dsize = strlen(keystr); data = tdb_fetch(pdb->tdb, key); + release_print_db(pdb); if (!data.dptr || data.dsize != sizeof(pid_t)) return (pid_t)-1; @@ -705,6 +838,7 @@ static void set_updating_pid(const fstring printer_name, BOOL delete) if (delete) { tdb_delete(pdb->tdb, key); + release_print_db(pdb); return; } @@ -712,6 +846,7 @@ static void set_updating_pid(const fstring printer_name, BOOL delete) data.dsize = sizeof(pid_t); tdb_store(pdb->tdb, key, data, TDB_REPLACE); + release_print_db(pdb); } /**************************************************************************** @@ -740,13 +875,19 @@ static void print_queue_update(int snum) * This is essentially a mutex on the update. */ - if (get_updating_pid(printer_name) != -1) + if (get_updating_pid(printer_name) != -1) { + release_print_db(pdb); return; + } /* Lock the queue for the database update */ slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name); - tdb_lock_bystring(pdb->tdb, keystr); + if (tdb_lock_bystring(pdb->tdb, keystr) == -1) { + DEBUG(0,("print_queue_update: Failed to lock printer %s database\n", printer_name)); + release_print_db(pdb); + return; + } /* * Ensure that no one else got in here. @@ -759,6 +900,7 @@ static void print_queue_update(int snum) * Someone else is doing the update, exit. */ tdb_unlock_bystring(pdb->tdb, keystr); + release_print_db(pdb); return; } @@ -865,6 +1007,7 @@ static void print_queue_update(int snum) /* Delete our pid from the db. */ set_updating_pid(printer_name, True); + release_print_db(pdb); } /**************************************************************************** @@ -874,9 +1017,13 @@ static void print_queue_update(int snum) BOOL print_job_exists(int snum, uint32 jobid) { struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum)); + BOOL ret; + if (!pdb) return False; - return tdb_exists(pdb->tdb, print_key(jobid)); + ret = tdb_exists(pdb->tdb, print_key(jobid)); + release_print_db(pdb); + return ret; } /**************************************************************************** @@ -908,6 +1055,23 @@ char *print_job_fname(int snum, uint32 jobid) return pjob->filename; } + +/**************************************************************************** + Give the filename used for a jobid. + Only valid for the process doing the spooling and when the job + has not been spooled. +****************************************************************************/ + +NT_DEVICEMODE *print_job_devmode(int snum, uint32 jobid) +{ + struct printjob *pjob = print_job_find(snum, jobid); + + if ( !pjob ) + return NULL; + + return pjob->nt_devmode; +} + /**************************************************************************** Set the place in the queue for a job. ****************************************************************************/ @@ -1000,8 +1164,11 @@ static BOOL is_owner(struct current_user *user, int snum, uint32 jobid) BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode) { - BOOL owner; + BOOL owner, deleted; + char *fname; + *errcode = WERR_OK; + owner = is_owner(user, snum, jobid); /* Check access against security descriptor or whether the user @@ -1014,15 +1181,40 @@ BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR return False; } - if (!print_job_delete1(snum, jobid)) + /* + * get the spooled filename of the print job + * if this works, then the file has not been spooled + * to the underlying print system. Just delete the + * spool file & return. + */ + + if ( (fname = print_job_fname( snum, jobid )) != NULL ) + { + /* remove the spool file */ + DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname )); + if ( unlink( fname ) == -1 ) { + *errcode = map_werror_from_unix(errno); + return False; + } + + return True; + } + + if (!print_job_delete1(snum, jobid)) { + *errcode = WERR_ACCESS_DENIED; return False; + } /* force update the database and say the delete failed if the job still exists */ print_queue_update(snum); + + deleted = !print_job_exists(snum, jobid); + if ( !deleted ) + *errcode = WERR_ACCESS_DENIED; - return !print_job_exists(snum, jobid); + return deleted; } /**************************************************************************** @@ -1161,8 +1353,10 @@ static BOOL print_cache_expired(int snum) DEBUG(3, ("print cache expired for queue %s \ (last_qscan_time = %d, time now = %d, qcachetime = %d)\n", printername, (int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() )); + release_print_db(pdb); return True; } + release_print_db(pdb); return False; } @@ -1184,6 +1378,7 @@ static int get_queue_status(int snum, print_status_struct *status) key.dptr = keystr; key.dsize = strlen(keystr); data = tdb_fetch(pdb->tdb, key); + release_print_db(pdb); if (data.dptr) { if (data.dsize == sizeof(print_status_struct)) { memcpy(status, data.dptr, sizeof(print_status_struct)); @@ -1214,44 +1409,11 @@ int print_queue_length(int snum, print_status_struct *pstatus) return len; } -/**************************************************************************** - Determine the number of jobs in all queues. This is very expensive. Don't - call ! JRA. -****************************************************************************/ - -static int get_total_jobs(void) -{ - int total_jobs = 0; - int snum; - int services = lp_numservices(); - - for (snum = 0; snum < services; snum++) { - struct tdb_print_db *pdb; - int jobs; - - if (!lp_print_ok(snum)) - continue; - - pdb = get_print_db_byname(lp_const_servicename(snum)); - if (!pdb) - continue; - - /* make sure the database is up to date */ - if (print_cache_expired(snum)) - print_queue_update(snum); - - jobs = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs"); - if (jobs > 0) - total_jobs += jobs; - } - return total_jobs; -} - /*************************************************************************** Start spooling a job - return the jobid. ***************************************************************************/ -uint32 print_job_start(struct current_user *user, int snum, char *jobname) +uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode ) { uint32 jobid; char *path; @@ -1261,6 +1423,7 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname) int njobs = 0; const char *printername = lp_const_servicename(snum); struct tdb_print_db *pdb = get_print_db_byname(printername); + BOOL pdb_locked = False; errno = 0; @@ -1269,11 +1432,13 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname) if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) { DEBUG(3, ("print_job_start: job start denied by security descriptor\n")); + release_print_db(pdb); return (uint32)-1; } if (!print_time_access_check(snum)) { DEBUG(3, ("print_job_start: job start denied by time check\n")); + release_print_db(pdb); return (uint32)-1; } @@ -1285,6 +1450,7 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname) if (sys_fsusage(path, &dspace, &dsize) == 0 && dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) { DEBUG(3, ("print_job_start: disk space check failed.\n")); + release_print_db(pdb); errno = ENOSPC; return (uint32)-1; } @@ -1293,6 +1459,7 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname) /* for autoloaded printers, check that the printcap entry still exists */ if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum), NULL)) { DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) )); + release_print_db(pdb); errno = ENOENT; return (uint32)-1; } @@ -1301,41 +1468,19 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname) if (lp_maxprintjobs(snum) && (njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) { DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per queue (%d).\n", njobs, lp_maxprintjobs(snum) )); + release_print_db(pdb); errno = ENOSPC; return (uint32)-1; } - /* Insure the maximum print jobs in the system is not violated */ - if (lp_totalprintjobs() && get_total_jobs() > lp_totalprintjobs()) { - DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per system (%d).\n", - njobs, lp_totalprintjobs() )); - errno = ENOSPC; + /* Lock the database */ + if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob") == -1) { + DEBUG(0,("print_job_start: failed to lock printing database %s\n", printername )); + release_print_db(pdb); return (uint32)-1; } - /* create the database entry */ - ZERO_STRUCT(pjob); - pjob.pid = local_pid; - pjob.sysjob = -1; - pjob.fd = -1; - pjob.starttime = time(NULL); - pjob.status = LPQ_SPOOLING; - pjob.size = 0; - pjob.spooled = False; - pjob.smbjob = True; - - fstrcpy(pjob.jobname, jobname); - - if ((vuser = get_valid_user_struct(user->vuid)) != NULL) { - fstrcpy(pjob.user, vuser->user.smb_name); - } else { - fstrcpy(pjob.user, uidtoname(user->uid)); - } - - fstrcpy(pjob.queuename, lp_const_servicename(snum)); - - /* lock the database */ - tdb_lock_bystring(pdb->tdb, "INFO/nextjob"); + pdb_locked = True; next_jobid = tdb_fetch_int32(pdb->tdb, "INFO/nextjob"); if (next_jobid == -1) @@ -1345,19 +1490,61 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname) if (!print_job_exists(snum, jobid)) break; } - if (jobid == next_jobid || !pjob_store(snum, jobid, &pjob)) { - DEBUG(3, ("print_job_start: either jobid (%d)==next_jobid(%d) or pjob_store failed.\n", + + if (jobid == next_jobid) { + DEBUG(3, ("print_job_start: jobid (%d)==next_jobid(%d).\n", jobid, next_jobid )); jobid = -1; goto fail; } + /* Store a dummy placeholder. This must be quick as we have the lock. */ + { + TDB_DATA dum; + dum.dptr = NULL; + dum.dsize = 0; + if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) { + DEBUG(3, ("print_job_start: jobid (%d) failed to store placeholder.\n", + jobid )); + jobid = -1; + goto fail; + } + } + if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) { DEBUG(3, ("print_job_start: failed to store INFO/nextjob.\n")); jobid = -1; goto fail; } + /* We've finished with the INFO/nextjob lock. */ + tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); + pdb_locked = False; + + /* create the database entry */ + + ZERO_STRUCT(pjob); + + pjob.pid = local_pid; + pjob.sysjob = -1; + pjob.fd = -1; + pjob.starttime = time(NULL); + pjob.status = LPQ_SPOOLING; + pjob.size = 0; + pjob.spooled = False; + pjob.smbjob = True; + pjob.nt_devmode = nt_devmode; + + fstrcpy(pjob.jobname, jobname); + + if ((vuser = get_valid_user_struct(user->vuid)) != NULL) { + fstrcpy(pjob.user, vuser->user.smb_name); + } else { + fstrcpy(pjob.user, uidtoname(user->uid)); + } + + fstrcpy(pjob.queuename, lp_const_servicename(snum)); + /* we have a job entry - now create the spool file */ slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX", path, PRINT_SPOOL_PREFIX, (unsigned int)jobid); @@ -1378,7 +1565,7 @@ to open spool file %s.\n", pjob.filename)); pjob_store(snum, jobid, &pjob); - tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); + release_print_db(pdb); /* * If the printer is marked as postscript output a leading @@ -1397,7 +1584,9 @@ to open spool file %s.\n", pjob.filename)); if (jobid != -1) pjob_delete(snum, jobid); - tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); + if (pdb_locked) + tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); + release_print_db(pdb); DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) )); return -1; @@ -1503,10 +1692,16 @@ static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void * int i; uint32 jobid; - if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) + /* sanity checks */ + + if ( key.dsize != sizeof(jobid) ) return 0; + memcpy(&jobid, key.dptr, sizeof(jobid)); - memcpy(&pjob, data.dptr, sizeof(pjob)); + + if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 ) + return 0; + free_nt_devicemode( &pjob.nt_devmode ); /* maybe it isn't for this queue */ if (ts->snum != lp_servicenumber(pjob.queuename)) @@ -1545,10 +1740,17 @@ static int traverse_count_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, struct printjob pjob; uint32 jobid; - if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) + /* sanity checks */ + + if ( key.dsize != sizeof(jobid) ) return 0; + memcpy(&jobid, key.dptr, sizeof(jobid)); - memcpy(&pjob, data.dptr, sizeof(pjob)); + + if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 ) + return 0; + + free_nt_devicemode( &pjob.nt_devmode ); /* maybe it isn't for this queue - this cannot happen with the tdb/printer code. JRA */ if (ts->snum != lp_servicenumber(pjob.queuename)) @@ -1630,13 +1832,17 @@ int print_queue_status(int snum, tdb_traverse(pdb->tdb, traverse_count_fn_queue, (void *)&tsc); - if (tsc.count == 0) + if (tsc.count == 0) { + release_print_db(pdb); return 0; + } /* Allocate the queue size. */ if ((tstruct.queue = (print_queue_struct *) - malloc(sizeof(print_queue_struct)*tsc.count)) == NULL) + malloc(sizeof(print_queue_struct)*tsc.count)) == NULL) { + release_print_db(pdb); return 0; + } /* * Fill in the queue. @@ -1648,6 +1854,7 @@ int print_queue_status(int snum, tstruct.snum = snum; tdb_traverse(pdb->tdb, traverse_fn_queue, (void *)&tstruct); + release_print_db(pdb); /* Sort the queue by submission time otherwise they are displayed in hash order. */ diff --git a/source3/profile/profile.c b/source3/profile/profile.c index 595593c6f0d..689f67da997 100644 --- a/source3/profile/profile.c +++ b/source3/profile/profile.c @@ -21,10 +21,14 @@ #include "includes.h" +#ifdef WITH_PROFILE #define IPC_PERMS ((SHM_R | SHM_W) | (SHM_R>>3) | (SHM_R>>6)) +#endif /* WITH_PROFILE */ +#ifdef WITH_PROFILE static int shm_id; static BOOL read_only; +#endif struct profile_header *profile_h; struct profile_stats *profile_p; @@ -45,6 +49,7 @@ void profile_message(int msg_type, pid_t src, void *buf, size_t len) int level; memcpy(&level, buf, sizeof(int)); +#ifdef WITH_PROFILE switch (level) { case 0: /* turn off profiling */ do_profile_flag = False; @@ -66,6 +71,9 @@ void profile_message(int msg_type, pid_t src, void *buf, size_t len) DEBUG(1,("INFO: Profiling values cleared from pid %d\n", (int)src)); break; } +#else /* WITH_PROFILE */ + DEBUG(1,("INFO: Profiling support unavailable in this build.\n")); +#endif /* WITH_PROFILE */ } /**************************************************************************** @@ -87,6 +95,7 @@ void reqprofile_message(int msg_type, pid_t src, void *buf, size_t len) /******************************************************************* open the profiling shared memory area ******************************************************************/ +#ifdef WITH_PROFILE BOOL profile_setup(BOOL rdonly) { struct shmid_ds shm_ds; @@ -154,3 +163,4 @@ BOOL profile_setup(BOOL rdonly) message_register(MSG_REQ_PROFILELEVEL, reqprofile_message); return True; } +#endif /* WITH_PROFILE */ diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c index 45c1f240010..a9dfb52f011 100644 --- a/source3/registry/reg_frontend.c +++ b/source3/registry/reg_frontend.c @@ -37,321 +37,6 @@ REGISTRY_HOOK reg_hooks[] = { }; -/* - * Utility functions for REGSUBKEY_CTR - */ - -/*********************************************************************** - Init the talloc context held by a REGSUBKEY_CTR structure - **********************************************************************/ - -void regsubkey_ctr_init( REGSUBKEY_CTR *ctr ) -{ - if ( !ctr->ctx ) - ctr->ctx = talloc_init(); -} - -/*********************************************************************** - Add a new key to the array - **********************************************************************/ - -int regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, char *keyname ) -{ - uint32 len; - char **pp; - - if ( keyname ) - { - len = strlen( keyname ); - - /* allocate a space for the char* in the array */ - - if ( ctr->subkeys == 0 ) - ctr->subkeys = talloc( ctr->ctx, sizeof(char*) ); - else { - pp = talloc_realloc( ctr->ctx, ctr->subkeys, sizeof(char*)*(ctr->num_subkeys+1) ); - if ( pp ) - ctr->subkeys = pp; - } - - /* allocate the string and save it in the array */ - - ctr->subkeys[ctr->num_subkeys] = talloc( ctr->ctx, len+1 ); - strncpy( ctr->subkeys[ctr->num_subkeys], keyname, len+1 ); - ctr->num_subkeys++; - } - - return ctr->num_subkeys; -} - -/*********************************************************************** - How many keys does the container hold ? - **********************************************************************/ - -int regsubkey_ctr_numkeys( REGSUBKEY_CTR *ctr ) -{ - return ctr->num_subkeys; -} - -/*********************************************************************** - Retreive a specific key string - **********************************************************************/ - -char* regsubkey_ctr_specific_key( REGSUBKEY_CTR *ctr, uint32 key_index ) -{ - if ( ! (key_index < ctr->num_subkeys) ) - return NULL; - - return ctr->subkeys[key_index]; -} - -/*********************************************************************** - free memory held by a REGSUBKEY_CTR structure - **********************************************************************/ - -void regsubkey_ctr_destroy( REGSUBKEY_CTR *ctr ) -{ - if ( ctr ) { - talloc_destroy( ctr->ctx ); - ZERO_STRUCTP( ctr ); - } -} - - -/* - * Utility functions for REGVAL_CTR - */ - -/*********************************************************************** - Init the talloc context held by a REGSUBKEY_CTR structure - **********************************************************************/ - -void regval_ctr_init( REGVAL_CTR *ctr ) -{ - if ( !ctr->ctx ) - ctr->ctx = talloc_init(); -} - -/*********************************************************************** - How many keys does the container hold ? - **********************************************************************/ - -int regval_ctr_numvals( REGVAL_CTR *ctr ) -{ - return ctr->num_values; -} - -/*********************************************************************** - allocate memory for and duplicate a REGISTRY_VALUE. - This is malloc'd memory so the caller should free it when done - **********************************************************************/ - -REGISTRY_VALUE* dup_registry_value( REGISTRY_VALUE *val ) -{ - REGISTRY_VALUE *copy = NULL; - - if ( !val ) - return NULL; - - if ( !(copy = malloc( sizeof(REGISTRY_VALUE) )) ) { - DEBUG(0,("dup_registry_value: malloc() failed!\n")); - return NULL; - } - - /* copy all the non-pointer initial data */ - - memcpy( copy, val, sizeof(REGISTRY_VALUE) ); - if ( val->data_p ) - { - if ( !(copy->data_p = memdup( val->data_p, val->size )) ) { - DEBUG(0,("dup_registry_value: memdup() failed for [%d] bytes!\n", - val->size)); - SAFE_FREE( copy ); - } - } - - return copy; -} - -/********************************************************************** - free the memory allocated to a REGISTRY_VALUE - *********************************************************************/ - -void free_registry_value( REGISTRY_VALUE *val ) -{ - if ( !val ) - return; - - SAFE_FREE( val->data_p ); - SAFE_FREE( val ); - - return; -} - -/********************************************************************** - *********************************************************************/ - -uint8* regval_data_p( REGISTRY_VALUE *val ) -{ - return val->data_p; -} - -/********************************************************************** - *********************************************************************/ - -int regval_size( REGISTRY_VALUE *val ) -{ - return val->size; -} - -/********************************************************************** - *********************************************************************/ - -char* regval_name( REGISTRY_VALUE *val ) -{ - return val->valuename; -} - -/********************************************************************** - *********************************************************************/ - -uint32 regval_type( REGISTRY_VALUE *val ) -{ - return val->type; -} - -/*********************************************************************** - Retreive a pointer to a specific value. Caller shoud dup the structure - since this memory may go away with a regval_ctr_destroy() - **********************************************************************/ - -REGISTRY_VALUE* regval_ctr_specific_value( REGVAL_CTR *ctr, uint32 idx ) -{ - if ( !(idx < ctr->num_values) ) - return NULL; - - return ctr->values[idx]; -} - -/*********************************************************************** - Retrive the TALLOC_CTX associated with a REGISTRY_VALUE - **********************************************************************/ - -TALLOC_CTX* regval_ctr_getctx( REGVAL_CTR *val ) -{ - if ( !val ) - return NULL; - - return val->ctx; -} - -/*********************************************************************** - Add a new registry value to the array - **********************************************************************/ - -int regval_ctr_addvalue( REGVAL_CTR *ctr, char *name, uint16 type, - char *data_p, size_t size ) -{ - REGISTRY_VALUE **ppreg; - uint16 len; - - if ( name ) - { - len = strlen( name ); - - /* allocate a slot in the array of pointers */ - - if ( ctr->num_values == 0 ) - ctr->values = talloc( ctr->ctx, sizeof(REGISTRY_VALUE*) ); - else { - ppreg = talloc_realloc( ctr->ctx, ctr->values, sizeof(REGISTRY_VALUE*)*(ctr->num_values+1) ); - if ( ppreg ) - ctr->values = ppreg; - } - - /* allocate a new value and store the pointer in the arrya */ - - ctr->values[ctr->num_values] = talloc( ctr->ctx, sizeof(REGISTRY_VALUE) ); - - /* init the value */ - - fstrcpy( ctr->values[ctr->num_values]->valuename, name ); - ctr->values[ctr->num_values]->type = type; - ctr->values[ctr->num_values]->data_p = talloc_memdup( ctr->ctx, data_p, size ); - ctr->values[ctr->num_values]->size = size; - ctr->num_values++; - } - - return ctr->num_values; -} - -/*********************************************************************** - Delete a single value from the registry container. - No need to free memory since it is talloc'd. - **********************************************************************/ - -int regval_ctr_delvalue( REGVAL_CTR *ctr, char *name ) -{ - int i; - - /* search for the value */ - - for ( i=0; inum_values; i++ ) { - if ( strcmp( ctr->values[i]->valuename, name ) == 0) - break; - } - - /* just return if we don't find it */ - - if ( i == ctr->num_values ) - return ctr->num_values; - - /* just shift everything down one */ - - for ( /* use previous i */; i<(ctr->num_values-1); i++ ) - memcpy( ctr->values[i], ctr->values[i+1], sizeof(REGISTRY_VALUE) ); - - /* paranoia */ - - ZERO_STRUCTP( ctr->values[i] ); - - ctr->num_values--; - - return ctr->num_values; -} - -/*********************************************************************** - Delete a single value from the registry container. - No need to free memory since it is talloc'd. - **********************************************************************/ - -REGISTRY_VALUE* regval_ctr_getvalue( REGVAL_CTR *ctr, char *name ) -{ - int i; - - /* search for the value */ - - for ( i=0; inum_values; i++ ) { - if ( strcmp( ctr->values[i]->valuename, name ) == 0) - return ctr->values[i]; - - } - - return NULL; -} - -/*********************************************************************** - free memory held by a REGVAL_CTR structure - **********************************************************************/ - -void regval_ctr_destroy( REGVAL_CTR *ctr ) -{ - if ( ctr ) { - talloc_destroy( ctr->ctx ); - ZERO_STRUCTP( ctr ); - } -} - /*********************************************************************** Open the registry database and initialize the REGISTRY_HOOK cache ***********************************************************************/ diff --git a/source3/registry/reg_printing.c b/source3/registry/reg_printing.c index 8f53fe9ea5c..a58a91a0a89 100644 --- a/source3/registry/reg_printing.c +++ b/source3/registry/reg_printing.c @@ -240,6 +240,7 @@ static int print_subpath_values_environments( char *key, REGVAL_CTR *val ) int buffer_size = 0; int i, length; char *filename; + UNISTR2 data;; DEBUG(8,("print_subpath_values_environments: Enter key => [%s]\n", key ? key : "NULL")); @@ -287,15 +288,23 @@ static int print_subpath_values_environments( char *key, REGVAL_CTR *val ) info3 = driver_ctr.info_3; filename = dos_basename( info3->driverpath ); - regval_ctr_addvalue( val, "Driver", REG_SZ, filename, strlen(filename)+1 ); + init_unistr2( &data, filename, strlen(filename)+1 ); + regval_ctr_addvalue( val, "Driver", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + filename = dos_basename( info3->configfile ); - regval_ctr_addvalue( val, "Configuration File", REG_SZ, filename, strlen(filename)+1 ); + init_unistr2( &data, filename, strlen(filename)+1 ); + regval_ctr_addvalue( val, "Configuration File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + filename = dos_basename( info3->datafile ); - regval_ctr_addvalue( val, "Data File", REG_SZ, filename, strlen(filename)+1 ); + init_unistr2( &data, filename, strlen(filename)+1 ); + regval_ctr_addvalue( val, "Data File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + filename = dos_basename( info3->helpfile ); - regval_ctr_addvalue( val, "Help File", REG_SZ, filename, strlen(filename)+1 ); - - regval_ctr_addvalue( val, "Data Type", REG_SZ, info3->defaultdatatype, strlen(info3->defaultdatatype)+1 ); + init_unistr2( &data, filename, strlen(filename)+1 ); + regval_ctr_addvalue( val, "Help File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + + init_unistr2( &data, info3->defaultdatatype, strlen(info3->defaultdatatype)+1 ); + regval_ctr_addvalue( val, "Data Type", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); regval_ctr_addvalue( val, "Version", REG_DWORD, (char*)&info3->cversion, sizeof(info3->cversion) ); @@ -313,19 +322,20 @@ static int print_subpath_values_environments( char *key, REGVAL_CTR *val ) length = strlen(filename); - buffer2 = Realloc( buffer, buffer_size + length + 1 ); + buffer2 = Realloc( buffer, buffer_size + (length + 1)*sizeof(uint16) ); if ( !buffer2 ) break; buffer = buffer2; + + init_unistr2( &data, filename, length+1 ); + memcpy( buffer+buffer_size, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - memcpy( buffer+buffer_size, filename, length+1 ); - - buffer_size += length + 1; + buffer_size += (length + 1)*sizeof(uint16); } /* terminated by double NULL. Add the final one here */ - buffer2 = Realloc( buffer, buffer_size + 1 ); + buffer2 = Realloc( buffer, buffer_size + 2 ); if ( !buffer2 ) { SAFE_FREE( buffer ); buffer_size = 0; @@ -333,12 +343,14 @@ static int print_subpath_values_environments( char *key, REGVAL_CTR *val ) else { buffer = buffer2; buffer[buffer_size++] = '\0'; + buffer[buffer_size++] = '\0'; } } regval_ctr_addvalue( val, "Dependent Files", REG_MULTI_SZ, buffer, buffer_size ); free_a_printer_driver( driver_ctr, 3 ); + SAFE_FREE( key2 ); SAFE_FREE( buffer ); @@ -453,11 +465,12 @@ static int print_subpath_printers( char *key, REGSUBKEY_CTR *subkeys ) int n_services = lp_numservices(); int snum; fstring sname; + int i; int num_subkeys = 0; char *keystr, *key2 = NULL; char *base, *new_path; NT_PRINTER_INFO_LEVEL *printer = NULL; - + fstring *subkey_names = NULL; DEBUG(10,("print_subpath_printers: key=>[%s]\n", key ? key : "NULL" )); @@ -483,22 +496,23 @@ static int print_subpath_printers( char *key, REGSUBKEY_CTR *subkeys ) key2 = strdup( key ); keystr = key2; reg_split_path( keystr, &base, &new_path ); + + if ( !W_ERROR_IS_OK( get_a_printer(&printer, 2, base) ) ) + goto done; + + num_subkeys = get_printer_subkeys( &printer->info_2->data, new_path?new_path:"", &subkey_names ); + for ( i=0; iuntiltime, sizeof(info2->untiltime) ); regval_ctr_addvalue( val, "cjobs", REG_DWORD, (char*)&info2->cjobs, sizeof(info2->cjobs) ); regval_ctr_addvalue( val, "AveragePPM", REG_DWORD, (char*)&info2->averageppm, sizeof(info2->averageppm) ); - - regval_ctr_addvalue( val, "Name", REG_SZ, info2->printername, sizeof(info2->printername)+1 ); - regval_ctr_addvalue( val, "Location", REG_SZ, info2->location, sizeof(info2->location)+1 ); - regval_ctr_addvalue( val, "Comment", REG_SZ, info2->comment, sizeof(info2->comment)+1 ); - regval_ctr_addvalue( val, "Parameters", REG_SZ, info2->parameters, sizeof(info2->parameters)+1 ); - regval_ctr_addvalue( val, "Port", REG_SZ, info2->portname, sizeof(info2->portname)+1 ); - regval_ctr_addvalue( val, "Server", REG_SZ, info2->servername, sizeof(info2->servername)+1 ); - regval_ctr_addvalue( val, "Share", REG_SZ, info2->sharename, sizeof(info2->sharename)+1 ); - regval_ctr_addvalue( val, "Driver", REG_SZ, info2->drivername, sizeof(info2->drivername)+1 ); - regval_ctr_addvalue( val, "Separator File", REG_SZ, info2->sepfile, sizeof(info2->sepfile)+1 ); - regval_ctr_addvalue( val, "Print Processor", REG_SZ, "winprint", sizeof("winprint")+1 ); + + init_unistr2( &data, info2->printername, strlen(info2->printername)+1 ); + regval_ctr_addvalue( val, "Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + init_unistr2( &data, info2->location, strlen(info2->location)+1 ); + regval_ctr_addvalue( val, "Location", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + init_unistr2( &data, info2->comment, strlen(info2->comment)+1 ); + regval_ctr_addvalue( val, "Comment", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + init_unistr2( &data, info2->parameters, strlen(info2->parameters)+1 ); + regval_ctr_addvalue( val, "Parameters", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + init_unistr2( &data, info2->portname, strlen(info2->portname)+1 ); + regval_ctr_addvalue( val, "Port", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + init_unistr2( &data, info2->servername, strlen(info2->servername)+1 ); + regval_ctr_addvalue( val, "Server", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + init_unistr2( &data, info2->sharename, strlen(info2->sharename)+1 ); + regval_ctr_addvalue( val, "Share", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + init_unistr2( &data, info2->drivername, strlen(info2->drivername)+1 ); + regval_ctr_addvalue( val, "Driver", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + init_unistr2( &data, info2->sepfile, strlen(info2->sepfile)+1 ); + regval_ctr_addvalue( val, "Separator File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + init_unistr2( &data, "winprint", strlen("winprint")+1 ); + regval_ctr_addvalue( val, "Print Processor", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); /* use a prs_struct for converting the devmode and security @@ -607,43 +630,36 @@ static int print_subpath_values_printers( char *key, REGVAL_CTR *val ) prs_mem_free( &prs ); - free_a_printer( &printer, 2 ); num_values = regval_ctr_numvals( val ); + goto done; } - - - keystr = new_path; - reg_split_path( keystr, &base, &new_path ); - - /* here should be no more path components here */ - - if ( new_path || strcmp(base, SPOOL_PRINTERDATA_KEY) ) - goto done; - /* now enumerate the PrinterDriverData key */ + /* now enumerate the key */ + if ( !W_ERROR_IS_OK( get_a_printer(&printer, 2, printername) ) ) goto done; - - info2 = printer->info_2; - /* iterate over all printer data and fill the regval container */ -#if 0 /* JERRY */ - for ( i=0; get_specific_param_by_index(*printer, 2, i, valuename, &data, &type, &data_len); i++ ) - { - regval_ctr_addvalue( val, valuename, type, data, data_len ); + p_data = &printer->info_2->data; + if ( (key_index = lookup_printerkey( p_data, new_path )) == -1 ) { + DEBUG(10,("print_subpath_values_printer: Unknown keyname [%s]\n", new_path)); + goto done; } -#endif - - free_a_printer( &printer, 2 ); - - num_values = regval_ctr_numvals( val ); + num_values = regval_ctr_numvals( &p_data->keys[key_index].values ); + + for ( i=0; ikeys[key_index].values, i) ); + + done: + if ( printer ) + free_a_printer( &printer, 2 ); + SAFE_FREE( key2 ); return num_values; diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index acc91355428..eaee3c26e7c 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -152,11 +152,106 @@ password ?).\n", cli->desthost )); return result; } +/**************************************************************************** +LSA Authenticate 3 + +Send the client credential, receive back a server credential. +Ensure that the server credential returned matches the session key +encrypt of the server challenge originally received. JRA. +****************************************************************************/ + +NTSTATUS cli_net_auth3(struct cli_state *cli, + uint16 sec_chan, + uint32 *neg_flags, DOM_CHAL *srv_chal) +{ + prs_struct qbuf, rbuf; + NET_Q_AUTH_3 q; + NET_R_AUTH_3 r; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + extern pstring global_myname; + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + + /* create and send a MSRPC command with api NET_AUTH2 */ + + DEBUG(4,("cli_net_auth3: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n", + cli->srv_name_slash, cli->mach_acct, sec_chan, global_myname, + credstr(cli->clnt_cred.challenge.data), *neg_flags)); + + /* store the parameters */ + init_q_auth_3(&q, cli->srv_name_slash, cli->mach_acct, + sec_chan, global_myname, &cli->clnt_cred.challenge, + *neg_flags); + + /* turn parameters into data stream */ + + if (!net_io_q_auth_3("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, NET_AUTH3, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!net_io_r_auth_3("", &r, &rbuf, 0)) { + goto done; + } + + result = r.status; + *neg_flags = r.srv_flgs.neg_flags; + + if (NT_STATUS_IS_OK(result)) { + UTIME zerotime; + + /* + * Check the returned value using the initial + * server received challenge. + */ + + zerotime.time = 0; + if (cred_assert( &r.srv_chal, cli->sess_key, srv_chal, + zerotime) == 0) { + + /* + * Server replied with bad credential. Fail. + */ + DEBUG(0,("cli_net_auth3: server %s replied with bad credential (bad machine \ +password ?).\n", cli->desthost )); + result = NT_STATUS_ACCESS_DENIED; + goto done; + } + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Return the secure channel type depending on the server role. */ + +uint16 get_sec_chan(void) +{ + uint16 sec_chan = SEC_CHAN_WKSTA; + + switch (lp_server_role()) { + case ROLE_DOMAIN_PDC: + sec_chan = SEC_CHAN_DOMAIN; + break; + case ROLE_DOMAIN_BDC: + sec_chan = SEC_CHAN_BDC; + break; + } + + return sec_chan; +} + /* Initialize domain session credentials */ NTSTATUS cli_nt_setup_creds(struct cli_state *cli, uint16 sec_chan, - const unsigned char mach_pwd[16]) + const unsigned char mach_pwd[16], uint32 *neg_flags, int level) { DOM_CHAL clnt_chal; DOM_CHAL srv_chal; @@ -182,24 +277,30 @@ NTSTATUS cli_nt_setup_creds(struct cli_state *cli, cli->sess_key); memset((char *)cli->sess_key+8, '\0', 8); - /******************* Authenticate 2 ********************/ + /******************* Authenticate 2/3 ********************/ - /* calculate auth-2 credentials */ + /* calculate auth-2/3 credentials */ zerotime.time = 0; - cred_create(cli->sess_key, &clnt_chal, zerotime, - &cli->clnt_cred.challenge); + cred_create(cli->sess_key, &clnt_chal, zerotime, &cli->clnt_cred.challenge); /* - * Send client auth-2 challenge. - * Receive an auth-2 challenge response and check it. + * Send client auth-2/3 challenge. + * Receive an auth-2/3 challenge response and check it. */ - - result = cli_net_auth2(cli, sec_chan, 0x000001ff, &srv_chal); + switch (level) { + case 2: + result = cli_net_auth2(cli, sec_chan, *neg_flags, &srv_chal); + break; + case 3: + result = cli_net_auth3(cli, sec_chan, neg_flags, &srv_chal); + break; + default: + DEBUG(1,("cli_nt_setup_creds: unsupported auth level: %d\n", level)); + break; + } - if (!NT_STATUS_IS_OK(result)) { - DEBUG(1,("cli_nt_setup_creds: auth2 challenge failed %s\n", - nt_errstr(result))); - } + if (!NT_STATUS_IS_OK(result)) + DEBUG(1,("cli_nt_setup_creds: auth%d challenge failed %s\n", level, nt_errstr(result))); return result; } @@ -257,24 +358,23 @@ file. They should be combined at some stage. )-: static void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred) { - /* - * Create the new client credentials. - */ - - cli->clnt_cred.timestamp.time = time(NULL); - - memcpy(new_clnt_cred, &cli->clnt_cred, sizeof(*new_clnt_cred)); - - /* Calculate the new credentials. */ - cred_create(cli->sess_key, &(cli->clnt_cred.challenge), - new_clnt_cred->timestamp, &(new_clnt_cred->challenge)); + /* + * Create the new client credentials. + */ + + cli->clnt_cred.timestamp.time = time(NULL); + + memcpy(new_clnt_cred, &cli->clnt_cred, sizeof(*new_clnt_cred)); + /* Calculate the new credentials. */ + cred_create(cli->sess_key, &(cli->clnt_cred.challenge), + new_clnt_cred->timestamp, &(new_clnt_cred->challenge)); } /* Sam synchronisation */ NTSTATUS cli_netlogon_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, DOM_CRED *ret_creds, - uint32 database_id, uint32 *num_deltas, + uint32 database_id, uint32 next_rid, uint32 *num_deltas, SAM_DELTA_HDR **hdr_deltas, SAM_DELTA_CTR **deltas) { @@ -297,7 +397,7 @@ NTSTATUS cli_netlogon_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, DOM_C gen_next_creds(cli, &clnt_creds); init_net_q_sam_sync(&q, cli->srv_name_slash, cli->clnt_name_slash + 2, - &clnt_creds, ret_creds, database_id); + &clnt_creds, ret_creds, database_id, next_rid); /* Marshall data and send request */ diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index eae6be51282..0416ed3b9ba 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -354,7 +354,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr if (!cli_api_pipe(cli, "\\PIPE\\", setup, 2, 0, /* Setup, length, max */ NULL, 0, 0, /* Params, length, max */ - pdata, data_len, data_len, /* data, length, max */ + pdata, data_len, 1024, /* data, length, max */ &rparam, &rparam_len, /* return params, len */ &prdata, &rdata_len)) /* return data, len */ { diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index 18e17758d6d..ca24d95e336 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -393,7 +393,7 @@ WERROR cli_spoolss_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx, WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx, uint32 offered, uint32 *needed, - uint32 flags, uint32 level, + char *name, uint32 flags, uint32 level, uint32 *num_printers, PRINTER_INFO_CTR *ctr) { prs_struct qbuf, rbuf; @@ -401,14 +401,10 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx, SPOOL_R_ENUMPRINTERS r; NEW_BUFFER buffer; WERROR result = W_ERROR(ERRgeneral); - fstring server; ZERO_STRUCT(q); ZERO_STRUCT(r); - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); - /* Initialise input parameters */ init_buffer(&buffer, offered, mem_ctx); @@ -416,7 +412,7 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx, prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - make_spoolss_q_enumprinters(&q, flags, server, level, &buffer, + make_spoolss_q_enumprinters(&q, flags, name, level, &buffer, offered); /* Marshall data and send request */ @@ -665,7 +661,8 @@ WERROR cli_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - make_spoolss_q_setprinter(mem_ctx, &q, pol, level, ctr, command); + if (!make_spoolss_q_setprinter(mem_ctx, &q, pol, level, ctr, command)) + goto done; /* Marshall data and send request */ @@ -771,6 +768,9 @@ WERROR cli_spoolss_getprinterdriver(struct cli_state *cli, case 3: decode_printer_driver_3(mem_ctx, r.buffer, 1, &ctr->info3); break; + default: + DEBUG(10, ("cli_spoolss_getprinterdriver: unknown info level %d", level)); + return WERR_UNKNOWN_LEVEL; } done: @@ -852,6 +852,10 @@ WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli, case 3: decode_printer_driver_3(mem_ctx, r.buffer, r.returned, &ctr->info3); break; + default: + DEBUG(10, ("cli_spoolss_enumprinterdrivers: unknown info level %d\n", + level)); + return WERR_UNKNOWN_LEVEL; } } @@ -1332,8 +1336,16 @@ WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx, if (needed) *needed = r.needed; - if (W_ERROR_IS_OK(result)) - smb_io_form_1("", r.buffer, form, 0); + if (W_ERROR_IS_OK(result)) { + switch(level) { + case 1: + smb_io_form_1("", r.buffer, form, 0); + break; + default: + DEBUG(10, ("cli_spoolss_getform: unknown info level %d", level)); + return WERR_UNKNOWN_LEVEL; + } + } done: prs_mem_free(&qbuf); @@ -1556,11 +1568,11 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx, switch(level) { case 1: decode_jobs_1(mem_ctx, r.buffer, r.returned, - ctr->job.job_info_1); + &ctr->job.job_info_1); break; case 2: decode_jobs_2(mem_ctx, r.buffer, r.returned, - ctr->job.job_info_2); + &ctr->job.job_info_2); break; default: DEBUG(3, ("unsupported info level %d", level)); @@ -1669,10 +1681,10 @@ WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx, switch(level) { case 1: - decode_jobs_1(mem_ctx, r.buffer, 1, ctr->job.job_info_1); + decode_jobs_1(mem_ctx, r.buffer, 1, &ctr->job.job_info_1); break; case 2: - decode_jobs_2(mem_ctx, r.buffer, 1, ctr->job.job_info_2); + decode_jobs_2(mem_ctx, r.buffer, 1, &ctr->job.job_info_2); break; default: DEBUG(3, ("unsupported info level %d", level)); @@ -1878,8 +1890,7 @@ WERROR cli_spoolss_enddocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, uint32 offered, uint32 *needed, POLICY_HND *hnd, char *valuename, - uint32 *data_type, char **data, - uint32 *data_size) + REGISTRY_VALUE *value) { prs_struct qbuf, rbuf; SPOOL_Q_GETPRINTERDATA q; @@ -1919,16 +1930,63 @@ WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if (data_type) - *data_type = r.type; + value->data_p = talloc_memdup(mem_ctx, r.data, r.needed); + value->type = r.type; + value->size = r.size; - if (data) { - *data = (char *)talloc(mem_ctx, r.needed); - memcpy(*data, r.data, r.needed); - } + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +WERROR cli_spoolss_getprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 offered, uint32 *needed, + POLICY_HND *hnd, char *keyname, + char *valuename, REGISTRY_VALUE *value) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_GETPRINTERDATAEX q; + SPOOL_R_GETPRINTERDATAEX r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_getprinterdataex(&q, hnd, keyname, valuename, offered); + + /* Marshall data and send request */ + + if (!spoolss_io_q_getprinterdataex("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTERDATAEX, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_getprinterdataex("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (needed) + *needed = r.needed; - if (data_size) - *data_size = r.needed; + if (!W_ERROR_IS_OK(r.status)) + goto done; + + /* Return output parameters */ + + value->data_p = talloc_memdup(mem_ctx, r.data, r.needed); + value->type = r.type; + value->size = r.needed; done: prs_mem_free(&qbuf); @@ -1940,9 +1998,7 @@ WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Set printer data */ WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, char *value, - uint32 data_type, char *data, - uint32 data_size) + POLICY_HND *hnd, REGISTRY_VALUE *value) { prs_struct qbuf, rbuf; SPOOL_Q_SETPRINTERDATA q; @@ -1959,7 +2015,8 @@ WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Initialise input parameters */ - make_spoolss_q_setprinterdata(&q, hnd, value, data, data_size); + make_spoolss_q_setprinterdata( + &q, hnd, value->valuename, value->type, value->data_p, value->size); /* Marshall data and send request */ @@ -1984,14 +2041,59 @@ WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +WERROR cli_spoolss_setprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd, char *keyname, + REGISTRY_VALUE *value) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_SETPRINTERDATAEX q; + SPOOL_R_SETPRINTERDATAEX r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_setprinterdataex( + &q, hnd, keyname, value->valuename, value->type, value->data_p, + value->size); + + /* Marshall data and send request */ + + if (!spoolss_io_q_setprinterdataex("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTERDATAEX, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_setprinterdataex("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(r.status)) + goto done; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /* Enum printer data */ WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, uint32 ndx, uint32 value_offered, uint32 data_offered, uint32 *value_needed, uint32 *data_needed, - char **value, uint32 *data_type, char **data, - uint32 *data_size) + REGISTRY_VALUE *value) { prs_struct qbuf, rbuf; SPOOL_Q_ENUMPRINTERDATA q; @@ -2027,30 +2129,83 @@ WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, goto done; /* Return data */ - + if (value_needed) *value_needed = r.realvaluesize; if (data_needed) *data_needed = r.realdatasize; - if (data_type) - *data_type = r.type; - if (value) { - fstring the_value; - - rpcstr_pull(the_value, r.value, sizeof(the_value), -1, + rpcstr_pull(value->valuename, r.value, sizeof(value->valuename), -1, STR_TERMINATE); - - *value = talloc_strdup(mem_ctx, the_value); + value->data_p = talloc_memdup(mem_ctx, r.data, r.realdatasize); + value->type = r.type; + value->size = r.realdatasize; } - if (data) - *data = talloc_memdup(mem_ctx, r.data, r.realdatasize); + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +WERROR cli_spoolss_enumprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 offered, uint32 *needed, + POLICY_HND *hnd, char *keyname, + REGVAL_CTR *ctr) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_ENUMPRINTERDATAEX q; + SPOOL_R_ENUMPRINTERDATAEX r; + WERROR result = W_ERROR(ERRgeneral); + int i; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ - if (data_size) - *data_size = r.realdatasize; + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_enumprinterdataex(&q, hnd, keyname, offered); + + /* Marshall data and send request */ + + if (!spoolss_io_q_enumprinterdataex("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERDATAEX, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_enumprinterdataex("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (needed) + *needed = r.needed; + + if (!W_ERROR_IS_OK(r.status)) + goto done; + + /* Return data */ + + ZERO_STRUCTP(ctr); + regval_ctr_init(ctr); + + for (i = 0; i < r.returned; i++) { + PRINTER_ENUM_VALUES *v = &r.ctr.values[i]; + fstring name; + + rpcstr_pull(name, v->valuename.buffer, sizeof(name), -1, + STR_TERMINATE); + regval_ctr_addvalue(ctr, name, v->type, v->data, v->data_len); + } done: prs_mem_free(&qbuf); @@ -2153,4 +2308,48 @@ WERROR cli_spoolss_deleteprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +WERROR cli_spoolss_deleteprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd, char *keyname, + char *valuename) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_DELETEPRINTERDATAEX q; + SPOOL_R_DELETEPRINTERDATAEX r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_deleteprinterdataex(&q, hnd, keyname, valuename); + + /* Marshall data and send request */ + + if (!spoolss_io_q_deleteprinterdataex("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_DELETEPRINTERDATAEX, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_deleteprinterdataex("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(r.status)) + goto done; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /** @} **/ diff --git a/source3/rpc_client/cli_spoolss_notify.c b/source3/rpc_client/cli_spoolss_notify.c index f03046558ee..d07ace8e0cd 100644 --- a/source3/rpc_client/cli_spoolss_notify.c +++ b/source3/rpc_client/cli_spoolss_notify.c @@ -222,6 +222,9 @@ done: return result; } +/********************************************************************* + *********************************************************************/ + WERROR cli_spoolss_rffpcnex(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint32 flags, uint32 options, char *localmachine, uint32 printerlocal, diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c index 01d76981736..3dd9c3bc2a3 100644 --- a/source3/rpc_parse/parse_misc.c +++ b/source3/rpc_parse/parse_misc.c @@ -1255,9 +1255,6 @@ BOOL smb_io_chal(char *desc, DOM_CHAL *chal, prs_struct *ps, int depth) prs_debug(ps, depth, desc, "smb_io_chal"); depth++; - - if(!prs_align(ps)) - return False; if(!prs_uint8s (False, "data", ps, depth, chal->data, 8)) return False; diff --git a/source3/rpc_parse/parse_net.c b/source3/rpc_parse/parse_net.c index da49a6531d0..e0f710b2d75 100644 --- a/source3/rpc_parse/parse_net.c +++ b/source3/rpc_parse/parse_net.c @@ -4,7 +4,8 @@ * Copyright (C) Andrew Tridgell 1992-1997, * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, * Copyright (C) Paul Ashton 1997. - * + * Copyright (C) Jean François Micouleau 2002. + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -552,8 +553,6 @@ void init_q_req_chal(NET_Q_REQ_CHAL *q_c, BOOL net_io_q_req_chal(char *desc, NET_Q_REQ_CHAL *q_c, prs_struct *ps, int depth) { - int old_align; - if (q_c == NULL) return False; @@ -571,15 +570,8 @@ BOOL net_io_q_req_chal(char *desc, NET_Q_REQ_CHAL *q_c, prs_struct *ps, int dep if(!smb_io_unistr2("", &q_c->uni_logon_clnt, True, ps, depth)) /* logon client unicode string */ return False; - old_align = ps->align; - ps->align = 0; - /* client challenge is _not_ aligned after the unicode strings */ - if(!smb_io_chal("", &q_c->clnt_chal, ps, depth)) { - /* client challenge */ - ps->align = old_align; + if(!smb_io_chal("", &q_c->clnt_chal, ps, depth)) return False; - } - ps->align = old_align; return True; } @@ -615,7 +607,6 @@ BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL *r_c, prs_struct *ps, int dept BOOL net_io_q_auth(char *desc, NET_Q_AUTH *q_a, prs_struct *ps, int depth) { - int old_align; if (q_a == NULL) return False; @@ -627,15 +618,8 @@ BOOL net_io_q_auth(char *desc, NET_Q_AUTH *q_a, prs_struct *ps, int depth) if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */ return False; - /* client challenge is _not_ aligned */ - old_align = ps->align; - ps->align = 0; - if(!smb_io_chal("", &q_a->clnt_chal, ps, depth)) { - /* client-calculated credentials */ - ps->align = old_align; + if(!smb_io_chal("", &q_a->clnt_chal, ps, depth)) return False; - } - ps->align = old_align; return True; } @@ -687,7 +671,6 @@ void init_q_auth_2(NET_Q_AUTH_2 *q_a, BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth) { - int old_align; if (q_a == NULL) return False; @@ -699,15 +682,8 @@ BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth) if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */ return False; - /* client challenge is _not_ aligned */ - old_align = ps->align; - ps->align = 0; - if(!smb_io_chal("", &q_a->clnt_chal, ps, depth)) { - /* client-calculated credentials */ - ps->align = old_align; + if(!smb_io_chal("", &q_a->clnt_chal, ps, depth)) return False; - } - ps->align = old_align; if(!net_io_neg_flags("", &q_a->clnt_flgs, ps, depth)) return False; @@ -740,6 +716,76 @@ BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth) return True; } +/******************************************************************* + Inits a NET_Q_AUTH_3 struct. +********************************************************************/ + +void init_q_auth_3(NET_Q_AUTH_3 *q_a, + const char *logon_srv, const char *acct_name, uint16 sec_chan, const char *comp_name, + DOM_CHAL *clnt_chal, uint32 clnt_flgs) +{ + DEBUG(5,("init_q_auth_3: %d\n", __LINE__)); + + init_log_info(&q_a->clnt_id, logon_srv, acct_name, sec_chan, comp_name); + memcpy(q_a->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data)); + q_a->clnt_flgs.neg_flags = clnt_flgs; + + DEBUG(5,("init_q_auth_3: %d\n", __LINE__)); +} + +/******************************************************************* + Reads or writes a structure. +********************************************************************/ + +BOOL net_io_q_auth_3(char *desc, NET_Q_AUTH_3 *q_a, prs_struct *ps, int depth) +{ + if (q_a == NULL) + return False; + + prs_debug(ps, depth, desc, "net_io_q_auth_3"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */ + return False; + if(!smb_io_chal("", &q_a->clnt_chal, ps, depth)) + return False; + if(!net_io_neg_flags("", &q_a->clnt_flgs, ps, depth)) + return False; + + return True; +} + +/******************************************************************* + Reads or writes a structure. +********************************************************************/ + +BOOL net_io_r_auth_3(char *desc, NET_R_AUTH_3 *r_a, prs_struct *ps, int depth) +{ + if (r_a == NULL) + return False; + + prs_debug(ps, depth, desc, "net_io_r_auth_3"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!smb_io_chal("srv_chal", &r_a->srv_chal, ps, depth)) /* server challenge */ + return False; + if(!net_io_neg_flags("srv_flgs", &r_a->srv_flgs, ps, depth)) + return False; + if (!prs_uint32("unknown", ps, depth, &r_a->unknown)) + return False; + + if(!prs_ntstatus("status", ps, depth, &r_a->status)) + return False; + + return True; +} + /******************************************************************* Inits a NET_Q_SRV_PWSET. @@ -1611,7 +1657,8 @@ makes a NET_Q_SAM_SYNC structure. ********************************************************************/ BOOL init_net_q_sam_sync(NET_Q_SAM_SYNC * q_s, const char *srv_name, const char *cli_name, DOM_CRED *cli_creds, - DOM_CRED *ret_creds, uint32 database_id) + DOM_CRED *ret_creds, uint32 database_id, + uint32 next_rid) { DEBUG(5, ("init_q_sam_sync\n")); @@ -1628,7 +1675,7 @@ BOOL init_net_q_sam_sync(NET_Q_SAM_SYNC * q_s, const char *srv_name, q_s->database_id = database_id; q_s->restart_state = 0; - q_s->sync_context = 0; + q_s->sync_context = next_rid; q_s->max_size = 0xffff; return True; @@ -1699,7 +1746,7 @@ static BOOL net_io_sam_delta_hdr(char *desc, SAM_DELTA_HDR * delta, /******************************************************************* reads or writes a structure. ********************************************************************/ -static BOOL net_io_sam_delta_stamp(char *desc, SAM_DELTA_STAMP *info, +static BOOL net_io_sam_delta_mod_count(char *desc, SAM_DELTA_MOD_COUNT *info, prs_struct *ps, int depth) { prs_debug(ps, depth, desc, "net_io_sam_delta_stamp"); @@ -2306,83 +2353,74 @@ static BOOL net_io_sam_alias_mem_info(char *desc, SAM_ALIAS_MEM_INFO * info, /******************************************************************* reads or writes a structure. ********************************************************************/ -static BOOL net_io_sam_dom_info(char *desc, SAM_DELTA_DOM *info, +static BOOL net_io_sam_policy_info(char *desc, SAM_DELTA_POLICY *info, prs_struct *ps, int depth) { int i; - - prs_debug(ps, depth, desc, "net_io_sam_dom_info"); + prs_debug(ps, depth, desc, "net_io_sam_policy_info"); depth++; if(!prs_align(ps)) return False; - if (!prs_uint32("unknown1", ps, depth, &info->unknown1)) - return False; - if (!prs_uint32("unknown2", ps, depth, &info->unknown2)) + if (!prs_uint32("max_log_size", ps, depth, &info->max_log_size)) return False; - if (!prs_uint32("unknown3", ps, depth, &info->unknown3)) + if (!prs_uint64("audit_retention_period", ps, depth, + &info->audit_retention_period)) return False; - if (!prs_uint32("unknown4", ps, depth, &info->unknown4)) + if (!prs_uint32("auditing_mode", ps, depth, &info->auditing_mode)) return False; - if (!prs_uint32("count1", ps, depth, &info->count1)) + if (!prs_uint32("num_events", ps, depth, &info->num_events)) return False; - if (!prs_uint32("ptr1", ps, depth, &info->ptr1)) + if (!prs_uint32("ptr_events", ps, depth, &info->ptr_events)) return False; - if (!prs_uint16("count2", ps, depth, &info->count2)) - return False; - if (!prs_uint16("count3", ps, depth, &info->count3)) - return False; + if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth)) + return False; - if (!prs_uint32("ptr2", ps, depth, &info->ptr2)) - return False; - if (!prs_uint32("ptr3", ps, depth, &info->ptr3)) + if (!prs_uint32("sid_ptr", ps, depth, &info->sid_ptr)) return False; - if (!prs_uint32("unknown4b", ps, depth, &info->unknown4b)) + if (!prs_uint32("paged_pool_limit", ps, depth, &info->paged_pool_limit)) return False; - if (!prs_uint32("unknown5", ps, depth, &info->unknown5)) + if (!prs_uint32("non_paged_pool_limit", ps, depth, + &info->non_paged_pool_limit)) return False; - if (!prs_uint32("unknown6", ps, depth, &info->unknown6)) + if (!prs_uint32("min_workset_size", ps, depth, &info->min_workset_size)) return False; - if (!prs_uint32("unknown7", ps, depth, &info->unknown7)) + if (!prs_uint32("max_workset_size", ps, depth, &info->max_workset_size)) return False; - if (!prs_uint32("unknown8", ps, depth, &info->unknown8)) + if (!prs_uint32("page_file_limit", ps, depth, &info->page_file_limit)) return False; - if (!prs_uint32("unknown9", ps, depth, &info->unknown9)) + if (!prs_uint64("time_limit", ps, depth, &info->time_limit)) return False; - if (!prs_uint32("unknown10", ps, depth, &info->unknown10)) + if (!smb_io_time("modify_time", &info->modify_time, ps, depth)) return False; - if (!prs_uint32("unknown11", ps, depth, &info->unknown11)) + if (!smb_io_time("create_time", &info->create_time, ps, depth)) return False; - if (!prs_uint32("unknown12", ps, depth, &info->unknown12)) + if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth)) return False; - if (!prs_uint32("unknown13", ps, depth, &info->unknown13)) - return False; - if (!prs_uint32("unknown14", ps, depth, &info->unknown14)) - return False; - if (!prs_uint32("unknown15", ps, depth, &info->unknown15)) - return False; - if (!prs_uint32("unknown16", ps, depth, &info->unknown16)) - return False; - if (!prs_uint32("unknown17", ps, depth, &info->unknown17)) - return False; + for (i=0; i<4; i++) { + UNIHDR dummy; + if (!smb_io_unihdr("dummy", &dummy, ps, depth)) + return False; + } - for (i=0; icount2; i++) - if (!prs_uint32("unknown18", ps, depth, &info->unknown18)) - return False; + for (i=0; i<4; i++) { + uint32 reserved; + if (!prs_uint32("reserved", ps, depth, &reserved)) + return False; + } - if (!prs_uint32("unknown19", ps, depth, &info->unknown19)) + if (!prs_uint32("num_event_audit_options", ps, depth, + &info->num_event_audit_options)) return False; - for (i=0; icount1; i++) - if (!prs_uint32("unknown20", ps, depth, &info->unknown20)) - return False; - - if (!prs_uint32("ptr4", ps, depth, &info->ptr4)) - return False; + for (i=0; inum_event_audit_options; i++) + if (!prs_uint32("event_audit_option", ps, depth, + &info->event_audit_option)) + return False; if (!smb_io_unistr2("domain_name", &info->domain_name, True, ps, depth)) return False; @@ -2390,18 +2428,23 @@ static BOOL net_io_sam_dom_info(char *desc, SAM_DELTA_DOM *info, if(!smb_io_dom_sid2("domain_sid", &info->domain_sid, ps, depth)) return False; + if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc, + info->hdr_sec_desc.buffer, ps, depth)) + + return False; + return True; } /******************************************************************* reads or writes a structure. ********************************************************************/ -static BOOL net_io_sam_unk0e_info(char *desc, SAM_DELTA_UNK0E *info, +static BOOL net_io_sam_trustdoms_info(char *desc, SAM_DELTA_TRUSTDOMS *info, prs_struct *ps, int depth) { int i; - prs_debug(ps, depth, desc, "net_io_sam_unk0e_info"); + prs_debug(ps, depth, desc, "net_io_sam_trustdoms_info"); depth++; if(!prs_align(ps)) @@ -2444,12 +2487,12 @@ static BOOL net_io_sam_unk0e_info(char *desc, SAM_DELTA_UNK0E *info, /******************************************************************* reads or writes a structure. ********************************************************************/ -static BOOL net_io_sam_unk12_info(char *desc, SAM_DELTA_UNK12 *info, - prs_struct *ps, int depth) +static BOOL net_io_sam_secret_info(char *desc, SAM_DELTA_SECRET *info, + prs_struct *ps, int depth) { int i; - prs_debug(ps, depth, desc, "net_io_sam_unk12_info"); + prs_debug(ps, depth, desc, "net_io_sam_secret_info"); depth++; if(!prs_align(ps)) @@ -2542,52 +2585,48 @@ static BOOL net_io_sam_privs_info(char *desc, SAM_DELTA_PRIVS *info, if(!prs_align(ps)) return False; - if(!prs_uint32("buf_size", ps, depth, &info->buf_size)) - return False; - - if(!sec_io_desc("sec_desc", &info->sec_desc, ps, depth)) - return False; - if(!smb_io_dom_sid2("sid", &info->sid, ps, depth)) return False; if(!prs_uint32("priv_count", ps, depth, &info->priv_count)) return False; - if(!prs_uint32("reserved1", ps, depth, &info->reserved1)) + if(!prs_uint32("priv_control", ps, depth, &info->priv_control)) return False; - if(!prs_uint32("ptr1", ps, depth, &info->ptr1)) + if(!prs_uint32("priv_attr_ptr", ps, depth, &info->priv_attr_ptr)) return False; - if(!prs_uint32("ptr2", ps, depth, &info->ptr2)) + if(!prs_uint32("priv_name_ptr", ps, depth, &info->priv_name_ptr)) return False; - if(!prs_uint32("unknown1", ps, depth, &info->unknown1)) + if (!prs_uint32("paged_pool_limit", ps, depth, &info->paged_pool_limit)) return False; - if(!prs_uint32("unknown2", ps, depth, &info->unknown2)) - return False; - if(!prs_uint32("unknown3", ps, depth, &info->unknown3)) + if (!prs_uint32("non_paged_pool_limit", ps, depth, + &info->non_paged_pool_limit)) return False; - if(!prs_uint32("unknown4", ps, depth, &info->unknown4)) + if (!prs_uint32("min_workset_size", ps, depth, &info->min_workset_size)) return False; - if(!prs_uint32("unknown5", ps, depth, &info->unknown5)) + if (!prs_uint32("max_workset_size", ps, depth, &info->max_workset_size)) return False; - if(!prs_uint32("unknown6", ps, depth, &info->unknown6)) + if (!prs_uint32("page_file_limit", ps, depth, &info->page_file_limit)) return False; - if(!prs_uint32("unknown7", ps, depth, &info->unknown7)) + if (!prs_uint64("time_limit", ps, depth, &info->time_limit)) return False; - if(!prs_uint32("unknown8", ps, depth, &info->unknown8)) + if (!prs_uint32("system_flags", ps, depth, &info->system_flags)) return False; - if(!prs_uint32("unknown9", ps, depth, &info->unknown9)) + if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth)) return False; - if(!prs_uint32("buf_size2", ps, depth, &info->buf_size2)) - return False; - if(!prs_uint32("ptr3", ps, depth, &info->ptr3)) - return False; + for (i=0; i<4; i++) { + UNIHDR dummy; + if (!smb_io_unihdr("dummy", &dummy, ps, depth)) + return False; + } - for (i=0; i<12; i++) - if(!prs_uint32("unknown10", ps, depth, &info->unknown10)) - return False; + for (i=0; i<4; i++) { + uint32 reserved; + if (!prs_uint32("reserved", ps, depth, &reserved)) + return False; + } if(!prs_uint32("attribute_count", ps, depth, &info->attribute_count)) return False; @@ -2612,6 +2651,10 @@ static BOOL net_io_sam_privs_info(char *desc, SAM_DELTA_PRIVS *info, if (!smb_io_unistr2("uni_privslist", &info->uni_privslist[i], True, ps, depth)) return False; + if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc, + info->hdr_sec_desc.buffer, ps, depth)) + return False; + return True; } @@ -2627,8 +2670,8 @@ static BOOL net_io_sam_delta_ctr(char *desc, uint8 sess_key[16], switch (type) { /* Seen in sam deltas */ - case SAM_DELTA_SAM_STAMP: - if (!net_io_sam_delta_stamp("", &delta->stamp, ps, depth)) + case SAM_DELTA_MODIFIED_COUNT: + if (!net_io_sam_delta_mod_count("", &delta->mod_count, ps, depth)) return False; break; @@ -2657,8 +2700,8 @@ static BOOL net_io_sam_delta_ctr(char *desc, uint8 sess_key[16], return False; break; - case SAM_DELTA_DOM_INFO: - if (!net_io_sam_dom_info("", &delta->dom_info, ps, depth)) + case SAM_DELTA_POLICY_INFO: + if (!net_io_sam_policy_info("", &delta->policy_info, ps, depth)) return False; break; @@ -2672,16 +2715,23 @@ static BOOL net_io_sam_delta_ctr(char *desc, uint8 sess_key[16], return False; break; - case SAM_DELTA_UNK0E_INFO: - if (!net_io_sam_unk0e_info("", &delta->unk0e_info, ps, depth)) + case SAM_DELTA_TRUST_DOMS: + if (!net_io_sam_trustdoms_info("", &delta->trustdoms_info, ps, depth)) return False; break; - case SAM_DELTA_UNK12_INFO: - if (!net_io_sam_unk12_info("", &delta->unk12_info, ps, depth)) + case SAM_DELTA_SECRET_INFO: + if (!net_io_sam_secret_info("", &delta->secret_info, ps, depth)) return False; break; + /* These guys are not implemented yet */ + + case SAM_DELTA_RENAME_GROUP: + case SAM_DELTA_RENAME_USER: + case SAM_DELTA_RENAME_ALIAS: + case SAM_DELTA_DELETE_GROUP: + case SAM_DELTA_DELETE_USER: default: DEBUG(0, ("Replication error: Unknown delta type 0x%x\n", type)); break; diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c index 4de6b88e9cc..843be331877 100644 --- a/source3/rpc_parse/parse_prs.c +++ b/source3/rpc_parse/parse_prs.c @@ -1061,7 +1061,9 @@ BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str) len++; - dump_data(5+depth, (char *)start, len * 2); + DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset, name)); + print_asc(5, (unsigned char*)start, 2*len); + DEBUG(5, ("\n")); } else { /* unmarshalling */ @@ -1114,6 +1116,10 @@ BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str) /* NULL terminate the UNISTR */ str->buffer[len++] = '\0'; } + + DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset, name)); + print_asc(5, (unsigned char*)str->buffer, 2*len); + DEBUG(5, ("\n")); } /* set the offset in the prs_struct; 'len' points to the diff --git a/source3/rpc_parse/parse_reg.c b/source3/rpc_parse/parse_reg.c index 365ad2dc70b..2698e824407 100644 --- a/source3/rpc_parse/parse_reg.c +++ b/source3/rpc_parse/parse_reg.c @@ -34,79 +34,13 @@ static uint32 reg_init_buffer2( BUFFER2 *buf2, REGISTRY_VALUE *val ) { - UNISTR2 unistr; uint32 real_size = 0; - char *string; - char *list = NULL; - char *list2 = NULL; if ( !buf2 || !val ) return 0; - real_size = val->size; - - switch (val->type ) - { - case REG_SZ: - string = (char*)val->data_p; - DEBUG(10,("reg_init_buffer2: REG_SZ string => [%s]\n", string)); - - init_unistr2( &unistr, (char*)val->data_p, strlen((char*)val->data_p)+1 ); - init_buffer2( buf2, (char*)unistr.buffer, unistr.uni_str_len*2 ); - real_size = unistr.uni_str_len*2; - break; - - case REG_MULTI_SZ: - string = (char*)val->data_p; - real_size = 0; - while ( string && *string ) - { - DEBUG(10,("reg_init_buffer2: REG_MULTI_SZ string => [%s], size => [%d]\n", string, real_size )); - - init_unistr2( &unistr, string, strlen(string)+1 ); - - list2 = Realloc( list, real_size + unistr.uni_str_len*2 ); - if ( !list2 ) - break; - list = list2; - - memcpy( list+real_size, unistr.buffer, unistr.uni_str_len*2 ); - - real_size += unistr.uni_str_len*2; - - string += strlen(string)+1; - } - - list2 = Realloc( list, real_size + 2 ); - if ( !list2 ) - break; - list = list2; - list[real_size++] = 0x0; - list[real_size++] = 0x0; - - init_buffer2( buf2, (char*)list, real_size ); - - DEBUG(10,("reg_init_buffer2: REG_MULTI_SZ size => [%d]\n", real_size )); - - break; - - case REG_BINARY: - DEBUG(10,("reg_init_buffer2: REG_BINARY size => [%d]\n", val->size )); - - init_buffer2( buf2, val->data_p, val->size ); - break; - - case REG_DWORD: - DEBUG(10,("reg_init_buffer2: REG_DWORD value => [%d]\n", *(uint32*)val->data_p)); - init_buffer2( buf2, val->data_p, val->size ); - break; - - default: - DEBUG(0,("reg_init_buffer2: Unsupported registry data type [%d]\n", val->type)); - break; - } - - SAFE_FREE( list ); + real_size = regval_size(val); + init_buffer2( buf2, (char*)regval_data_p(val), real_size ); return real_size; } @@ -1767,7 +1701,11 @@ BOOL reg_io_q_open_entry(char *desc, REG_Q_OPEN_ENTRY *r_q, prs_struct *ps, int void init_reg_r_open_entry(REG_R_OPEN_ENTRY *r_r, POLICY_HND *pol, NTSTATUS status) { - memcpy(&r_r->pol, pol, sizeof(r_r->pol)); + if (NT_STATUS_IS_OK(status)) { + memcpy(&r_r->pol, pol, sizeof(r_r->pol)); + } else { + ZERO_STRUCT(r_r->pol); + } r_r->status = status; } diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 3a7f4b57ae6..36b00ff55db 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -659,7 +659,7 @@ BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmo { "panningheight", NULL } }; - /* assign at run time to keep non-gcc vompilers happy */ + /* assign at run time to keep non-gcc compilers happy */ opt_fields[0].field = &devmode->icmmethod; opt_fields[1].field = &devmode->icmintent; @@ -1211,6 +1211,26 @@ BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u, return True; } +/******************************************************************* + * make a structure. + ********************************************************************/ + +BOOL make_spoolss_q_getprinterdataex(SPOOL_Q_GETPRINTERDATAEX *q_u, + const POLICY_HND *handle, + char *keyname, char *valuename, uint32 size) +{ + if (q_u == NULL) return False; + + DEBUG(5,("make_spoolss_q_getprinterdataex\n")); + + q_u->handle = *handle; + init_unistr2(&q_u->valuename, valuename, strlen(valuename) + 1); + init_unistr2(&q_u->keyname, keyname, strlen(keyname) + 1); + q_u->size = size; + + return True; +} + /******************************************************************* * read a structure. * called from spoolss_q_getprinterdata (srv_spoolss.c) @@ -1344,7 +1364,7 @@ BOOL spoolss_io_r_getprinterdata(char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_st if (UNMARSHALLING(ps) && r_u->size) { r_u->data = prs_alloc_mem(ps, r_u->size); - if(r_u->data) + if(!r_u->data) return False; } @@ -3346,7 +3366,9 @@ uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info) * it is easier to maintain the calculation here and * not place the burden on the caller to remember. --jerry */ - size += size % 4; + if ((size % 4) != 0) { + size += 4 - (size % 4); + } return size; } @@ -3678,7 +3700,7 @@ uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p) /* uint32(offset) + uint32(length) + length) */ size += (size_of_uint32(&p->value_len)*2) + p->value_len; - size += (size_of_uint32(&p->data_len)*2) + p->data_len; + size += (size_of_uint32(&p->data_len)*2) + p->data_len + (p->data_len%2) ; size += size_of_uint32(&p->type); @@ -6065,20 +6087,52 @@ BOOL make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u, return True; } +/******************************************************************* +********************************************************************/ + +BOOL make_spoolss_q_enumprinterdataex(SPOOL_Q_ENUMPRINTERDATAEX *q_u, + const POLICY_HND *hnd, char *key, + uint32 size) +{ + memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); + init_unistr2(&q_u->key, key, strlen(key)+1); + q_u->size = size; + + return True; +} + /******************************************************************* ********************************************************************/ BOOL make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND *hnd, - char* value, char* data, uint32 data_size) + char* value, uint32 data_type, char* data, uint32 data_size) +{ + memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); + q_u->type = data_type; + init_unistr2(&q_u->value, value, strlen(value)+1); + + q_u->max_len = q_u->real_len = data_size; + q_u->data = data; + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL make_spoolss_q_setprinterdataex(SPOOL_Q_SETPRINTERDATAEX *q_u, const POLICY_HND *hnd, + char *key, char* value, uint32 data_type, char* data, + uint32 data_size) { memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); - q_u->type = REG_SZ; + q_u->type = data_type; init_unistr2(&q_u->value, value, strlen(value)+1); + init_unistr2(&q_u->key, key, strlen(key)+1); q_u->max_len = q_u->real_len = data_size; q_u->data = data; return True; } + /******************************************************************* ********************************************************************/ @@ -6863,6 +6917,12 @@ BOOL spoolss_io_r_getprinterdataex(char *desc, SPOOL_R_GETPRINTERDATAEX *r_u, pr if (!prs_uint32("size", ps, depth, &r_u->size)) return False; + if (UNMARSHALLING(ps) && r_u->size) { + r_u->data = prs_alloc_mem(ps, r_u->size); + if(!r_u->data) + return False; + } + if (!prs_uint8s(False,"data", ps, depth, r_u->data, r_u->size)) return False; @@ -7083,16 +7143,22 @@ static BOOL spoolss_io_printer_enum_values_ctr(char *desc, prs_struct *ps, prs_debug(ps, depth, desc, "spoolss_io_printer_enum_values_ctr"); depth++; - if (!prs_uint32("size", ps, depth, &ctr->size)) - return False; - - /* offset data begins at 20 bytes per structure * size_of_array. - Don't forget the uint32 at the beginning */ + /* + * offset data begins at 20 bytes per structure * size_of_array. + * Don't forget the uint32 at the beginning + * */ current_offset = basic_unit * ctr->size_of_array; /* first loop to write basic enum_value information */ + if (UNMARSHALLING(ps)) { + ctr->values = (PRINTER_ENUM_VALUES *)prs_alloc_mem( + ps, ctr->size_of_array * sizeof(PRINTER_ENUM_VALUES)); + if (!ctr->values) + return False; + } + for (i=0; isize_of_array; i++) { valuename_offset = current_offset; @@ -7106,18 +7172,22 @@ static BOOL spoolss_io_printer_enum_values_ctr(char *desc, prs_struct *ps, return False; data_offset = ctr->values[i].value_len + valuename_offset; + if (!prs_uint32("data_offset", ps, depth, &data_offset)) return False; if (!prs_uint32("data_len", ps, depth, &ctr->values[i].data_len)) return False; - current_offset = data_offset + ctr->values[i].data_len - basic_unit; + current_offset = data_offset + ctr->values[i].data_len - basic_unit; + /* account for 2 byte alignment */ + current_offset += (current_offset % 2); } - /* loop #2 for writing the dynamically size objects - while viewing conversations between Win2k -> Win2k, - 4-byte alignment does not seem to matter here --jerry */ + /* + * loop #2 for writing the dynamically size objects; pay + * attention to 2-byte alignment here.... + */ for (i=0; isize_of_array; i++) { @@ -7125,12 +7195,20 @@ static BOOL spoolss_io_printer_enum_values_ctr(char *desc, prs_struct *ps, if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename)) return False; + if (UNMARSHALLING(ps)) { + ctr->values[i].data = (uint8 *)prs_alloc_mem( + ps, ctr->values[i].data_len); + if (!ctr->values[i].data) + return False; + } + if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len)) return False; + + if ( !prs_align_uint16(ps) ) + return False; } - - return True; } @@ -7141,15 +7219,21 @@ static BOOL spoolss_io_printer_enum_values_ctr(char *desc, prs_struct *ps, BOOL spoolss_io_r_enumprinterdataex(char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, prs_struct *ps, int depth) { + int data_offset, end_offset; prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdataex"); depth++; if(!prs_align(ps)) return False; - if (!spoolss_io_printer_enum_values_ctr("", ps, &r_u->ctr, depth )) + if (!prs_uint32("size", ps, depth, &r_u->ctr.size)) return False; + data_offset = prs_offset(ps); + + if (!prs_set_offset(ps, data_offset + r_u->ctr.size)) + return False; + if(!prs_align(ps)) return False; @@ -7162,6 +7246,20 @@ BOOL spoolss_io_r_enumprinterdataex(char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, if(!prs_werror("status", ps, depth, &r_u->status)) return False; + r_u->ctr.size_of_array = r_u->returned; + + end_offset = prs_offset(ps); + + if (!prs_set_offset(ps, data_offset)) + return False; + + if (r_u->ctr.size) + if (!spoolss_io_printer_enum_values_ctr("", ps, &r_u->ctr, depth )) + return False; + + if (!prs_set_offset(ps, end_offset)) + return False; + return True; } @@ -7510,6 +7608,21 @@ BOOL make_spoolss_q_deleteprinterdata(SPOOL_Q_DELETEPRINTERDATA *q_u, return True; } +/******************************************************************* + * init a structure. + ********************************************************************/ + +BOOL make_spoolss_q_deleteprinterdataex(SPOOL_Q_DELETEPRINTERDATAEX *q_u, + POLICY_HND *handle, char *key, + char *value) +{ + memcpy(&q_u->handle, handle, sizeof(POLICY_HND)); + init_unistr2(&q_u->valuename, value, strlen(value) + 1); + init_unistr2(&q_u->keyname, key, strlen(key) + 1); + + return True; +} + /******************************************************************* * init a structure. ********************************************************************/ diff --git a/source3/rpc_parse/parse_srv.c b/source3/rpc_parse/parse_srv.c index 531267c308c..672db36a288 100644 --- a/source3/rpc_parse/parse_srv.c +++ b/source3/rpc_parse/parse_srv.c @@ -1119,10 +1119,8 @@ BOOL srv_io_r_net_share_enum(char *desc, SRV_R_NET_SHARE_ENUM *r_n, prs_struct * if(!prs_uint32("total_entries", ps, depth, &r_n->total_entries)) return False; - if(r_n->total_entries != 0) { - if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth)) - return False; - } + if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth)) + return False; if(!prs_werror("status", ps, depth, &r_n->status)) return False; diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index f28441886a5..e187e1556ef 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -473,6 +473,8 @@ NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_E /* * preferred length is set to 5 as a "our" preferred length * nt sets this parameter to 2 + * update (20.08.2002): it's not preferred length, but preferred size! + * it needs further investigation how to optimally choose this value */ uint32 max_num_domains = q_u->preferred_len < 5 ? q_u->preferred_len : 10; TRUSTDOM **trust_doms; diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c index 8f6011826aa..4478729e4d9 100644 --- a/source3/rpc_server/srv_netlog_nt.c +++ b/source3/rpc_server/srv_netlog_nt.c @@ -712,8 +712,8 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON * pdb_get_logon_script(sampw), pdb_get_profile_path(sampw), pdb_get_logon_time(sampw), - pdb_get_logoff_time(sampw), - pdb_get_kickoff_time(sampw), + get_time_t_max(), + get_time_t_max(), pdb_get_pass_last_set_time(sampw), pdb_get_pass_can_change_time(sampw), pdb_get_pass_must_change_time(sampw), diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index b7be415abcd..1947d5514e5 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -276,9 +276,6 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm auth_usersupplied_info *user_info = NULL; auth_serversupplied_info *server_info = NULL; - uid_t uid; - uid_t gid; - DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n")); memset(p->user_name, '\0', sizeof(p->user_name)); @@ -427,27 +424,30 @@ failed authentication on named pipe %s.\n", domain, user_name, wks, p->name )); memcpy(p->session_key, server_info->session_key, sizeof(p->session_key)); - uid = pdb_get_uid(server_info->sam_account); - gid = pdb_get_gid(server_info->sam_account); - - p->pipe_user.uid = uid; - p->pipe_user.gid = gid; - - /* Set up pipe user group membership. */ - initialise_groups(p->pipe_user_name, p->pipe_user.uid, p->pipe_user.gid); - get_current_groups(p->pipe_user.gid, &p->pipe_user.ngroups, &p->pipe_user.groups); + p->pipe_user.uid = pdb_get_uid(server_info->sam_account); + p->pipe_user.gid = pdb_get_gid(server_info->sam_account); + + p->pipe_user.ngroups = server_info->n_groups; + if (p->pipe_user.ngroups) { + if (!(p->pipe_user.groups = memdup(server_info->groups, sizeof(gid_t) * p->pipe_user.ngroups))) { + DEBUG(0,("failed to memdup group list to p->pipe_user.groups\n")); + free_server_info(&server_info); + return False; + } + } if (server_info->ptok) - add_supplementary_nt_login_groups(&p->pipe_user.ngroups, &p->pipe_user.groups, &server_info->ptok); - - /* Create an NT_USER_TOKEN struct for this user. */ - p->pipe_user.nt_user_token = create_nt_token(p->pipe_user.uid,p->pipe_user.gid, - p->pipe_user.ngroups, p->pipe_user.groups, - server_info->guest, server_info->ptok); + p->pipe_user.nt_user_token = dup_nt_token(server_info->ptok); + else { + DEBUG(1,("Error: Authmodule failed to provide nt_user_token\n")); + p->pipe_user.nt_user_token = NULL; + free_server_info(&server_info); + return False; + } p->ntlmssp_auth_validated = True; - pdb_free_sam(&server_info->sam_account); + free_server_info(&server_info); return True; } diff --git a/source3/rpc_server/srv_reg_nt.c b/source3/rpc_server/srv_reg_nt.c index cd9596d2a72..f96de7e5339 100644 --- a/source3/rpc_server/srv_reg_nt.c +++ b/source3/rpc_server/srv_reg_nt.c @@ -342,6 +342,9 @@ NTSTATUS _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u) { NTSTATUS status = NT_STATUS_NO_SUCH_FILE; fstring name; + char *value_ascii = ""; + fstring value; + int value_length; REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol ); REGISTRY_VALUE *val = NULL; REGISTRY_VALUE emptyval; @@ -380,15 +383,20 @@ NTSTATUS _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u) switch (lp_server_role()) { case ROLE_DOMAIN_PDC: case ROLE_DOMAIN_BDC: - regval_ctr_addvalue( ®vals, REGSTR_PRODUCTTYPE, REG_SZ, REG_PT_LANMANNT, strlen(REG_PT_LANMANNT)+1 ); + value_ascii = REG_PT_LANMANNT; break; case ROLE_STANDALONE: - regval_ctr_addvalue( ®vals, REGSTR_PRODUCTTYPE, REG_SZ, REG_PT_SERVERNT, strlen(REG_PT_SERVERNT)+1 ); + value_ascii = REG_PT_SERVERNT; break; case ROLE_DOMAIN_MEMBER: - regval_ctr_addvalue( ®vals, REGSTR_PRODUCTTYPE, REG_SZ, REG_PT_WINNT, strlen(REG_PT_WINNT)+1 ); + value_ascii = REG_PT_WINNT; break; } + value_length = push_ucs2(value, value, value_ascii, + sizeof(value), + STR_TERMINATE|STR_NOALIGN); + regval_ctr_addvalue(®vals, REGSTR_PRODUCTTYPE, REG_SZ, + value, value_length); val = dup_registry_value( regval_ctr_specific_value( ®vals, 0 ) ); diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index a30622c6008..ea631838dab 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -57,6 +57,8 @@ struct samr_info { DOM_SID sid; uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */ uint32 acc_granted; + uint16 acb_mask; + BOOL all_machines; DISP_INFO disp_info; TALLOC_CTX *mem_ctx; @@ -68,8 +70,7 @@ struct generic_mapping usr_generic_mapping = {USER_READ, USER_WRITE, USER_EXECUT struct generic_mapping grp_generic_mapping = {GROUP_READ, GROUP_WRITE, GROUP_EXECUTE, GROUP_ALL_ACCESS}; struct generic_mapping ali_generic_mapping = {ALIAS_READ, ALIAS_WRITE, ALIAS_EXECUTE, ALIAS_ALL_ACCESS}; -static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *d_size); - +static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size); /******************************************************************* Checks if access to an object should be granted, and returns that @@ -151,26 +152,36 @@ static struct samr_info *get_samr_info_by_sid(DOM_SID *psid) return info; } + /******************************************************************* Function to free the per handle data. ********************************************************************/ -static void free_samr_db(struct samr_info *info) +static void free_samr_users(struct samr_info *info) { int i; - /* Groups are talloced */ - if (info->disp_info.user_dbloaded){ for (i=0; idisp_info.num_user_account; i++) { /* Not really a free, actually a 'clear' */ pdb_free_sam(&info->disp_info.disp_user_info[i].sam); } } - info->disp_info.user_dbloaded=False; + info->disp_info.num_user_account=0; +} + + +/******************************************************************* + Function to free the per handle data. + ********************************************************************/ +static void free_samr_db(struct samr_info *info) +{ + /* Groups are talloced */ + + free_samr_users(info); + info->disp_info.group_dbloaded=False; info->disp_info.num_group_account=0; - info->disp_info.num_user_account=0; } @@ -199,7 +210,7 @@ static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass) } -static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask) +static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL all_machines) { SAM_ACCOUNT *pwd = NULL; DISP_USER_INFO *pwd_array = NULL; @@ -209,11 +220,15 @@ static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask) DEBUG(10,("load_sampwd_entries\n")); /* if the snapshoot is already loaded, return */ - if (info->disp_info.user_dbloaded==True) { + if ((info->disp_info.user_dbloaded==True) + && (info->acb_mask == acb_mask) + && (info->all_machines == all_machines)) { DEBUG(10,("load_sampwd_entries: already in memory\n")); return NT_STATUS_OK; } + free_samr_users(info); + if (!pdb_setsampwent(False)) { DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n")); return NT_STATUS_ACCESS_DENIED; @@ -222,10 +237,19 @@ static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask) for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd))) && pdb_getsampwent(pwd) == True; pwd=NULL) { - if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) { - pdb_free_sam(&pwd); - DEBUG(5,(" acb_mask %x reject\n", acb_mask)); - continue; + if (all_machines) { + if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST) + || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) { + DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask)); + pdb_free_sam(&pwd); + continue; + } + } else { + if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) { + pdb_free_sam(&pwd); + DEBUG(5,(" acb_mask %x reject\n", acb_mask)); + continue; + } } /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */ @@ -253,6 +277,8 @@ static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask) /* the snapshoot is in memory, we're ready to enumerate fast */ + info->acb_mask = acb_mask; + info->all_machines = all_machines; info->disp_info.user_dbloaded=True; DEBUG(12,("load_sampwd_entries: done\n")); @@ -406,46 +432,6 @@ NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, return r_u->status; } - -/******************************************************************* - samr_make_sam_obj_sd - ********************************************************************/ - -static NTSTATUS samr_make_sam_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size) -{ - extern DOM_SID global_sid_World; - DOM_SID adm_sid; - DOM_SID act_sid; - - SEC_ACE ace[3]; - SEC_ACCESS mask; - - SEC_ACL *psa = NULL; - - sid_copy(&adm_sid, &global_sid_Builtin); - sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS); - - sid_copy(&act_sid, &global_sid_Builtin); - sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS); - - /*basic access for every one*/ - init_sec_access(&mask, SAMR_EXECUTE | SAMR_READ); - init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - - /*full access for builtin aliases Administrators and Account Operators*/ - init_sec_access(&mask, SAMR_ALL_ACCESS); - init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - - if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL) - return NT_STATUS_NO_MEMORY; - - if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL) - return NT_STATUS_NO_MEMORY; - - return NT_STATUS_OK; -} - /******************************************************************* samr_make_dom_obj_sd ********************************************************************/ @@ -787,7 +773,7 @@ NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__)); become_root(); - r_u->status=load_sampwd_entries(info, q_u->acb_mask); + r_u->status=load_sampwd_entries(info, q_u->acb_mask, False); unbecome_root(); if (!NT_STATUS_IS_OK(r_u->status)) @@ -1058,8 +1044,6 @@ static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DO /******************************************************************* samr_reply_enum_dom_groups - Only reply with one group - domain admins. This must be fixed for - a real PDC. JRA. ********************************************************************/ NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u) @@ -1143,7 +1127,6 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, { struct samr_info *info = NULL; uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */ - uint16 acb_mask; uint32 max_entries=q_u->max_entries; uint32 enum_context=q_u->start_idx; @@ -1194,20 +1177,14 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, * JFM, 12/20/2001 */ - /* Get what we need from the password database */ - - if (q_u->switch_level==2) - acb_mask = ACB_WSTRUST; - else - acb_mask = ACB_NORMAL; - /* Get what we need from the password database */ switch (q_u->switch_level) { case 0x1: case 0x2: case 0x4: become_root(); - r_u->status=load_sampwd_entries(info, acb_mask); + /* Level 2 is for all machines, otherwise only 'normal' users */ + r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2); unbecome_root(); if (!NT_STATUS_IS_OK(r_u->status)) { DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n")); @@ -2126,7 +2103,7 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA break; case 0x02: become_root(); - r_u->status=load_sampwd_entries(info, ACB_NORMAL); + r_u->status=load_sampwd_entries(info, ACB_NORMAL, False); unbecome_root(); if (!NT_STATUS_IS_OK(r_u->status)) { DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n")); @@ -3880,6 +3857,7 @@ NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, S struct samr_info *info; PRIVILEGE_SET priv_set; uint32 acc_granted; + gid_t gid; init_privilege(&priv_set); @@ -3903,10 +3881,11 @@ NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, S return NT_STATUS_GROUP_EXISTS; /* we can create the UNIX group */ - smb_create_group(name); + if (smb_create_group(name, &gid) != 0) + return NT_STATUS_ACCESS_DENIED; /* check if the group has been successfully created */ - if ((grp=getgrnam(name)) == NULL) + if ((grp=getgrgid(gid)) == NULL) return NT_STATUS_ACCESS_DENIED; r_u->rid=pdb_gid_to_group_rid(grp->gr_gid); @@ -3943,6 +3922,7 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S struct samr_info *info; PRIVILEGE_SET priv_set; uint32 acc_granted; + gid_t gid; init_privilege(&priv_set); @@ -3966,10 +3946,11 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S return NT_STATUS_GROUP_EXISTS; /* we can create the UNIX group */ - smb_create_group(name); + if (smb_create_group(name, &gid) != 0) + return NT_STATUS_ACCESS_DENIED; /* check if the group has been successfully created */ - if ((grp=getgrnam(name)) == NULL) + if ((grp=getgrgid(gid)) == NULL) return NT_STATUS_ACCESS_DENIED; r_u->rid=pdb_gid_to_group_rid(grp->gr_gid); @@ -4095,9 +4076,9 @@ NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_ } /********************************************************************* - _samr_set_groupinfo + _samr_set_aliasinfo - update a domain group's comment. + update an alias's comment. *********************************************************************/ NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u) @@ -4290,10 +4271,10 @@ NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOW break; case 0x02: become_root(); - r_u->status=load_sampwd_entries(info, ACB_NORMAL); + r_u->status=load_sampwd_entries(info, ACB_NORMAL, False); unbecome_root(); if (!NT_STATUS_IS_OK(r_u->status)) { - DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n")); + DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n")); return r_u->status; } num_users=info->disp_info.num_user_account; @@ -4301,7 +4282,7 @@ NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOW r_u->status=load_group_domain_entries(info, get_global_sam_sid()); if (NT_STATUS_IS_ERR(r_u->status)) { - DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n")); + DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n")); return r_u->status; } num_groups=info->disp_info.num_group_account; diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 7aceaa548f2..2190215107a 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -4,7 +4,7 @@ * Copyright (C) Andrew Tridgell 1992-2000, * Copyright (C) Luke Kenneth Casson Leighton 1996-2000, * Copyright (C) Jean François Micouleau 1998-2000, - * Copyright (C) Jeremy Allison 2001, + * Copyright (C) Jeremy Allison 2001-2002, * Copyright (C) Gerald Carter 2000-2002, * Copyright (C) Tim Potter 2001-2002. * @@ -87,6 +87,10 @@ typedef struct _Printer{ fstring machine; fstring user; } client; + + /* devmode sent in the OpenPrinter() call */ + NT_DEVICEMODE *nt_devmode; + } Printer_entry; static Printer_entry *printers_list; @@ -196,6 +200,11 @@ static void srv_spoolss_replycloseprinter(POLICY_HND *handle) cli_ulogoff(¬ify_cli); cli_shutdown(¬ify_cli); message_deregister(MSG_PRINTER_NOTIFY2); + + /* Tell the connections db we're no longer interested in + * printer notify messages. */ + + register_message_flags( False, FLAG_MSG_PRINTING ); } smb_connections--; @@ -219,6 +228,8 @@ static void free_printer_entry(void *ptr) free_spool_notify_option(&Printer->notify.option); Printer->notify.option=NULL; Printer->notify.client_connected=False; + + free_nt_devicemode( &Printer->nt_devmode ); /* Remove from the internal list. */ DLIST_REMOVE(printers_list, Printer); @@ -566,7 +577,14 @@ static BOOL is_monitoring_event(Printer_entry *p, uint16 notify_type, { SPOOL_NOTIFY_OPTION *option = p->notify.option; uint32 i, j; - + + /* + * Flags should always be zero when the change notify + * is registered by the cliebnt's spooler. A user Win32 app + * might use the flags though instead of the NOTIFY_OPTION_INFO + * --jerry + */ + if (p->notify.flags) return is_monitoring_event_flags( p->notify.flags, notify_type, notify_field); @@ -716,26 +734,177 @@ static struct notify2_message_table job_notify_table[] = { /* 0x17 */ { "JOB_NOTIFY_BYTES_PRINTED", NULL }, }; + +/*********************************************************************** + Allocate talloc context for container object + **********************************************************************/ + +static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr ) +{ + if ( !ctr ) + return; + + ctr->ctx = talloc_init(); + + return; +} + +/*********************************************************************** + release all allocated memory and zero out structure + **********************************************************************/ + +static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr ) +{ + if ( !ctr ) + return; + + if ( ctr->ctx ) + talloc_destroy(ctr->ctx); + + ZERO_STRUCTP(ctr); + + return; +} + +/*********************************************************************** + **********************************************************************/ + +static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr ) +{ + if ( !ctr ) + return NULL; + + return ctr->ctx; +} + +/*********************************************************************** + **********************************************************************/ + +static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx ) +{ + if ( !ctr || !ctr->msg_groups ) + return NULL; + + if ( idx >= ctr->num_groups ) + return NULL; + + return &ctr->msg_groups[idx]; + +} + +/*********************************************************************** + How many groups of change messages do we have ? + **********************************************************************/ + +static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr ) +{ + if ( !ctr ) + return 0; + + return ctr->num_groups; +} + +/*********************************************************************** + Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group + **********************************************************************/ + +static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg ) +{ + SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL; + SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL; + SPOOLSS_NOTIFY_MSG *msg_list = NULL; + int i, new_slot; + + if ( !ctr || !msg ) + return 0; + + /* loop over all groups looking for a matching printer name */ + + for ( i=0; inum_groups; i++ ) { + if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 ) + break; + } + + /* add a new group? */ + + if ( i == ctr->num_groups ) + { + ctr->num_groups++; + + if ( !(groups = talloc_realloc( ctr->ctx, ctr->msg_groups, sizeof(SPOOLSS_NOTIFY_MSG_GROUP)*ctr->num_groups)) ) { + DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n")); + return 0; + } + ctr->msg_groups = groups; + + /* clear the new entry and set the printer name */ + + ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] ); + fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer ); + } + + /* add the change messages; 'i' is the correct index now regardless */ + + msg_grp = &ctr->msg_groups[i]; + + msg_grp->num_msgs++; + + if ( !(msg_list = talloc_realloc( ctr->ctx, msg_grp->msgs, sizeof(SPOOLSS_NOTIFY_MSG)*msg_grp->num_msgs )) ) { + DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs)); + return 0; + } + msg_grp->msgs = msg_list; + + new_slot = msg_grp->num_msgs-1; + memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) ); + + /* need to allocate own copy of data */ + + if ( msg->len != 0 ) + msg_grp->msgs[new_slot].notify.data = talloc_memdup( ctr->ctx, msg->notify.data, msg->len ); + + return ctr->num_groups; +} + /*********************************************************************** Send a change notication message on all handles which have a call back registered **********************************************************************/ -static void process_notify2_message(struct spoolss_notify_msg *msg, - TALLOC_CTX *mem_ctx) +static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx ) { - Printer_entry *p; - - DEBUG(8,("process_notify2_message: Enter...[%s]\n", msg->printer)); + Printer_entry *p; + TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr ); + SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx ); + SPOOLSS_NOTIFY_MSG *messages; + + + if ( !msg_group ) { + DEBUG(5,("send_notify2_changes() called with no msg group!\n")); + return; + } + + messages = msg_group->msgs; - for (p = printers_list; p; p = p->next) { + if ( !messages ) { + DEBUG(5,("send_notify2_changes() called with no messages!\n")); + return; + } + + DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername)); + + /* loop over all printers */ + + for (p = printers_list; p; p = p->next) + { SPOOL_NOTIFY_INFO_DATA *data; - uint32 data_len = 1; - uint32 id; + uint32 data_len = 0; + uint32 id; + int i; /* Is there notification on this handle? */ - if (!p->notify.client_connected) + if ( !p->notify.client_connected ) continue; DEBUG(10,("Client connected! [%s]\n", p->dev.handlename)); @@ -744,25 +913,31 @@ static void process_notify2_message(struct spoolss_notify_msg *msg, notifications. */ if ( ( p->printer_type == PRINTER_HANDLE_IS_PRINTER ) && - ( !strequal(msg->printer, p->dev.handlename) ) ) + ( !strequal(msg_group->printername, p->dev.handlename) ) ) continue; DEBUG(10,("Our printer\n")); + /* allocate the max entries possible */ + + data = talloc( mem_ctx, msg_group->num_msgs*sizeof(SPOOL_NOTIFY_INFO_DATA) ); + ZERO_STRUCTP(data); + + /* build the array of change notifications */ + + for ( i=0; inum_msgs; i++ ) + { + SPOOLSS_NOTIFY_MSG *msg = &messages[i]; + /* Are we monitoring this event? */ if (!is_monitoring_event(p, msg->type, msg->field)) continue; + DEBUG(10,("process_notify2_message: Sending message type [%x] field [%x] for printer [%s]\n", msg->type, msg->field, p->dev.handlename)); - /* OK - send the event to the client */ - - data = talloc(mem_ctx, sizeof(SPOOL_NOTIFY_INFO_DATA)); - - ZERO_STRUCTP(data); - /* * if the is a printer notification handle and not a job notification * type, then set the id to 0. Other wise just use what was specified @@ -784,8 +959,8 @@ static void process_notify2_message(struct spoolss_notify_msg *msg, /* Convert unix jobid to smb jobid */ - if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) { - + if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) + { id = sysjob_to_jobid(msg->id); if (id == -1) { @@ -794,22 +969,20 @@ static void process_notify2_message(struct spoolss_notify_msg *msg, } } - construct_info_data(data, msg->type, msg->field, id); + construct_info_data( &data[data_len], msg->type, msg->field, id ); switch(msg->type) { case PRINTER_NOTIFY_TYPE: if ( !printer_notify_table[msg->field].fn ) goto done; - - printer_notify_table[msg->field].fn(msg, data, mem_ctx); + printer_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx); break; case JOB_NOTIFY_TYPE: if ( !job_notify_table[msg->field].fn ) goto done; - - job_notify_table[msg->field].fn(msg, data, mem_ctx); + job_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx); break; @@ -818,59 +991,139 @@ static void process_notify2_message(struct spoolss_notify_msg *msg, goto done; } + data_len++; + } + cli_spoolss_rrpcn( ¬ify_cli, mem_ctx, &p->notify.client_hnd, data_len, data, p->notify.change, 0 ); } + done: - DEBUG(8,("process_notify2_message: Exit...\n")); + DEBUG(8,("send_notify2_changes: Exit...\n")); return; } -/* Receive a notify2 message */ +/*********************************************************************** + **********************************************************************/ -static void receive_notify2_message(int msg_type, pid_t src, void *buf, - size_t len) +static BOOL notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, void *buf, size_t len ) { - struct spoolss_notify_msg msg; + int offset = 0; - TALLOC_CTX *mem_ctx = talloc_init(); /* Unpack message */ - ZERO_STRUCT(msg); - offset += tdb_unpack((char *)buf + offset, len - offset, "f", - msg.printer); + msg->printer); offset += tdb_unpack((char *)buf + offset, len - offset, "ddddd", - &msg.type, &msg.field, &msg.id, &msg.len, &msg.flags); + &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags); - if (msg.len == 0) + if (msg->len == 0) tdb_unpack((char *)buf + offset, len - offset, "dd", - &msg.notify.value[0], &msg.notify.value[1]); + &msg->notify.value[0], &msg->notify.value[1]); else tdb_unpack((char *)buf + offset, len - offset, "B", - &msg.len, &msg.notify.data); + &msg->len, &msg->notify.data); - DEBUG(3, ("got NOTIFY2 message, type %d, field 0x%02x, flags 0x%04x\n", - msg.type, msg.field, msg.flags)); + DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message, type %d, field 0x%02x, flags 0x%04x\n", + msg->type, msg->field, msg->flags)); - if (msg.len == 0) - DEBUG(3, ("value1 = %d, value2 = %d\n", msg.notify.value[0], - msg.notify.value[1])); + if (msg->len == 0) + DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0], + msg->notify.value[1])); else - dump_data(3, msg.notify.data, msg.len); + dump_data(3, msg->notify.data, msg->len); + + return True; +} + +/******************************************************************** + Receive a notify2 message list + ********************************************************************/ + +static void receive_notify2_message_list(int msg_type, pid_t src, void *msg, size_t len) +{ + size_t msg_count, i; + char *buf = (char *)msg; + char *msg_ptr; + size_t msg_len; + SPOOLSS_NOTIFY_MSG notify; + SPOOLSS_NOTIFY_MSG_CTR messages; + int num_groups; + + if (len < 4) { + DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n")); + return; + } + + msg_count = IVAL(buf, 0); + msg_ptr = buf + 4; - /* Process message */ + DEBUG(5, ("receive_notify2_message_list: got %d messages in list\n", msg_count)); - process_notify2_message(&msg, mem_ctx); + if (msg_count == 0) { + DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n")); + return; + } - /* Free message */ + /* initialize the container */ + + ZERO_STRUCT( messages ); + notify_msg_ctr_init( &messages ); + + /* + * build message groups for each printer identified + * in a change_notify msg. Remember that a PCN message + * includes the handle returned for the srv_spoolss_replyopenprinter() + * call. Therefore messages are grouped according to printer handle. + */ + + for ( i=0; i len) { + DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n")); + return; + } - if (msg.len > 0) - free(msg.notify.data); + msg_len = IVAL(msg_ptr,0); + msg_ptr += 4; - talloc_destroy(mem_ctx); + if (msg_ptr + msg_len - buf > len) { + DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n")); + return; + } + + /* unpack messages */ + + ZERO_STRUCT( notify ); + notify2_unpack_msg( ¬ify, msg_ptr, msg_len ); + msg_ptr += msg_len; + + /* add to correct list in container */ + + notify_msg_ctr_addmsg( &messages, ¬ify ); + + /* free memory that might have been allocated by notify2_unpack_msg() */ + + if ( notify.len != 0 ) + SAFE_FREE( notify.notify.data ); + } + + /* process each group of messages */ + + num_groups = notify_msg_ctr_numgroups( &messages ); + for ( i=0; iprinter_default; - POLICY_HND *handle = &r_u->handle; + UNISTR2 *printername = NULL; + PRINTER_DEFAULT *printer_default = &q_u->printer_default; + POLICY_HND *handle = &r_u->handle; fstring name; int snum; @@ -1180,39 +1484,36 @@ Can't find printer handle we created for printer %s\n", name )); return WERR_INVALID_PRINTER_NAME; } - /* - First case: the user is opening the print server: - - Disallow MS AddPrinterWizard if parameter disables it. A Win2k - client 1st tries an OpenPrinterEx with access==0, MUST be allowed. - - Then both Win2k and WinNT clients try an OpenPrinterEx with - SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0) - or if the user is listed in the smb.conf printer admin parameter. - - Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the - client view printer folder, but does not show the MSAPW. - - Note: this test needs code to check access rights here too. Jeremy - could you look at this? - - - Second case: the user is opening a printer: - NT doesn't let us connect to a printer if the connecting user - doesn't have print permission. - - */ - get_current_user(&user, p); - if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER) { + /* + * First case: the user is opening the print server: + * + * Disallow MS AddPrinterWizard if parameter disables it. A Win2k + * client 1st tries an OpenPrinterEx with access==0, MUST be allowed. + * + * Then both Win2k and WinNT clients try an OpenPrinterEx with + * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0) + * or if the user is listed in the smb.conf printer admin parameter. + * + * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the + * client view printer folder, but does not show the MSAPW. + * + * Note: this test needs code to check access rights here too. Jeremy + * could you look at this? + * + * Second case: the user is opening a printer: + * NT doesn't let us connect to a printer if the connecting user + * doesn't have print permission. + */ + if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER) + { /* Printserver handles use global struct... */ snum = -1; - /* Map standard access rights to object specific access - rights */ + /* Map standard access rights to object specific access rights */ se_map_standard(&printer_default->access_required, &printserver_std_mapping); @@ -1231,23 +1532,32 @@ Can't find printer handle we created for printer %s\n", name )); /* Allow admin access */ - if (printer_default->access_required & - SERVER_ACCESS_ADMINISTER) { - + if ( printer_default->access_required & SERVER_ACCESS_ADMINISTER ) + { if (!lp_ms_add_printer_wizard()) { close_printer_handle(p, handle); return WERR_ACCESS_DENIED; } - if (user.uid == 0 || - user_in_list(uidtoname(user.uid), - lp_printer_admin(snum))) - return WERR_OK; + /* if the user is not root and not a printer admin, then fail */ - close_printer_handle(p, handle); - return WERR_ACCESS_DENIED; + if ( user.uid != 0 + && !user_in_list(uidtoname(user.uid), lp_printer_admin(snum)) ) + { + close_printer_handle(p, handle); + return WERR_ACCESS_DENIED; + } + + printer_default->access_required = SERVER_ACCESS_ADMINISTER; + } + else + { + printer_default->access_required = SERVER_ACCESS_ENUMERATE; } + DEBUG(4,("Setting print server access = %s\n", (printer_default->access_required == SERVER_ACCESS_ADMINISTER) + ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" )); + /* We fall through to return WERR_OK */ } @@ -1296,84 +1606,24 @@ Can't find printer handle we created for printer %s\n", name )); else printer_default->access_required = PRINTER_ACCESS_USE; - DEBUG(4,("Setting printer access=%x\n", printer_default->access_required)); - Printer->access_granted = printer_default->access_required; - - /* - * If we have a default device pointer in the - * printer_default struct, then we need to get - * the printer info from the tdb and if there is - * no default devicemode there then we do a *SET* - * here ! This is insanity.... JRA. - */ - - /* - * If the openprinterex rpc call contains a devmode, - * it's a per-user one. This per-user devmode is derivated - * from the global devmode. Openprinterex() contains a per-user - * devmode for when you do EMF printing and spooling. - * In the EMF case, the NT workstation is only doing half the job - * of rendering the page. The other half is done by running the printer - * driver on the server. - * The EMF file doesn't contain the page description (paper size, orientation, ...). - * The EMF file only contains what is to be printed on the page. - * So in order for the server to know how to print, the NT client sends - * a devicemode attached to the openprinterex call. - * But this devicemode is short lived, it's only valid for the current print job. - * - * If Samba would have supported EMF spooling, this devicemode would - * have been attached to the handle, to sent it to the driver to correctly - * rasterize the EMF file. - * - * As Samba only supports RAW spooling, we only receive a ready-to-print file, - * we just act as a pass-thru between windows and the printer. - * - * In order to know that Samba supports only RAW spooling, NT has to call - * getprinter() at level 2 (attribute field) or NT has to call startdoc() - * and until NT sends a RAW job, we refuse it. - * - * But to call getprinter() or startdoc(), you first need a valid handle, - * and to get an handle you have to call openprintex(). Hence why you have - * a devicemode in the openprinterex() call. - * - * - * Differences between NT4 and NT 2000. - * NT4: - * --- - * On NT4, you only have a global devicemode. This global devicemode can be changed - * by the administrator (or by a user with enough privs). Everytime a user - * wants to print, the devicemode is resetted to the default. In Word, everytime - * you print, the printer's characteristics are always reset to the global devicemode. - * - * NT 2000: - * ------- - * In W2K, there is the notion of per-user devicemode. The first time you use - * a printer, a per-user devicemode is build from the global devicemode. - * If you change your per-user devicemode, it is saved in the registry, under the - * H_KEY_CURRENT_KEY sub_tree. So that everytime you print, you have your default - * printer preferences available. - * - * To change the per-user devicemode: it's the "Printing Preferences ..." button - * on the General Tab of the printer properties windows. - * - * To change the global devicemode: it's the "Printing Defaults..." button - * on the Advanced Tab of the printer properties window. - * - * JFM. - */ + DEBUG(4,("Setting printer access = %s\n", (printer_default->access_required == PRINTER_ACCESS_ADMINISTER) + ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" )); - - -#if 0 - if (printer_default->devmode_cont.devmode != NULL) { - result = printer_write_default_dev( snum, printer_default); - if (result != 0) { - close_printer_handle(p, handle); - return result; - } - } -#endif } + + Printer->access_granted = printer_default->access_required; + + /* + * If the client sent a devmode in the OpenPrinter() call, then + * save it here in case we get a job submission on this handle + */ + + if ( (Printer->printer_type != PRINTER_HANDLE_IS_PRINTSERVER) + && q_u->printer_default.devmode_cont.devmode_ptr ) + { + convert_devicemode( Printer->dev.handlename, q_u->printer_default.devmode_cont.devmode, + &Printer->nt_devmode ); + } return WERR_OK; } @@ -1599,8 +1849,11 @@ WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER fstring driver; fstring arch; NT_PRINTER_DRIVER_INFO_LEVEL info; + NT_PRINTER_DRIVER_INFO_LEVEL info_win2k; int version; struct current_user user; + WERROR status; + WERROR status_win2k = WERR_ACCESS_DENIED; get_current_user(&user, p); @@ -1608,25 +1861,58 @@ WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER unistr2_to_ascii(arch, &q_u->arch, sizeof(arch)-1 ); /* check that we have a valid driver name first */ - if ((version=get_version_id(arch)) == -1) { - /* this is what NT returns */ + + if ((version=get_version_id(arch)) == -1) return WERR_INVALID_ENVIRONMENT; + + ZERO_STRUCT(info); + ZERO_STRUCT(info_win2k); + + if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) + { + /* try for Win2k driver if "Windows NT x86" */ + + if ( version == 2 ) { + version = 3; + if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) { + status = WERR_UNKNOWN_PRINTER_DRIVER; + goto done; + } + } } - /* if they said "Windows NT x86", then try for version 2 & 3 */ + if (printer_driver_in_use(info.info_3)) { + status = WERR_PRINTER_DRIVER_IN_USE; + goto done; + } if ( version == 2 ) - version = DRIVER_ANY_VERSION; + { + if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3))) + { + /* if we get to here, we now have 2 driver info structures to remove */ + /* remove the Win2k driver first*/ - ZERO_STRUCT(info); + status_win2k = delete_printer_driver(info_win2k.info_3, &user, 3, False ); + free_a_printer_driver( info_win2k, 3 ); + + /* this should not have failed---if it did, report to client */ + if ( !W_ERROR_IS_OK(status_win2k) ) + goto done; + } + } - if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) - return WERR_UNKNOWN_PRINTER_DRIVER; + status = delete_printer_driver(info.info_3, &user, version, False); + + /* if at least one of the deletes succeeded return OK */ - if (printer_driver_in_use(info.info_3)) - return WERR_PRINTER_DRIVER_IN_USE; + if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) ) + status = WERR_OK; + +done: + free_a_printer_driver( info, 3 ); - return delete_printer_driver(info.info_3, &user, DRIVER_ANY_VERSION, False); + return status; } /******************************************************************** @@ -1638,10 +1924,13 @@ WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIV fstring driver; fstring arch; NT_PRINTER_DRIVER_INFO_LEVEL info; + NT_PRINTER_DRIVER_INFO_LEVEL info_win2k; int version; uint32 flags = q_u->delete_flags; BOOL delete_files; struct current_user user; + WERROR status; + WERROR status_win2k = WERR_ACCESS_DENIED; get_current_user(&user, p); @@ -1656,17 +1945,36 @@ WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIV if ( flags & DPD_DELETE_SPECIFIC_VERSION ) version = q_u->version; - else if ( version == 2 ) - /* if they said "Windows NT x86", then try for version 2 & 3 */ - version = DRIVER_ANY_VERSION; ZERO_STRUCT(info); + ZERO_STRUCT(info_win2k); + + status = get_a_printer_driver(&info, 3, driver, arch, version); - if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) - return WERR_UNKNOWN_PRINTER_DRIVER; + if ( !W_ERROR_IS_OK(status) ) + { + /* + * if the client asked for a specific version, + * or this is something other than Windows NT x86, + * then we've failed + */ + + if ( (flags&DPD_DELETE_SPECIFIC_VERSION) || (version !=2) ) + goto done; + + /* try for Win2k driver if "Windows NT x86" */ + + version = 3; + if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) { + status = WERR_UNKNOWN_PRINTER_DRIVER; + goto done; + } + } - if ( printer_driver_in_use(info.info_3) ) - return WERR_PRINTER_DRIVER_IN_USE; + if ( printer_driver_in_use(info.info_3) ) { + status = WERR_PRINTER_DRIVER_IN_USE; + goto done; + } /* * we have a couple of cases to consider. @@ -1682,24 +1990,119 @@ WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIV delete_files = flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES); - if ( delete_files ) - { - /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */ + /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */ + + if ( delete_files && printer_driver_files_in_use(info.info_3) & (flags&DPD_DELETE_ALL_FILES) ) { + /* no idea of the correct error here */ + status = WERR_ACCESS_DENIED; + goto done; + } + + + /* also check for W32X86/3 if necessary; maybe we already have? */ + + if ( (version == 2) && ((flags&DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) { + if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3))) + { + + if ( delete_files && printer_driver_files_in_use(info_win2k.info_3) & (flags&DPD_DELETE_ALL_FILES) ) { + /* no idea of the correct error here */ + free_a_printer_driver( info_win2k, 3 ); + status = WERR_ACCESS_DENIED; + goto done; + } + + /* if we get to here, we now have 2 driver info structures to remove */ + /* remove the Win2k driver first*/ - if ( printer_driver_files_in_use(info.info_3) & (flags&DPD_DELETE_ALL_FILES) ) - /* no idea of the correct error here */ - return WERR_ACCESS_DENIED; + status_win2k = delete_printer_driver(info_win2k.info_3, &user, 3, delete_files); + free_a_printer_driver( info_win2k, 3 ); + + /* this should not have failed---if it did, report to client */ + + if ( !W_ERROR_IS_OK(status_win2k) ) + goto done; + } } - return delete_printer_driver(info.info_3, &user, version, delete_files); + status = delete_printer_driver(info.info_3, &user, version, delete_files); + + if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) ) + status = WERR_OK; +done: + free_a_printer_driver( info, 3 ); + + return status; +} + + +/**************************************************************************** + Internal routine for retreiving printerdata + ***************************************************************************/ + +static WERROR get_printer_dataex( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL *printer, + char *key, char *value, uint32 *type, uint8 **data, + uint32 *needed, uint32 in_size ) +{ + REGISTRY_VALUE *val; + int size, data_len; + + if ( !(val = get_printer_data( printer->info_2, key, value)) ) + return WERR_BADFILE; + + *type = regval_type( val ); + + DEBUG(5,("get_printer_dataex: allocating %d\n", in_size)); + + size = regval_size( val ); + + /* copy the min(in_size, len) */ + + if ( in_size ) { + data_len = (size > in_size) ? in_size : size*sizeof(uint8); + if ( (*data = (uint8 *)talloc_memdup(ctx, regval_data_p(val), data_len)) == NULL ) + return WERR_NOMEM; + } + else + *data = NULL; + + *needed = size; + + DEBUG(5,("get_printer_dataex: copy done\n")); + + return WERR_OK; +} + +/**************************************************************************** + Internal routine for removing printerdata + ***************************************************************************/ + +static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, char *key, char *value ) +{ + delete_printer_data( printer->info_2, key, value ); + + return mod_a_printer(*printer, 2); } +/**************************************************************************** + Internal routine for storing printerdata + ***************************************************************************/ + +static WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, char *key, char *value, + uint32 type, uint8 *data, int real_len ) +{ + delete_printer_data( printer->info_2, key, value ); + + add_printer_data( printer->info_2, key, value, type, data, real_len ); + + return mod_a_printer(*printer, 2); +} /******************************************************************** GetPrinterData on a printer server Handle. ********************************************************************/ -static BOOL getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size) +static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size) { int i; @@ -1708,50 +2111,50 @@ static BOOL getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 if (!strcmp(value, "W3SvcInstalled")) { *type = 0x4; if((*data = (uint8 *)talloc_zero(ctx, 4*sizeof(uint8) )) == NULL) - return False; - *needed = 0x4; - return True; + return WERR_NOMEM; + *needed = 0x4; + return WERR_OK; } if (!strcmp(value, "BeepEnabled")) { *type = 0x4; if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL) - return False; + return WERR_NOMEM; SIVAL(*data, 0, 0x00); *needed = 0x4; - return True; + return WERR_OK; } if (!strcmp(value, "EventLog")) { *type = 0x4; if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL) - return False; + return WERR_NOMEM; /* formally was 0x1b */ SIVAL(*data, 0, 0x0); *needed = 0x4; - return True; + return WERR_OK; } if (!strcmp(value, "NetPopup")) { *type = 0x4; if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL) - return False; + return WERR_NOMEM; SIVAL(*data, 0, 0x00); *needed = 0x4; - return True; + return WERR_OK; } if (!strcmp(value, "MajorVersion")) { *type = 0x4; if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL) - return False; + return WERR_NOMEM; #ifndef EMULATE_WIN2K_HACK /* JERRY */ SIVAL(*data, 0, 2); #else SIVAL(*data, 0, 3); #endif *needed = 0x4; - return True; + return WERR_OK; } if (!strcmp(value, "DefaultSpoolDirectory")) { @@ -1761,7 +2164,7 @@ static BOOL getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type = 0x1; *needed = 2*(strlen(string)+1); if((*data = (uint8 *)talloc(ctx, ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL) - return False; + return WERR_NOMEM; memset(*data, 0, (*needed > in_size) ? *needed:in_size); /* it's done by hand ready to go on the wire */ @@ -1769,7 +2172,7 @@ static BOOL getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 (*data)[2*i]=string[i]; (*data)[2*i+1]='\0'; } - return True; + return WERR_OK; } if (!strcmp(value, "Architecture")) { @@ -1777,97 +2180,36 @@ static BOOL getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type = 0x1; *needed = 2*(strlen(string)+1); if((*data = (uint8 *)talloc(ctx, ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL) - return False; + return WERR_NOMEM; memset(*data, 0, (*needed > in_size) ? *needed:in_size); for (i=0; iinfo_2, SPOOL_PRINTERDATA_KEY, value)) ) - { - free_a_printer(&printer, 2); - return False; - } - - *type = regval_type( val ); - - - DEBUG(5,("getprinterdata_printer:allocating %d\n", in_size)); - - if (in_size) - { - if ( (*data = (uint8 *)talloc(ctx, in_size * sizeof(uint8))) == NULL ) - return False; - - memset( *data, 0, in_size *sizeof(uint8) ); - - /* copy the min(in_size, len) */ - - size = regval_size( val ); - memcpy( *data, regval_data_p(val), (size > in_size) ? in_size : size*sizeof(uint8) ); - } - else - *data = NULL; - - *needed = size; - - DEBUG(5,("getprinterdata_printer:copy done\n")); - - - free_a_printer(&printer, 2); - return True; -} - /******************************************************************** * spoolss_getprinterdata ********************************************************************/ WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u) { - POLICY_HND *handle = &q_u->handle; - UNISTR2 *valuename = &q_u->valuename; - uint32 in_size = q_u->size; - uint32 *type = &r_u->type; - uint32 *out_size = &r_u->size; - uint8 **data = &r_u->data; - uint32 *needed = &r_u->needed; - - fstring value; - BOOL found=False; - Printer_entry *Printer = find_printer_index_by_hnd(p, handle); + POLICY_HND *handle = &q_u->handle; + UNISTR2 *valuename = &q_u->valuename; + uint32 in_size = q_u->size; + uint32 *type = &r_u->type; + uint32 *out_size = &r_u->size; + uint8 **data = &r_u->data; + uint32 *needed = &r_u->needed; + WERROR status; + fstring value; + Printer_entry *Printer = find_printer_index_by_hnd(p, handle); + NT_PRINTER_INFO_LEVEL *printer = NULL; + int snum = 0; /* * Reminder: when it's a string, the length is in BYTES @@ -1885,45 +2227,58 @@ WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPO DEBUG(4,("_spoolss_getprinterdata\n")); - if (!Printer) { - if((*data=(uint8 *)talloc_zero(p->mem_ctx, 4*sizeof(uint8))) == NULL) - return WERR_NOMEM; + if ( !Printer ) { DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); - return WERR_BADFID; + status = WERR_BADFID; + goto done; } unistr2_to_ascii(value, valuename, sizeof(value)-1); - if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER) - found = getprinterdata_printer_server(p->mem_ctx, value, type, data, needed, *out_size); + if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER ) + status = getprinterdata_printer_server( p->mem_ctx, value, type, data, needed, *out_size ); else - found = getprinterdata_printer(p, p->mem_ctx, handle, value, type, data, needed, *out_size); + { + if ( !get_printer_snum(p,handle, &snum) ) { + status = WERR_BADFID; + goto done; + } - if ( !found ) + status = get_a_printer(&printer, 2, lp_servicename(snum)); + if ( !W_ERROR_IS_OK(status) ) + goto done; + + status = get_printer_dataex( p->mem_ctx, printer, SPOOL_PRINTERDATA_KEY, value, type, data, needed, *out_size ); + } + + if (*needed > *out_size) + status = WERR_MORE_DATA; + +done: + if ( !W_ERROR_IS_OK(status) ) { - DEBUG(5, ("value not found, allocating %d\n", *out_size)); + DEBUG(5, ("error: allocating %d\n", *out_size)); /* reply this param doesn't exist */ - if (*out_size) { - if((*data=(uint8 *)talloc_zero(p->mem_ctx, *out_size*sizeof(uint8))) == NULL) + if ( *out_size ) { + if((*data=(uint8 *)talloc_zero(p->mem_ctx, *out_size*sizeof(uint8))) == NULL) { + if ( printer ) + free_a_printer( &printer, 2 ); return WERR_NOMEM; - } else { + } + } + else { *data = NULL; } - - /* error depends on handle type */ - - if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER) - return WERR_INVALID_PARAM; - else - return WERR_BADFILE; } - if (*needed > *out_size) - return WERR_MORE_DATA; - else - return WERR_OK; + /* cleanup & exit */ + + if ( printer ) + free_a_printer( &printer, 2 ); + + return status; } /********************************************************* @@ -1961,6 +2316,7 @@ static BOOL spoolss_connect_to_client(struct cli_state *the_cli, char *remote_ma if (!attempt_netbios_session_request(the_cli, global_myname, remote_machine, &the_cli->dest_ip)) { DEBUG(0,("connect_to_client: machine %s rejected the NetBIOS session request.\n", remote_machine)); + cli_shutdown(the_cli); return False; } @@ -2036,7 +2392,10 @@ static BOOL srv_spoolss_replyopenprinter(char *printer, uint32 localprinter, uin if(!spoolss_connect_to_client(¬ify_cli, unix_printer)) return False; - message_register(MSG_PRINTER_NOTIFY2, receive_notify2_message); + message_register(MSG_PRINTER_NOTIFY2, receive_notify2_message_list); + /* Tell the connections db we're now interested in printer + * notify messages. */ + register_message_flags( True, FLAG_MSG_PRINTING ); } smb_connections++; @@ -2436,8 +2795,8 @@ static void spoolss_notify_security_desc(int snum, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - data->notify_data.data.length=0; - data->notify_data.data.string = NULL; + data->notify_data.sd.size = printer->info_2->secdesc_buf->len; + data->notify_data.sd.desc = dup_sec_desc( mem_ctx, printer->info_2->secdesc_buf->sec ) ; } /******************************************************************* @@ -3443,47 +3802,20 @@ static void free_dev_mode(DEVICEMODE *dev) SAFE_FREE(dev); } + /**************************************************************************** - Create a DEVMODE struct. Returns malloced memory. + Convert an NT_DEVICEMODE to a DEVICEMODE structure. Both pointers + should be valid upon entry ****************************************************************************/ -DEVICEMODE *construct_dev_mode(int snum) +static BOOL convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode ) { - char adevice[32]; - char aform[32]; - NT_PRINTER_INFO_LEVEL *printer = NULL; - NT_DEVICEMODE *ntdevmode = NULL; - DEVICEMODE *devmode = NULL; - - DEBUG(7,("construct_dev_mode\n")); - - DEBUGADD(8,("getting printer characteristics\n")); - - if ((devmode = (DEVICEMODE *)malloc(sizeof(DEVICEMODE))) == NULL) { - DEBUG(2,("construct_dev_mode: malloc fail.\n")); - return NULL; - } - - ZERO_STRUCTP(devmode); - - if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum)))) - goto fail; - - if (printer->info_2->devmode) - ntdevmode = dup_nt_devicemode(printer->info_2->devmode); - - if (ntdevmode == NULL) { - DEBUG(5, ("BONG! There was no device mode!\n")); - goto fail; - } - - DEBUGADD(8,("loading DEVICEMODE\n")); - - slprintf(adevice, sizeof(adevice)-1, printer->info_2->printername); - init_unistr(&devmode->devicename, adevice); + if ( !devmode || !ntdevmode ) + return False; + + init_unistr(&devmode->devicename, ntdevmode->devicename); - slprintf(aform, sizeof(aform)-1, ntdevmode->formname); - init_unistr(&devmode->formname, aform); + init_unistr(&devmode->formname, ntdevmode->formname); devmode->specversion = ntdevmode->specversion; devmode->driverversion = ntdevmode->driverversion; @@ -3511,23 +3843,51 @@ DEVICEMODE *construct_dev_mode(int snum) if (ntdevmode->private != NULL) { if ((devmode->private=(uint8 *)memdup(ntdevmode->private, ntdevmode->driverextra)) == NULL) - goto fail; + return False; } + + return True; +} - free_nt_devicemode(&ntdevmode); - free_a_printer(&printer,2); +/**************************************************************************** + Create a DEVMODE struct. Returns malloced memory. +****************************************************************************/ - return devmode; +DEVICEMODE *construct_dev_mode(int snum) +{ + NT_PRINTER_INFO_LEVEL *printer = NULL; + DEVICEMODE *devmode = NULL; + + DEBUG(7,("construct_dev_mode\n")); + + DEBUGADD(8,("getting printer characteristics\n")); - fail: + if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum)))) + return NULL; - if (ntdevmode) - free_nt_devicemode(&ntdevmode); - if (printer) - free_a_printer(&printer,2); - free_dev_mode(devmode); + if ( !printer->info_2->devmode ) { + DEBUG(5, ("BONG! There was no device mode!\n")); + goto done; + } + + if ((devmode = (DEVICEMODE *)malloc(sizeof(DEVICEMODE))) == NULL) { + DEBUG(2,("construct_dev_mode: malloc fail.\n")); + goto done; + } + + ZERO_STRUCTP(devmode); + + DEBUGADD(8,("loading DEVICEMODE\n")); + + if ( !convert_nt_devicemode( devmode, printer->info_2->devmode ) ) { + free_dev_mode( devmode ); + devmode = NULL; + } - return NULL; +done: + free_a_printer(&printer,2); + + return devmode; } /******************************************************************** @@ -4384,7 +4744,7 @@ static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fst * convert an array of ascii string to a UNICODE string ********************************************************************/ -static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *servername) +static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, char *servername) { int i=0; int j=0; @@ -4397,26 +4757,34 @@ static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *ser while (True) { - if (char_array == NULL) + if ( !char_array ) v = ""; - else { + else + { v = char_array[i]; - if (!v) v = ""; /* hack to handle null lists */ + if (!v) + v = ""; /* hack to handle null lists */ } - if ( !strlen(v) ) - break; + /* hack to allow this to be used in places other than when generating + the list of dependent files */ + + if ( servername ) + slprintf( line, sizeof(line)-1, "\\\\%s%s", servername, v ); + else + pstrcpy( line, v ); - slprintf(line, sizeof(line)-1, "\\\\%s%s", servername, v); - DEBUGADD(6,("%d:%s:%d\n", i, line, strlen(line))); - if((tuary=Realloc(*uni_array, (j+strlen(line)+2)*sizeof(uint16))) == NULL) { + if ( (tuary=Realloc(*uni_array, (j+strlen(line)+2)*sizeof(uint16))) == NULL ) { DEBUG(2,("init_unistr_array: Realloc error\n" )); - return; + return 0; } else *uni_array = tuary; + if ( !strlen(v) ) + break; + j += (rpcstr_push((*uni_array+j), line, sizeof(uint16)*strlen(line)+2, STR_TERMINATE) / sizeof(uint16)); i++; } @@ -4426,6 +4794,10 @@ static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *ser } DEBUGADD(6,("last one:done\n")); + + /* return size of array in uint16's */ + + return j+1; } /******************************************************************** @@ -4444,29 +4816,29 @@ static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_IN init_unistr( &info->name, driver.info_3->name ); init_unistr( &info->architecture, driver.info_3->environment ); - if (strlen(driver.info_3->driverpath)) { - slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath); - init_unistr( &info->driverpath, temp ); - } else - init_unistr( &info->driverpath, "" ); + if (strlen(driver.info_3->driverpath)) { + slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath); + init_unistr( &info->driverpath, temp ); + } else + init_unistr( &info->driverpath, "" ); - if (strlen(driver.info_3->datafile)) { - slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile); - init_unistr( &info->datafile, temp ); - } else - init_unistr( &info->datafile, "" ); + if (strlen(driver.info_3->datafile)) { + slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile); + init_unistr( &info->datafile, temp ); + } else + init_unistr( &info->datafile, "" ); - if (strlen(driver.info_3->configfile)) { - slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile); - init_unistr( &info->configfile, temp ); - } else - init_unistr( &info->configfile, "" ); + if (strlen(driver.info_3->configfile)) { + slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile); + init_unistr( &info->configfile, temp ); + } else + init_unistr( &info->configfile, "" ); - if (strlen(driver.info_3->helpfile)) { - slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->helpfile); - init_unistr( &info->helpfile, temp ); - } else - init_unistr( &info->helpfile, "" ); + if (strlen(driver.info_3->helpfile)) { + slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->helpfile); + init_unistr( &info->helpfile, temp ); + } else + init_unistr( &info->helpfile, "" ); init_unistr( &info->monitorname, driver.info_3->monitorname ); init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype ); @@ -4933,10 +5305,6 @@ WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, S * in EMF format. * * So I add checks like in NT Server ... - * - * lkclXXXX jean-francois, i love this kind of thing. oh, well, - * there's a bug in NT client-side code, so we'll fix it in the - * server-side code. *nnnnnggggh!* */ if (info_1->p_datatype != 0) { @@ -4954,7 +5322,7 @@ WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, S unistr2_to_ascii(jobname, &info_1->docname, sizeof(jobname)); - Printer->jobid = print_job_start(&user, snum, jobname); + Printer->jobid = print_job_start(&user, snum, jobname, Printer->nt_devmode); /* An error occured in print_job_start() so return an appropriate NT error code. */ @@ -5004,6 +5372,13 @@ WERROR _spoolss_writeprinter(pipes_struct *p, SPOOL_Q_WRITEPRINTER *q_u, SPOOL_R return WERR_BADFID; (*buffer_written) = print_job_write(snum, Printer->jobid, (char *)buffer, buffer_size); + if (*buffer_written == -1) { + r_u->buffer_written = 0; + if (errno == ENOSPC) + return WERR_NO_SPOOL_SPACE; + else + return WERR_ACCESS_DENIED; + } r_u->buffer_written = q_u->buffer_size2; @@ -5046,11 +5421,13 @@ static WERROR control_printer(POLICY_HND *handle, uint32 command, errcode = WERR_OK; } break; +#if 0 /* JERRY - Never called */ case PRINTER_CONTROL_PURGE: if (print_queue_purge(&user, snum, &errcode)) { errcode = WERR_OK; } break; +#endif default: return WERR_UNKNOWN_LEVEL; } @@ -5060,13 +5437,31 @@ static WERROR control_printer(POLICY_HND *handle, uint32 command, /******************************************************************** * api_spoolss_abortprinter + * From MSDN: "Deletes printer's spool file if printer is configured + * for spooling" ********************************************************************/ WERROR _spoolss_abortprinter(pipes_struct *p, SPOOL_Q_ABORTPRINTER *q_u, SPOOL_R_ABORTPRINTER *r_u) { - POLICY_HND *handle = &q_u->handle; - - return control_printer(handle, PRINTER_CONTROL_PURGE, p); + POLICY_HND *handle = &q_u->handle; + Printer_entry *Printer = find_printer_index_by_hnd(p, handle); + int snum; + struct current_user user; + WERROR errcode = WERR_OK; + + if (!Printer) { + DEBUG(2,("_spoolss_abortprinter: Invalid handle (%s:%u:%u)\n",OUR_HANDLE(handle))); + return WERR_BADFID; + } + + if (!get_printer_snum(p, handle, &snum)) + return WERR_BADFID; + + get_current_user( &user, p ); + + print_job_delete( &user, snum, Printer->jobid, &errcode ); + + return errcode; } /******************************************************************** @@ -5315,22 +5710,6 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level, goto done; } -#if 0 /* JERRY */ - - /* - * Another one of those historical misunderstandings... - * This is reminisent of a similar call we had in _spoolss_setprinterdata() - * I'm leaving it here as a reminder. --jerry - */ - - if (nt_printer_info_level_equal(printer, old_printer)) { - DEBUG(3, ("update_printer: printer info has not changed\n")); - result = WERR_OK; - goto done; - } - -#endif - /* Check calling user has permission to update printer description */ if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) { @@ -5349,49 +5728,22 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level, } /* - * Set the DRIVER_INIT info in the tdb; trigger on magic value for the - * DEVMODE.displayfrequency, which is not used for printer drivers. This - * requires Win32 client code (see other notes elsewhere in the code). + * When a *new* driver is bound to a printer, the drivername is used to + * lookup previously saved driver initialization info, which is then + * bound to the printer, simulating what happens in the Windows arch. */ - if (printer->info_2->devmode && - printer->info_2->devmode->displayfrequency == MAGIC_DISPLAY_FREQUENCY) + if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)) { - - DEBUG(10,("update_printer: Save printer driver init data\n")); - printer->info_2->devmode->displayfrequency = 0; - - if (update_driver_init(*printer, 2)!=0) { - DEBUG(10,("update_printer: error updating printer driver init DEVMODE\n")); - result = WERR_ACCESS_DENIED; - goto done; - } - - /* we need to reset all driver init data for all printers - bound to this driver */ - - srv_spoolss_reset_printerdata( printer->info_2->drivername ); - - } - else - { - /* - * When a *new* driver is bound to a printer, the drivername is used to - * lookup previously saved driver initialization info, which is then - * bound to the printer, simulating what happens in the Windows arch. - */ - if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)) + if (!set_driver_init(printer, 2)) { - if (!set_driver_init(printer, 2)) - { - DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n", - printer->info_2->drivername)); - } - - DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n", + DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n", printer->info_2->drivername)); - - notify_printer_driver(snum, printer->info_2->drivername); } + + DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n", + printer->info_2->drivername)); + + notify_printer_driver(snum, printer->info_2->drivername); } /* Update printer info */ @@ -6594,8 +6946,11 @@ static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_ */ if (!devmode) + { set_driver_init(printer, 2); - else { + } + else + { /* A valid devmode was included, convert and link it */ DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n")); @@ -6605,8 +6960,6 @@ static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_ return WERR_NOMEM; } - set_driver_init(printer, 2); - /* write the ASCII on disk */ err = mod_a_printer(*printer, 2); if (!W_ERROR_IS_OK(err)) { @@ -6905,7 +7258,7 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S uint32 idx = q_u->index; uint32 in_value_len = q_u->valuesize; uint32 in_data_len = q_u->datasize; - uint32 *out_max_value_len= &r_u->valuesize; + uint32 *out_max_value_len = &r_u->valuesize; uint16 **out_value = &r_u->value; uint32 *out_value_len = &r_u->realvaluesize; uint32 *out_type = &r_u->type; @@ -7112,7 +7465,8 @@ WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP * when connecting to a printer --jerry */ - if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) { + if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) + { DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n")); status = WERR_ACCESS_DENIED; goto done; @@ -7122,15 +7476,27 @@ WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP if (!W_ERROR_IS_OK(status)) return status; - /* save the registry data */ - unistr2_to_ascii( valuename, value, sizeof(valuename)-1 ); - delete_printer_data( printer->info_2, SPOOL_PRINTERDATA_KEY, valuename ); - add_printer_data( printer->info_2, SPOOL_PRINTERDATA_KEY, valuename, type, data, real_len ); - - /* write the **entire** printer out to disk.... :-( */ - status = mod_a_printer(*printer, 2); + /* + * When client side code sets a magic printer data key, detect it and save + * the current printer data and the magic key's data (its the DEVMODE) for + * future printer/driver initializations. + */ + if ( (type == REG_BINARY) && strequal( valuename, PHANTOM_DEVMODE_KEY)) + { + /* Set devmode and printer initialization info */ + status = save_driver_init( printer, 2, data, real_len ); + + srv_spoolss_reset_printerdata( printer->info_2->drivername ); + } + else + { + status = set_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename, + type, data, real_len ); + if ( W_ERROR_IS_OK(status) ) + status = mod_a_printer(*printer, 2); + } done: free_a_printer(&printer, 2); @@ -7204,9 +7570,7 @@ WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_ unistr2_to_ascii( valuename, value, sizeof(valuename)-1 ); - status = delete_printer_data( printer->info_2, SPOOL_PRINTERDATA_KEY, valuename ); - if ( NT_STATUS_IS_OK(status) ) - status = mod_a_printer(*printer, 2); + status = delete_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename ); free_a_printer(&printer, 2); @@ -7235,40 +7599,52 @@ WERROR _spoolss_addform( pipes_struct *p, SPOOL_Q_ADDFORM *q_u, SPOOL_R_ADDFORM DEBUG(2,("_spoolss_addform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); return WERR_BADFID; } + + + /* forms can be added on printer of on the print server handle */ + + if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTER ) + { + if (!get_printer_snum(p,handle, &snum)) + return WERR_BADFID; + + status = get_a_printer(&printer, 2, lp_servicename(snum)); + if (!W_ERROR_IS_OK(status)) + goto done; + } - if (!get_printer_snum(p,handle, &snum)) - return WERR_BADFID; - - if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) { + if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) { DEBUG(2,("_spoolss_addform: denied by handle permissions.\n")); status = WERR_ACCESS_DENIED; goto done; } - + /* can't add if builtin */ + if (get_a_builtin_ntform(&form->name,&tmpForm)) { - return WERR_ALREADY_EXISTS; + status = WERR_ALREADY_EXISTS; + goto done; } - count=get_ntforms(&list); - if(!add_a_form(&list, form, &count)) - return WERR_NOMEM; + count = get_ntforms(&list); + + if(!add_a_form(&list, form, &count)) { + status = WERR_NOMEM; + goto done; + } + write_ntforms(&list, count); /* - * ChangeID must always be set + * ChangeID must always be set if this is a printer */ - status = get_a_printer(&printer, 2, lp_servicename(snum)); - if (!W_ERROR_IS_OK(status)) - goto done; - - status = mod_a_printer(*printer, 2); - if (!W_ERROR_IS_OK(status)) - goto done; + if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTER ) + status = mod_a_printer(*printer, 2); done: - free_a_printer(&printer, 2); + if ( printer ) + free_a_printer(&printer, 2); SAFE_FREE(list); return status; @@ -7283,7 +7659,6 @@ WERROR _spoolss_deleteform( pipes_struct *p, SPOOL_Q_DELETEFORM *q_u, SPOOL_R_DE UNISTR2 *form_name = &q_u->name; nt_forms_struct tmpForm; int count=0; - WERROR ret = WERR_OK; nt_forms_struct *list=NULL; Printer_entry *Printer = find_printer_index_by_hnd(p, handle); int snum; @@ -7297,40 +7672,49 @@ WERROR _spoolss_deleteform( pipes_struct *p, SPOOL_Q_DELETEFORM *q_u, SPOOL_R_DE return WERR_BADFID; } - if (!get_printer_snum(p, handle, &snum)) - return WERR_BADFID; + /* forms can be deleted on printer of on the print server handle */ + + if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTER ) + { + if (!get_printer_snum(p,handle, &snum)) + return WERR_BADFID; + + status = get_a_printer(&printer, 2, lp_servicename(snum)); + if (!W_ERROR_IS_OK(status)) + goto done; + } - if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) { - DEBUG(2,("_spoolss_deleteform: denied by handle permissions\n")); - return WERR_ACCESS_DENIED; + if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) { + DEBUG(2,("_spoolss_deleteform: denied by handle permissions.\n")); + status = WERR_ACCESS_DENIED; + goto done; } /* can't delete if builtin */ + if (get_a_builtin_ntform(form_name,&tmpForm)) { - return WERR_INVALID_PARAM; + status = WERR_INVALID_PARAM; + goto done; } count = get_ntforms(&list); - if(!delete_a_form(&list, form_name, &count, &ret)) - return WERR_INVALID_PARAM; + + if ( !delete_a_form(&list, form_name, &count, &status )) + goto done; /* - * ChangeID must always be set + * ChangeID must always be set if this is a printer */ - status = get_a_printer(&printer, 2, lp_servicename(snum)); - if (!W_ERROR_IS_OK(status)) - goto done; - - status = mod_a_printer(*printer, 2); - if (!W_ERROR_IS_OK(status)) - goto done; + if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTER ) + status = mod_a_printer(*printer, 2); done: - free_a_printer(&printer, 2); + if ( printer ) + free_a_printer(&printer, 2); SAFE_FREE(list); - return ret; + return status; } /**************************************************************************** @@ -7356,40 +7740,48 @@ WERROR _spoolss_setform(pipes_struct *p, SPOOL_Q_SETFORM *q_u, SPOOL_R_SETFORM * return WERR_BADFID; } - if (!get_printer_snum(p, handle, &snum)) - return WERR_BADFID; + /* forms can be modified on printer of on the print server handle */ + + if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTER ) + { + if (!get_printer_snum(p,handle, &snum)) + return WERR_BADFID; + + status = get_a_printer(&printer, 2, lp_servicename(snum)); + if (!W_ERROR_IS_OK(status)) + goto done; + } - if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) { + if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) { DEBUG(2,("_spoolss_setform: denied by handle permissions\n")); - return WERR_ACCESS_DENIED; + status = WERR_ACCESS_DENIED; + goto done; } /* can't set if builtin */ if (get_a_builtin_ntform(&form->name,&tmpForm)) { - return WERR_INVALID_PARAM; + status = WERR_INVALID_PARAM; + goto done; } - count=get_ntforms(&list); + count = get_ntforms(&list); update_a_form(&list, form, count); write_ntforms(&list, count); /* - * ChangeID must always be set + * ChangeID must always be set if this is a printer */ - status = get_a_printer(&printer, 2, lp_servicename(snum)); - if (!W_ERROR_IS_OK(status)) - goto done; + if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTER ) + status = mod_a_printer(*printer, 2); - status = mod_a_printer(*printer, 2); - if (!W_ERROR_IS_OK(status)) - goto done; done: - free_a_printer(&printer, 2); + if ( printer ) + free_a_printer(&printer, 2); SAFE_FREE(list); - return WERR_OK; + return status; } /**************************************************************************** @@ -7638,7 +8030,7 @@ static WERROR getjob_level_1(print_queue_struct *queue, int count, int snum, uin return WERR_NOMEM; } - for (i=0; ioffered; uint32 *needed = &r_u->needed; + WERROR wstatus = WERR_OK; int snum; int count; - print_queue_struct *queue=NULL; + print_queue_struct *queue = NULL; print_status_struct prt_status; /* that's an [in out] buffer */ @@ -7764,7 +8172,7 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_ DEBUG(5,("spoolss_getjob\n")); - *needed=0; + *needed = 0; if (!get_printer_snum(p, handle, &snum)) return WERR_BADFID; @@ -7774,19 +8182,29 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_ DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n", count, prt_status.status, prt_status.message)); - switch (level) { + switch ( level ) { case 1: - return getjob_level_1(queue, count, snum, jobid, buffer, offered, needed); + wstatus = getjob_level_1(queue, count, snum, jobid, + buffer, offered, needed); + break; case 2: - return getjob_level_2(queue, count, snum, jobid, buffer, offered, needed); + wstatus = getjob_level_2(queue, count, snum, jobid, + buffer, offered, needed); + break; default: - SAFE_FREE(queue); - return WERR_UNKNOWN_LEVEL; + wstatus = WERR_UNKNOWN_LEVEL; + break; } + + SAFE_FREE(queue); + return wstatus; } /******************************************************************** - * spoolss_getprinterdataex + spoolss_getprinterdataex + + From MSDN documentation of GetPrinterDataEx: pass request + to GetPrinterData if key is "PrinterDriverData". ********************************************************************/ WERROR _spoolss_getprinterdataex(pipes_struct *p, SPOOL_Q_GETPRINTERDATAEX *q_u, SPOOL_R_GETPRINTERDATAEX *r_u) @@ -7797,112 +8215,181 @@ WERROR _spoolss_getprinterdataex(pipes_struct *p, SPOOL_Q_GETPRINTERDATAEX *q_u, uint32 *out_size = &r_u->size; uint8 **data = &r_u->data; uint32 *needed = &r_u->needed; - - fstring key, value; + fstring keyname, valuename; + Printer_entry *Printer = find_printer_index_by_hnd(p, handle); - BOOL found = False; + + NT_PRINTER_INFO_LEVEL *printer = NULL; + int snum = 0; + WERROR status = WERR_OK; DEBUG(4,("_spoolss_getprinterdataex\n")); - unistr2_to_ascii(key, &q_u->keyname, sizeof(key) - 1); - unistr2_to_ascii(value, &q_u->valuename, sizeof(value) - 1); + unistr2_to_ascii(keyname, &q_u->keyname, sizeof(keyname) - 1); + unistr2_to_ascii(valuename, &q_u->valuename, sizeof(valuename) - 1); + + DEBUG(10, ("_spoolss_getprinterdataex: key => [%s], value => [%s]\n", + keyname, valuename)); /* in case of problem, return some default values */ - *needed=0; - *type=0; - *out_size=0; + + *needed = 0; + *type = 0; + *out_size = in_size; - if (!Printer) { - if((*data=(uint8 *)talloc_zero(p->mem_ctx, 4*sizeof(uint8))) == NULL) - return WERR_NOMEM; - DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); - return WERR_BADFID; + DEBUG(2,("_spoolss_getprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); + status = WERR_BADFID; + goto done; } - /* Is the handle to a printer or to the server? */ - if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER) - { + if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER) { DEBUG(10,("_spoolss_getprinterdatex: Not implemented for server handles yet\n")); - return WERR_INVALID_PARAM; + status = WERR_INVALID_PARAM; + goto done; } - else - { - /* - * From MSDN documentation of GetPrinterDataEx: pass request - * to GetPrinterData if key is "PrinterDriverData". This is - * the only key we really support. Other keys to implement: - * (a) DsDriver - * (b) DsSpooler - * (c) PnPData - * (d) DsUser - */ - - if (strcmp(key, SPOOL_PRINTERDATA_KEY) != 0) - return WERR_BADFILE; + + if ( !get_printer_snum(p,handle, &snum) ) + return WERR_BADFID; - DEBUG(10, ("_spoolss_getprinterdataex: pass me to getprinterdata\n")); - found = getprinterdata_printer(p, p->mem_ctx, handle, value, - type, data, needed, in_size); - + status = get_a_printer(&printer, 2, lp_servicename(snum)); + if ( !W_ERROR_IS_OK(status) ) + goto done; + + /* check to see if the keyname is valid */ + if ( !strlen(keyname) ) { + status = WERR_INVALID_PARAM; + goto done; } - - if (!found) { - DEBUG(5, ("value not found, allocating %d\n", *out_size)); + + if ( lookup_printerkey( &printer->info_2->data, keyname ) == -1 ) { + DEBUG(4,("_spoolss_getprinterdataex: Invalid keyname [%s]\n", keyname )); + free_a_printer( &printer, 2 ); + status = WERR_BADFILE; + goto done; + } + + /* When given a new keyname, we should just create it */ + + status = get_printer_dataex( p->mem_ctx, printer, keyname, valuename, type, data, needed, in_size ); + + if (*needed > *out_size) + status = WERR_MORE_DATA; + +done: + if ( !W_ERROR_IS_OK(status) ) + { + DEBUG(5, ("error: allocating %d\n", *out_size)); /* reply this param doesn't exist */ - if (*out_size) { - if((*data=(uint8 *)talloc_zero(p->mem_ctx, *out_size*sizeof(uint8))) == NULL) - return WERR_NOMEM; - } else { + + if ( *out_size ) + { + if( (*data=(uint8 *)talloc_zero(p->mem_ctx, *out_size*sizeof(uint8))) == NULL ) { + status = WERR_NOMEM; + goto done; + } + } + else { *data = NULL; - } - - return WERR_INVALID_PARAM; + } } - if (*needed > *out_size) - return WERR_MORE_DATA; - else - return WERR_OK; + if ( printer ) + free_a_printer( &printer, 2 ); + + return status; } /******************************************************************** - * spoolss_setprinterdata + * spoolss_setprinterdataex ********************************************************************/ WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u, SPOOL_R_SETPRINTERDATAEX *r_u) { - SPOOL_Q_SETPRINTERDATA q_u_local; - SPOOL_R_SETPRINTERDATA r_u_local; - fstring key; + POLICY_HND *handle = &q_u->handle; + uint32 type = q_u->type; + uint8 *data = q_u->data; + uint32 real_len = q_u->real_len; + NT_PRINTER_INFO_LEVEL *printer = NULL; + int snum = 0; + WERROR status = WERR_OK; + Printer_entry *Printer = find_printer_index_by_hnd(p, handle); + fstring valuename; + fstring keyname; + char *oid_string; + DEBUG(4,("_spoolss_setprinterdataex\n")); /* From MSDN documentation of SetPrinterDataEx: pass request to SetPrinterData if key is "PrinterDriverData" */ - unistr2_to_ascii(key, &q_u->key, sizeof(key) - 1); + if (!Printer) { + DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); + return WERR_BADFID; + } - if (strcmp(key, SPOOL_PRINTERDATA_KEY) != 0) - return WERR_INVALID_PARAM; - - ZERO_STRUCT(q_u_local); - ZERO_STRUCT(r_u_local); - - /* make a copy to call _spoolss_setprinterdata() */ - - memcpy(&q_u_local.handle, &q_u->handle, sizeof(POLICY_HND)); - copy_unistr2(&q_u_local.value, &q_u->value); - q_u_local.type = q_u->type; - q_u_local.max_len = q_u->max_len; - q_u_local.data = q_u->data; - q_u_local.real_len = q_u->real_len; - q_u_local.numeric_data = q_u->numeric_data; + if ( !get_printer_snum(p,handle, &snum) ) + return WERR_BADFID; + + /* + * Access check : NT returns "access denied" if you make a + * SetPrinterData call without the necessary privildge. + * we were originally returning OK if nothing changed + * which made Win2k issue **a lot** of SetPrinterData + * when connecting to a printer --jerry + */ + + if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) + { + DEBUG(3, ("_spoolss_setprinterdataex: change denied by handle access permissions\n")); + return WERR_ACCESS_DENIED; + } + + status = get_a_printer(&printer, 2, lp_servicename(snum)); + if (!W_ERROR_IS_OK(status)) + return status; + + unistr2_to_ascii( valuename, &q_u->value, sizeof(valuename) - 1); + unistr2_to_ascii( keyname, &q_u->key, sizeof(keyname) - 1); + + /* check for OID in valuename */ + + if ( (oid_string = strchr( valuename, ',' )) != NULL ) + { + *oid_string = '\0'; + oid_string++; + } + + /* save the registry data */ + + status = set_printer_dataex( printer, keyname, valuename, type, data, real_len ); + + /* save the OID if one was specified and the previous set call succeeded */ + + if ( W_ERROR_IS_OK(status) && oid_string ) + { + + fstrcat( keyname, "\\" ); + fstrcat( keyname, SPOOL_OID_KEY ); - return _spoolss_setprinterdata(p, &q_u_local, &r_u_local); + /* + * I'm not checking the status here on purpose. Don't know + * if this is right, but I'm returning the status from the + * previous set_printer_dataex() call. I have no idea if + * this is right. --jerry + */ + + set_printer_dataex( printer, keyname, valuename, + REG_SZ, (void*)oid_string, strlen(oid_string)+1 ); + } + + free_a_printer(&printer, 2); + + return status; } @@ -7912,26 +8399,44 @@ WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u, WERROR _spoolss_deleteprinterdataex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATAEX *q_u, SPOOL_R_DELETEPRINTERDATAEX *r_u) { - SPOOL_Q_DELETEPRINTERDATA q_u_local; - SPOOL_R_DELETEPRINTERDATA r_u_local; - fstring key; - - /* From MSDN documentation of SetPrinterDataEx: pass request to - SetPrinterData if key is "PrinterDriverData" */ - - unistr2_to_ascii(key, &q_u->keyname, sizeof(key) - 1); + POLICY_HND *handle = &q_u->handle; + UNISTR2 *value = &q_u->valuename; + UNISTR2 *key = &q_u->keyname; - if (strcmp(key, SPOOL_PRINTERDATA_KEY) != 0) - return WERR_INVALID_PARAM; + NT_PRINTER_INFO_LEVEL *printer = NULL; + int snum=0; + WERROR status = WERR_OK; + Printer_entry *Printer=find_printer_index_by_hnd(p, handle); + pstring valuename, keyname; - memcpy(&q_u_local.handle, &q_u->handle, sizeof(POLICY_HND)); - copy_unistr2(&q_u_local.valuename, &q_u->valuename); + DEBUG(5,("spoolss_deleteprinterdataex\n")); - return _spoolss_deleteprinterdata( p, &q_u_local, &r_u_local ); -} + if (!Printer) { + DEBUG(2,("_spoolss_deleteprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); + return WERR_BADFID; + } + + if (!get_printer_snum(p, handle, &snum)) + return WERR_BADFID; + + if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) { + DEBUG(3, ("_spoolss_deleteprinterdataex: printer properties change denied by handle\n")); + return WERR_ACCESS_DENIED; + } + + status = get_a_printer(&printer, 2, lp_servicename(snum)); + if (!W_ERROR_IS_OK(status)) + return status; + + unistr2_to_ascii( valuename, value, sizeof(valuename)-1 ); + unistr2_to_ascii( keyname, key, sizeof(keyname)-1 ); + status = delete_printer_dataex( printer, keyname, valuename ); + free_a_printer(&printer, 2); + return status; +} /******************************************************************** * spoolss_enumprinterkey @@ -7940,73 +8445,69 @@ WERROR _spoolss_deleteprinterdataex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATAEX WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u) { - fstring key; - uint16 *enumkeys = NULL; - char* ptr = NULL; - int i; - int printerkey_len = strlen(SPOOL_PRINTERDATA_KEY)+1; - + fstring key; + fstring *keynames = NULL; + uint16 *enumkeys = NULL; + int num_keys; + int printerkey_len; + POLICY_HND *handle = &q_u->handle; + Printer_entry *Printer = find_printer_index_by_hnd(p, handle); + NT_PRINTER_DATA *data; + NT_PRINTER_INFO_LEVEL *printer = NULL; + int snum = 0; + WERROR status = WERR_BADFILE; + + DEBUG(4,("_spoolss_enumprinterkey\n")); - unistr2_to_ascii( key, &q_u->key, sizeof(key)-1 ); + if (!Printer) { + DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); + return WERR_BADFID; + } - /* - * we only support enumating all keys (key == "") - * Of course, the only key we support is the "PrinterDriverData" - * key - */ + if ( !get_printer_snum(p,handle, &snum) ) + return WERR_BADFID; - if ( !strlen( key ) ) - { - r_u->needed = printerkey_len*2; + status = get_a_printer(&printer, 2, lp_servicename(snum)); + if (!W_ERROR_IS_OK(status)) + return status; - if ( q_u->size < r_u->needed ) - return WERR_MORE_DATA; + /* get the list of subkey names */ - if ( !(enumkeys = talloc( p->mem_ctx, printerkey_len*2 )) ) { - DEBUG(0,("_spoolss_enumprinterkey: talloc() failed for [%d] bytes!\n", - printerkey_len)); - return WERR_NOMEM; - } - - ptr = SPOOL_PRINTERDATA_KEY; - for ( i=0; i<(printerkey_len-1); i++ ) - { - enumkeys[i] = (uint16)(*ptr); - ptr++; - } + unistr2_to_ascii( key, &q_u->key, sizeof(key)-1 ); + data = &printer->info_2->data; - /* tag of '\0's */ - - enumkeys[i] = 0x0; - - if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys)) - return WERR_BADFILE; - - return WERR_OK; + num_keys = get_printer_subkeys( data, key, &keynames ); + + if ( num_keys == -1 ) { + status = WERR_BADFILE; + goto done; } - - /* The "PrinterDriverData" key should have no subkeys */ - if ( strcmp(key, SPOOL_PRINTERDATA_KEY) == 0 ) - { - uint16 dummy_key = 0; - - r_u->needed = 2; - - if (q_u->size < r_u->needed) - return WERR_MORE_DATA; - - if ( !make_spoolss_buffer5(p->mem_ctx, &r_u->keys, 1, &dummy_key ) ) - return WERR_BADFILE; - - return WERR_OK; + + printerkey_len = init_unistr_array( &enumkeys, keynames, NULL ); + + r_u->needed = printerkey_len*2; + + if ( q_u->size < r_u->needed ) { + status = WERR_MORE_DATA; + goto done; } - - /* The return value for an unknown key is documented in MSDN - EnumPrinterKey description */ - - return WERR_BADFILE; + if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys)) { + status = WERR_NOMEM; + goto done; + } + + status = WERR_OK; + + if ( q_u->size < r_u->needed ) + status = WERR_MORE_DATA; + +done: + free_a_printer( &printer, 2 ); + SAFE_FREE( keynames ); + + return status; } /******************************************************************** @@ -8015,25 +8516,49 @@ WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPO WERROR _spoolss_deleteprinterkey(pipes_struct *p, SPOOL_Q_DELETEPRINTERKEY *q_u, SPOOL_R_DELETEPRINTERKEY *r_u) { - Printer_entry *Printer = find_printer_index_by_hnd(p, &q_u->handle); - fstring key; + POLICY_HND *handle = &q_u->handle; + Printer_entry *Printer = find_printer_index_by_hnd(p, &q_u->handle); + fstring key; + NT_PRINTER_INFO_LEVEL *printer = NULL; + int snum=0; + WERROR status; + + DEBUG(5,("spoolss_deleteprinterkey\n")); if (!Printer) { - DEBUG(2,("_spoolss_deleteprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(&q_u->handle))); + DEBUG(2,("_spoolss_deleteprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); return WERR_BADFID; } + + /* if keyname == NULL, return error */ + + if ( !q_u->keyname.buffer ) + return WERR_INVALID_PARAM; + + if (!get_printer_snum(p, handle, &snum)) + return WERR_BADFID; + + if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) { + DEBUG(3, ("_spoolss_deleteprinterkey: printer properties change denied by handle\n")); + return WERR_ACCESS_DENIED; + } + + status = get_a_printer(&printer, 2, lp_servicename(snum)); + if (!W_ERROR_IS_OK(status)) + return status; + + /* delete the key and all subneys */ unistr2_to_ascii(key, &q_u->keyname, sizeof(key) - 1); + + status = delete_all_printer_data( printer->info_2, key ); - if (strcmp(key, SPOOL_PRINTERDATA_KEY) != 0) - return WERR_INVALID_PARAM; - - /* - * this is what 2k returns when you try to delete the "PrinterDriverData" - * key - */ - - return WERR_ACCESS_DENIED; + if ( W_ERROR_IS_OK(status) ) + status = mod_a_printer(*printer, 2); + + free_a_printer( &printer, 2 ); + + return status; } @@ -8068,7 +8593,6 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_ return WERR_BADFID; } - /* first get the printer off of disk */ if (!get_printer_snum(p,handle, &snum)) diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c index 5c1038949b5..69945b50b84 100644 --- a/source3/rpc_server/srv_srvsvc_nt.c +++ b/source3/rpc_server/srv_srvsvc_nt.c @@ -338,10 +338,10 @@ BOOL share_access_check(connection_struct *conn, int snum, user_struct *vuser, u if (!psd) goto out; - if (vuser) - token = vuser->nt_user_token; - else + if (conn->nt_user_token) token = conn->nt_user_token; + else + token = vuser->nt_user_token; ret = se_access_check(psd, token, desired_access, &granted, &status); diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index 194e4981224..ed681606588 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -86,15 +86,8 @@ static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli, printf("forest name is %s\n", forest_name); if (info_class == 12) { - int i; - uint32 *data1 = (uint32 *) dom_guid.info; - uint16 *data2 = (uint16 *) &dom_guid.info[4]; - uint16 *data3 = (uint16 *) &dom_guid.info[6]; - printf("domain GUID is %08x-%04x-%04x", *data1,*data2,*data3); - printf("-%02x%02x-", dom_guid.info[8], dom_guid.info[9]); - for (i=10;irids[j], group->attribs[j]); break; } - case SAM_DELTA_SAM_STAMP: { - SAM_DELTA_STAMP *stamp = &deltas[i].stamp; + case SAM_DELTA_MODIFIED_COUNT: { + SAM_DELTA_MOD_COUNT *mc = &deltas[i].mod_count; - printf("sam sequence update: 0x%04x\n", - stamp->seqnum); + printf("sam sequence update: 0x%04x\n", mc->seqnum); break; } default: @@ -152,6 +151,7 @@ static NTSTATUS cmd_netlogon_sam_sync(struct cli_state *cli, SAM_DELTA_HDR *hdr_deltas; SAM_DELTA_CTR *deltas; DOM_CRED ret_creds; + uint32 neg_flags = 0x000001ff; if (argc > 2) { fprintf(stderr, "Usage: %s [database_id]\n", argv[0]); @@ -174,8 +174,7 @@ static NTSTATUS cmd_netlogon_sam_sync(struct cli_state *cli, goto done; } - result = cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? - SEC_CHAN_WKSTA : SEC_CHAN_BDC, trust_passwd); + result = cli_nt_setup_creds(cli, get_sec_chan(), trust_passwd, &neg_flags, 2); if (!NT_STATUS_IS_OK(result)) { fprintf(stderr, "Error initialising session creds\n"); @@ -188,7 +187,7 @@ static NTSTATUS cmd_netlogon_sam_sync(struct cli_state *cli, /* Synchronise sam database */ result = cli_netlogon_sam_sync(cli, mem_ctx, &ret_creds, database_id, - &num_deltas, &hdr_deltas, &deltas); + 0, &num_deltas, &hdr_deltas, &deltas); if (!NT_STATUS_IS_OK(result)) goto done; @@ -213,6 +212,7 @@ static NTSTATUS cmd_netlogon_sam_deltas(struct cli_state *cli, SAM_DELTA_HDR *hdr_deltas; SAM_DELTA_CTR *deltas; UINT64_S seqnum; + uint32 neg_flags = 0x000001ff; if (argc != 3) { fprintf(stderr, "Usage: %s database_id seqnum\n", argv[0]); @@ -238,8 +238,7 @@ static NTSTATUS cmd_netlogon_sam_deltas(struct cli_state *cli, goto done; } - result = cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? - SEC_CHAN_WKSTA : SEC_CHAN_BDC, trust_passwd); + result = cli_nt_setup_creds(cli, get_sec_chan(), trust_passwd, &neg_flags, 2); if (!NT_STATUS_IS_OK(result)) { fprintf(stderr, "Error initialising session creds\n"); @@ -273,12 +272,15 @@ static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli, NTSTATUS result = NT_STATUS_UNSUCCESSFUL; int logon_type = NET_LOGON_TYPE; char *username, *password; + uint32 neg_flags = 0x000001ff; + int auth_level = 2; /* Check arguments */ - if (argc < 3 || argc > 4) { + if (argc < 3 || argc > 6) { fprintf(stderr, "Usage: samlogon " - "[logon_type]\n"); + "[logon_type] [neg flags] [auth level (2 or 3)]\n" + "neg flags being 0x000001ff or 0x6007ffff\n"); return NT_STATUS_OK; } @@ -288,6 +290,12 @@ static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli, if (argc == 4) sscanf(argv[3], "%i", &logon_type); + if (argc == 5) + sscanf(argv[4], "%i", &neg_flags); + + if (argc == 6) + sscanf(argv[5], "%i", &auth_level); + /* Authenticate ourselves with the domain controller */ if (!secrets_init()) { @@ -295,14 +303,12 @@ static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli, return result; } - if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd, - NULL)) { + if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd, NULL)) { fprintf(stderr, "could not fetch trust account password\n"); goto done; } - result = cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? - SEC_CHAN_WKSTA : SEC_CHAN_BDC, trust_passwd); + result = cli_nt_setup_creds(cli, get_sec_chan(), trust_passwd, &neg_flags, auth_level); if (!NT_STATUS_IS_OK(result)) { fprintf(stderr, "Error initialising session creds\n"); @@ -311,8 +317,7 @@ static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli, /* Perform the sam logon */ - result = cli_netlogon_sam_logon(cli, mem_ctx, username, password, - logon_type); + result = cli_netlogon_sam_logon(cli, mem_ctx, username, password, logon_type); if (!NT_STATUS_IS_OK(result)) goto done; diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index 22e2db41f31..15648e4d1b5 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -313,15 +313,22 @@ static NTSTATUS cmd_spoolss_enum_printers(struct cli_state *cli, uint32 info_level = 1; PRINTER_INFO_CTR ctr; uint32 i = 0, num_printers, needed; + fstring name; - if (argc > 2) + if (argc > 3) { - printf("Usage: %s [level]\n", argv[0]); + printf("Usage: %s [level] [name]\n", argv[0]); return NT_STATUS_OK; } - if (argc == 2) { + if (argc == 2) info_level = atoi(argv[1]); + + if (argc == 3) + fstrcpy(name, argv[2]); + else { + slprintf(name, sizeof(name)-1, "\\\\%s", cli->desthost); + strupper(name); } /* Enumerate printers -- Should we enumerate types other @@ -330,12 +337,12 @@ static NTSTATUS cmd_spoolss_enum_printers(struct cli_state *cli, ZERO_STRUCT(ctr); result = cli_spoolss_enum_printers( - cli, mem_ctx, 0, &needed, PRINTER_ENUM_LOCAL, + cli, mem_ctx, 0, &needed, name, PRINTER_ENUM_LOCAL, info_level, &num_printers, &ctr); if (W_ERROR_V(result) == ERRinsufficientbuffer) result = cli_spoolss_enum_printers( - cli, mem_ctx, needed, NULL, PRINTER_ENUM_LOCAL, + cli, mem_ctx, needed, NULL, name, PRINTER_ENUM_LOCAL, info_level, &num_printers, &ctr); if (W_ERROR_IS_OK(result)) { @@ -1613,7 +1620,8 @@ static NTSTATUS cmd_spoolss_setprinterdata(struct cli_state *cli, POLICY_HND pol; BOOL opened_hnd = False; PRINTER_INFO_CTR ctr; - PRINTER_INFO_0 *info = NULL; + PRINTER_INFO_0 info; + REGISTRY_VALUE value; /* parse the command arguements */ if (argc != 4) { @@ -1635,6 +1643,8 @@ static NTSTATUS cmd_spoolss_setprinterdata(struct cli_state *cli, opened_hnd = True; + ctr.printers_0 = &info; + result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed, &pol, 0, &ctr); @@ -1645,13 +1655,16 @@ static NTSTATUS cmd_spoolss_setprinterdata(struct cli_state *cli, goto done; printf("%s\n", timestring(True)); - printf("\tchange_id (before set)\t:[0x%x]\n", info->change_id); + printf("\tchange_id (before set)\t:[0x%x]\n", info.change_id); /* Set the printer data */ - result = cli_spoolss_setprinterdata( - cli, mem_ctx, &pol, argv[2], REG_SZ, argv[3], - strlen(argv[3]) + 1); + fstrcpy(value.valuename, argv[2]); + value.type = REG_SZ; + value.size = strlen(argv[3]) + 1; + value.data_p = talloc_memdup(mem_ctx, argv[3], value.size); + + result = cli_spoolss_setprinterdata(cli, mem_ctx, &pol, &value); if (!W_ERROR_IS_OK(result)) { printf ("Unable to set [%s=%s]!\n", argv[2], argv[3]); @@ -1668,7 +1681,7 @@ static NTSTATUS cmd_spoolss_setprinterdata(struct cli_state *cli, goto done; printf("%s\n", timestring(True)); - printf("\tchange_id (after set)\t:[0x%x]\n", info->change_id); + printf("\tchange_id (after set)\t:[0x%x]\n", info.change_id); done: /* cleanup */ @@ -1778,10 +1791,10 @@ static NTSTATUS cmd_spoolss_enum_jobs(struct cli_state *cli, for (i = 0; i < num_jobs; i++) { switch(level) { case 1: - display_job_info_1(ctr.job.job_info_1[i]); + display_job_info_1(&ctr.job.job_info_1[i]); break; case 2: - display_job_info_2(ctr.job.job_info_2[i]); + display_job_info_2(&ctr.job.job_info_2[i]); break; default: d_printf("unknown info level %d\n", level); diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 2d86fb1d3d0..880fdc599a8 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -573,24 +573,6 @@ static NTSTATUS process_cmd(struct cli_state *cli, char *cmd) } -/* Print usage information */ -static void usage(void) -{ - printf("Usage: rpcclient [options] server\n"); - - printf("\t-A or --authfile authfile File containing user credentials\n"); - printf("\t-c or --command \"command string\" Execute semicolon separated cmds\n"); - printf("\t-d or --debug debuglevel Set the debuglevel\n"); - printf("\t-l or --logfile logfile Logfile to use instead of stdout\n"); - printf("\t-h or --help Print this help message.\n"); - printf("\t-N or --nopass Don't ask for a password\n"); - printf("\t-s or --conf configfile Specify an alternative config file\n"); - printf("\t-U or --user username Set the network username\n"); - printf("\t-W or --workgroup domain Set the domain name for user account\n"); - printf("\t-I or --dest-ip ip Specify destination IP address\n"); - printf("\n"); -} - /* Main function */ int main(int argc, char *argv[]) @@ -599,7 +581,6 @@ static void usage(void) static int got_pass = 0; BOOL interactive = True; int opt; - int olddebug; static char *cmdstr = ""; const char *server; struct cli_state *cli; @@ -616,41 +597,36 @@ static void usage(void) struct cmd_set **cmd_set; struct in_addr server_ip; NTSTATUS nt_status; - extern BOOL AllowDebugChange; /* make sure the vars that get altered (4th field) are in a fixed location or certain compilers complain */ poptContext pc; struct poptOption long_options[] = { - {"authfile", 'A', POPT_ARG_STRING, &opt_authfile, 'A'}, - {"conf", 's', POPT_ARG_STRING, &opt_configfile, 's'}, - {"nopass", 'N', POPT_ARG_NONE, &got_pass}, - {"user", 'U', POPT_ARG_STRING, &opt_username, 'U'}, - {"workgroup", 'W', POPT_ARG_STRING, &opt_domain, 'W'}, - {"command", 'c', POPT_ARG_STRING, &cmdstr}, - {"logfile", 'l', POPT_ARG_STRING, &opt_logfile, 'l'}, - {"help", 'h', POPT_ARG_NONE, 0, 'h'}, - {"dest-ip", 'I', POPT_ARG_STRING, &opt_ipaddr, 'I'}, + POPT_AUTOHELP + {"authfile", 'A', POPT_ARG_STRING, &opt_authfile, 'A', "File containing user credentials"}, + {"conf", 's', POPT_ARG_STRING, &opt_configfile, 's', "Specify an alternative config file"}, + {"nopass", 'N', POPT_ARG_NONE, &got_pass, 'N', "Don't ask for a password"}, + {"user", 'U', POPT_ARG_STRING, &opt_username, 'U', "Set the network username"}, + {"workgroup", 'W', POPT_ARG_STRING, &opt_domain, 'W', "Set the domain name for user account"}, + {"command", 'c', POPT_ARG_STRING, &cmdstr, 'c', "Execute semicolon separated cmds"}, + {"logfile", 'l', POPT_ARG_STRING, &opt_logfile, 'l', "Logfile to use instead of stdout"}, + {"dest-ip", 'I', POPT_ARG_STRING, &opt_ipaddr, 'I', "Specify destination IP address"}, { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_debug }, { NULL } }; - setlinebuf(stdout); - DEBUGLEVEL = 1; - AllowDebugChange = False; - /* Parse options */ + pc = poptGetContext("rpcclient", argc, (const char **) argv, + long_options, 0); + if (argc == 1) { - usage(); + poptPrintHelp(pc, stderr, 0); return 0; } - pc = poptGetContext("rpcclient", argc, (const char **) argv, - long_options, 0); - while((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case 'A': @@ -686,7 +662,7 @@ static void usage(void) break; } case 'I': - if (!inet_aton(opt_ipaddr, &server_ip)) { + if ( (server_ip.s_addr=inet_addr(opt_ipaddr)) == INADDR_NONE ) { fprintf(stderr, "%s not a valid IP address\n", opt_ipaddr); return 1; @@ -694,11 +670,6 @@ static void usage(void) case 'W': pstrcpy(domain, opt_domain); break; - - case 'h': - default: - usage(); - exit(1); } } @@ -708,7 +679,7 @@ static void usage(void) server = poptGetArg(pc); if (!server || poptGetArg(pc)) { - usage(); + poptPrintHelp(pc, stderr, 0); return 1; } @@ -721,12 +692,9 @@ static void usage(void) reopen_logs(); /* Load smb.conf file */ - /* FIXME! How to get this DEBUGLEVEL to last over lp_load()? */ - olddebug = DEBUGLEVEL; - if (!lp_load(dyn_CONFIGFILE,True,False,False)) { + + if (!lp_load(dyn_CONFIGFILE,True,False,False)) fprintf(stderr, "Can't load %s\n", dyn_CONFIGFILE); - } - DEBUGLEVEL = olddebug; load_interfaces(); diff --git a/source3/rpcclient/samsync.c b/source3/rpcclient/samsync.c index 3694eb47dfa..7124f9416ad 100644 --- a/source3/rpcclient/samsync.c +++ b/source3/rpcclient/samsync.c @@ -217,8 +217,8 @@ static void decode_sam_deltas(uint32 num_deltas, SAM_DELTA_HDR *hdr_deltas, SAM_ decode_sam_als_mem_info(a); break; } - case SAM_DELTA_DOM_INFO: { - SAM_DELTA_DOM *a; + case SAM_DELTA_POLICY_INFO: { + SAM_DELTA_POLICY *a; a = &deltas[i].dom_info; decode_sam_dom_info(a); break; @@ -324,15 +324,15 @@ static void sam_account_from_delta(SAM_ACCOUNT *account, static void apply_account_info(SAM_ACCOUNT_INFO *sam_acct_delta) { - SAM_ACCOUNT sam_acct; + SAM_ACCOUNT *sam_acct; BOOL result; - ZERO_STRUCT(sam_acct); - - pdb_init_sam(&sam_acct); + if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_acct))) { + return; + } - sam_account_from_delta(&sam_acct, sam_acct_delta); - result = pdb_add_sam_account(&sam_acct); + sam_account_from_delta(sam_acct, sam_acct_delta); + result = pdb_add_sam_account(sam_acct); } /* Apply an array of deltas to the SAM database */ @@ -362,6 +362,7 @@ static NTSTATUS sam_sync(struct cli_state *cli, unsigned char trust_passwd[16], uint32 num_deltas_0, num_deltas_2; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; struct pdb_context *in; + uint32 neg_flags = 0x000001ff; DOM_CRED ret_creds; @@ -384,7 +385,7 @@ static NTSTATUS sam_sync(struct cli_state *cli, unsigned char trust_passwd[16], /* Request a challenge */ - if (!NT_STATUS_IS_OK(cli_nt_setup_creds(cli, SEC_CHAN_BDC, trust_passwd))) { + if (!NT_STATUS_IS_OK(cli_nt_setup_creds(cli, SEC_CHAN_BDC, trust_passwd, &neg_flags, 2))) { DEBUG(0, ("Error initialising session creds\n")); goto done; } @@ -394,13 +395,16 @@ static NTSTATUS sam_sync(struct cli_state *cli, unsigned char trust_passwd[16], /* Do sam synchronisation on the SAM database*/ - result = cli_netlogon_sam_sync(cli, mem_ctx, &ret_creds, 0, + result = cli_netlogon_sam_sync(cli, mem_ctx, &ret_creds, 0, 0, &num_deltas_0, &hdr_deltas_0, &deltas_0); if (!NT_STATUS_IS_OK(result)) goto done; + + /* Update sam */ + apply_deltas(num_deltas_0, hdr_deltas_0, deltas_0); @@ -412,7 +416,7 @@ static NTSTATUS sam_sync(struct cli_state *cli, unsigned char trust_passwd[16], #if 1 /* Do sam synchronisation on the LSA database */ - result = cli_netlogon_sam_sync(cli, mem_ctx, &ret_creds, 2, &num_deltas_2, &hdr_deltas_2, &deltas_2); + result = cli_netlogon_sam_sync(cli, mem_ctx, &ret_creds, 2, 0, &num_deltas_2, &hdr_deltas_2, &deltas_2); if (!NT_STATUS_IS_OK(result)) goto done; @@ -466,8 +470,6 @@ static NTSTATUS sam_sync(struct cli_state *cli, unsigned char trust_passwd[16], goto done; } - /* Update sam tdb */ - done: cli_nt_session_close(cli); talloc_destroy(mem_ctx); @@ -543,7 +545,7 @@ static void user_callback(poptContext con, const struct poptOption *opt, const char *arg, const void *data) { - char *p, *ch; + const char *p, *ch; if (!arg) return; diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 6623c6df646..9d411711cb9 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -531,13 +531,33 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); } /**************************************************************************** - Return True if the blocking lock queue has entries. + Return the number of seconds to the next blocking locks timeout, or default_timeout *****************************************************************************/ - -BOOL blocking_locks_pending(void) +unsigned blocking_locks_timeout(unsigned default_timeout) { - blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); - return (blr == NULL ? False : True); + unsigned timeout = default_timeout; + time_t t; + blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst(&blocking_lock_queue); + + /* note that we avoid the time() syscall if there are no blocking locks */ + if (!blr) { + return timeout; + } + + t = time(NULL); + + while (blr) { + if (timeout > (blr->expire_time - t)) { + timeout = blr->expire_time - t; + } + blr = (blocking_lock_record *)ubi_slNext(blr); + } + + if (timeout < 1) { + timeout = 1; + } + + return timeout; } /**************************************************************************** @@ -576,7 +596,7 @@ void process_blocking_lock_queue(time_t t) DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n", fsp->fnum, fsp->fsp_name )); - if((blr->expire_time != -1) && (blr->expire_time > t)) { + if((blr->expire_time != -1) && (blr->expire_time <= t)) { /* * Lock expired - throw away all previously * obtained locks and return lock error. @@ -584,7 +604,7 @@ void process_blocking_lock_queue(time_t t) DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n", fsp->fnum, fsp->fsp_name )); - blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); + blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); continue; diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c index d70e50f8995..22407348e82 100644 --- a/source3/smbd/conn.c +++ b/source3/smbd/conn.c @@ -131,7 +131,7 @@ void conn_close_all(void) connection_struct *conn, *next; for (conn=Connections;conn;conn=next) { next=conn->next; - close_cnum(conn, (uint16)-1); + close_cnum(conn, conn->vuid); } } @@ -157,6 +157,27 @@ BOOL conn_idle_all(time_t t, int deadtime) return allidle; } +/**************************************************************************** +clear a vuid out of the validity cache, and as the 'owner' of a connection. +****************************************************************************/ +void conn_clear_vuid_cache(uint16 vuid) +{ + connection_struct *conn; + int i; + + for (conn=Connections;conn;conn=conn->next) { + if (conn->vuid == vuid) { + conn->vuid = UID_FIELD_INVALID; + } + + for (i=0;ivuid_cache.entries && i< VUID_CACHE_SIZE;i++) { + if (conn->vuid_cache.list[i] == vuid) { + conn->vuid_cache.list[i] = UID_FIELD_INVALID; + } + } + } +} + /**************************************************************************** Free a conn structure. ****************************************************************************/ @@ -191,7 +212,6 @@ void conn_free(connection_struct *conn) conn->ngroups = 0; } - delete_nt_token(&conn->nt_user_token); free_namearray(conn->veto_list); free_namearray(conn->hide_list); free_namearray(conn->veto_oplock_list); diff --git a/source3/smbd/connection.c b/source3/smbd/connection.c index 5609c2963d8..ad394a01ca0 100644 --- a/source3/smbd/connection.c +++ b/source3/smbd/connection.c @@ -28,14 +28,24 @@ static TDB_CONTEXT *tdb; TDB_CONTEXT *conn_tdb_ctx(void) { - if (!tdb) { + if (!tdb) tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, O_RDWR | O_CREAT, 0644); - } return tdb; } +static void make_conn_key(connection_struct *conn,char *name, TDB_DATA *pkbuf, struct connections_key *pkey) +{ + ZERO_STRUCTP(pkey); + pkey->pid = sys_getpid(); + pkey->cnum = conn?conn->cnum:-1; + fstrcpy(pkey->name, name); + + pkbuf->dptr = (char *)pkey; + pkbuf->dsize = sizeof(*pkey); +} + /**************************************************************************** Delete a connection record. ****************************************************************************/ @@ -45,17 +55,12 @@ BOOL yield_connection(connection_struct *conn,char *name) struct connections_key key; TDB_DATA kbuf; - if (!tdb) return False; + if (!tdb) + return False; DEBUG(3,("Yielding connection to %s\n",name)); - ZERO_STRUCT(key); - key.pid = sys_getpid(); - key.cnum = conn?conn->cnum:-1; - fstrcpy(key.name, name); - - kbuf.dptr = (char *)&key; - kbuf.dsize = sizeof(key); + make_conn_key(conn, name, &kbuf, &key); if (tdb_delete(tdb, kbuf) != 0) { int dbg_lvl = (!conn && (tdb_error(tdb) == TDB_ERR_NOEXIST)) ? 3 : 0; @@ -88,7 +93,7 @@ static int count_fn( TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *u memcpy(&crec, dbuf.dptr, sizeof(crec)); - if (crec.cnum == -1) + if (crec.cnum == -1) return 0; /* If the pid was not found delete the entry from connections.tdb */ @@ -111,16 +116,16 @@ static int count_fn( TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *u Claim an entry in the connections database. ****************************************************************************/ -BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOOL Clear) +BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOOL Clear, uint32 msg_flags) { struct connections_key key; struct connections_data crec; TDB_DATA kbuf, dbuf; - if (!tdb) { + if (!tdb) tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, O_RDWR | O_CREAT, 0644); - } + if (!tdb) return False; @@ -156,13 +161,7 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO DEBUG(5,("claiming %s %d\n",name,max_connections)); - ZERO_STRUCT(key); - key.pid = sys_getpid(); - key.cnum = conn?conn->cnum:-1; - fstrcpy(key.name, name); - - kbuf.dptr = (char *)&key; - kbuf.dsize = sizeof(key); + make_conn_key(conn, name, &kbuf, &key); /* fill in the crec */ ZERO_STRUCT(crec); @@ -176,6 +175,7 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO lp_servicename(SNUM(conn)),sizeof(crec.name)-1); } crec.start = time(NULL); + crec.bcast_msg_flags = msg_flags; StrnCpy(crec.machine,get_remote_machine_name(),sizeof(crec.machine)-1); StrnCpy(crec.addr,conn?conn->client_address:client_addr(),sizeof(crec.addr)-1); @@ -191,3 +191,45 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO return True; } + +BOOL register_message_flags(BOOL doreg, uint32 msg_flags) +{ + struct connections_key key; + struct connections_data *pcrec; + TDB_DATA kbuf, dbuf; + + if (!tdb) + return False; + + DEBUG(10,("register_message_flags: %s flags 0x%x\n", + doreg ? "adding" : "removing", + (unsigned int)msg_flags )); + + make_conn_key(NULL, "", &kbuf, &key); + + dbuf = tdb_fetch(tdb, kbuf); + if (!dbuf.dptr) { + DEBUG(0,("register_message_flags: tdb_fetch failed\n")); + return False; + } + + pcrec = (struct connections_data *)dbuf.dptr; + pcrec->bcast_msg_flags = msg_flags; + if (doreg) + pcrec->bcast_msg_flags |= msg_flags; + else + pcrec->bcast_msg_flags &= ~msg_flags; + + if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) { + DEBUG(0,("register_message_flags: tdb_store failed with error %s.\n", + tdb_errorstr(tdb) )); + SAFE_FREE(dbuf.dptr); + return False; + } + + DEBUG(10,("register_message_flags: new flags 0x%x\n", + (unsigned int)pcrec->bcast_msg_flags )); + + SAFE_FREE(dbuf.dptr); + return True; +} diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 1a18476b75b..396ecd98c49 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -553,9 +553,24 @@ void *dptr_fetch_lanman2(int dptr_num) BOOL dir_check_ftype(connection_struct *conn,int mode,SMB_STRUCT_STAT *st,int dirtype) { - if (((mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0) - return False; - return True; + int mask; + + /* Check the "may have" search bits. */ + if (((mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0) + return False; + + /* Check the "must have" bits, which are the may have bits shifted eight */ + /* If must have bit is set, the file/dir can not be returned in search unless the matching + file attribute is set */ + mask = ((dirtype >> 8) & (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM)); /* & 0x37 */ + if(mask) { + if((mask & (mode & (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM))) == mask) /* check if matching attribute present */ + return True; + else + return False; + } + + return True; } static BOOL mangle_mask_match(connection_struct *conn, char *filename, char *mask) @@ -663,18 +678,15 @@ typedef struct char *current; } Dir; - - /******************************************************************* -check to see if a user can read a file. This is only approximate, -it is used as part of the "hide unreadable" option. Don't -use it for anything security sensitive + Check to see if a user can read a file. This is only approximate, + it is used as part of the "hide unreadable" option. Don't + use it for anything security sensitive. ********************************************************************/ -static BOOL user_can_read_file(connection_struct *conn, char *name) +static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst) { extern struct current_user current_user; - SMB_STRUCT_STAT ste; SEC_DESC *psd = NULL; size_t sd_size; files_struct *fsp; @@ -683,8 +695,6 @@ static BOOL user_can_read_file(connection_struct *conn, char *name) NTSTATUS status; uint32 access_granted; - ZERO_STRUCT(ste); - /* * If user is a member of the Admin group * we never hide files from them. @@ -694,16 +704,16 @@ static BOOL user_can_read_file(connection_struct *conn, char *name) return True; /* If we can't stat it does not show it */ - if (vfs_stat(conn, name, &ste) != 0) + if (!VALID_STAT(*pst) && (vfs_stat(conn, name, pst) != 0)) return False; /* Pseudo-open the file (note - no fd's created). */ - if(S_ISDIR(ste.st_mode)) - fsp = open_directory(conn, name, &ste, 0, SET_DENY_MODE(DENY_NONE), (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), + if(S_ISDIR(pst->st_mode)) + fsp = open_directory(conn, name, pst, 0, SET_DENY_MODE(DENY_NONE), (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), unix_mode(conn,aRONLY|aDIR, name), &smb_action); else - fsp = open_file_shared1(conn, name, &ste, FILE_READ_ATTRIBUTES, SET_DENY_MODE(DENY_NONE), + fsp = open_file_shared1(conn, name, pst, FILE_READ_ATTRIBUTES, SET_DENY_MODE(DENY_NONE), (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action); if (!fsp) @@ -722,16 +732,15 @@ static BOOL user_can_read_file(connection_struct *conn, char *name) } /******************************************************************* -check to see if a user can write a file (and only files, we do not -check dirs on this one). This is only approximate, -it is used as part of the "hide unwriteable" option. Don't -use it for anything security sensitive + Check to see if a user can write a file (and only files, we do not + check dirs on this one). This is only approximate, + it is used as part of the "hide unwriteable" option. Don't + use it for anything security sensitive. ********************************************************************/ -static BOOL user_can_write_file(connection_struct *conn, char *name) +static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst) { extern struct current_user current_user; - SMB_STRUCT_STAT ste; SEC_DESC *psd = NULL; size_t sd_size; files_struct *fsp; @@ -740,8 +749,6 @@ static BOOL user_can_write_file(connection_struct *conn, char *name) NTSTATUS status; uint32 access_granted; - ZERO_STRUCT(ste); - /* * If user is a member of the Admin group * we never hide files from them. @@ -751,15 +758,15 @@ static BOOL user_can_write_file(connection_struct *conn, char *name) return True; /* If we can't stat it does not show it */ - if (vfs_stat(conn, name, &ste) != 0) + if (!VALID_STAT(*pst) && (vfs_stat(conn, name, pst) != 0)) return False; /* Pseudo-open the file (note - no fd's created). */ - if(S_ISDIR(ste.st_mode)) + if(S_ISDIR(pst->st_mode)) return True; else - fsp = open_file_shared1(conn, name, &ste, FILE_WRITE_ATTRIBUTES, SET_DENY_MODE(DENY_NONE), + fsp = open_file_shared1(conn, name, pst, FILE_WRITE_ATTRIBUTES, SET_DENY_MODE(DENY_NONE), (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action); if (!fsp) @@ -777,6 +784,30 @@ static BOOL user_can_write_file(connection_struct *conn, char *name) &access_granted, &status); } +/******************************************************************* + Is a file a "special" type ? +********************************************************************/ + +static BOOL file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst) +{ + /* + * If user is a member of the Admin group + * we never hide files from them. + */ + + if (conn->admin_user) + return True; + + /* If we can't stat it does not show it */ + if (!VALID_STAT(*pst) && (vfs_stat(conn, name, pst) != 0)) + return True; + + if (S_ISREG(pst->st_mode) || S_ISDIR(pst->st_mode) || S_ISLNK(pst->st_mode)) + return False; + + return True; +} + /******************************************************************* Open a directory. ********************************************************************/ @@ -802,6 +833,8 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) while (True) { int l; BOOL normal_entry = True; + SMB_STRUCT_STAT st; + char *entry = NULL; if (used == 0) { n = "."; @@ -818,6 +851,7 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) normal_entry = True; } + ZERO_STRUCT(st); l = strlen(n)+1; /* If it's a vetoed file, pretend it doesn't even exist */ @@ -826,30 +860,45 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) /* Honour _hide unreadable_ option */ if (normal_entry && conn && lp_hideunreadable(SNUM(conn))) { - char *entry; int ret=0; - if (asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) { - ret = user_can_read_file(conn, entry); - SAFE_FREE(entry); + if (entry || asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) { + ret = user_can_read_file(conn, entry, &st); } - if (!ret) + if (!ret) { + SAFE_FREE(entry); continue; + } } /* Honour _hide unwriteable_ option */ if (normal_entry && conn && lp_hideunwriteable_files(SNUM(conn))) { - char *entry; int ret=0; - if (asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) { - ret = user_can_write_file(conn, entry); + if (entry || asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) { + ret = user_can_write_file(conn, entry, &st); + } + if (!ret) { SAFE_FREE(entry); + continue; + } + } + + /* Honour _hide_special_ option */ + if (normal_entry && conn && lp_hide_special_files(SNUM(conn))) { + int ret=0; + + if (entry || asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) { + ret = file_is_special(conn, entry, &st); } - if (!ret) + if (ret) { + SAFE_FREE(entry); continue; + } } + SAFE_FREE(entry); + if (used + l > dirp->mallocsize) { int s = MAX(used+l,used+2000); char *r; diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index ce98af4ace5..d343db26f6b 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -168,7 +168,7 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen pstrcpy(orig_path, name); - if(stat_cache_lookup(conn, name, dirpath, &start, &st)) { + if(!case_sensitive && stat_cache_lookup(conn, name, dirpath, &start, &st)) { *pst = st; return True; } diff --git a/source3/smbd/mangle_hash.c b/source3/smbd/mangle_hash.c index 1d4697474ce..0446a953ff5 100644 --- a/source3/smbd/mangle_hash.c +++ b/source3/smbd/mangle_hash.c @@ -730,7 +730,7 @@ static void name_map(char *OutName, BOOL need83, BOOL cache83) DEBUG(5,("name_map( %s, need83 = %s, cache83 = %s)\n", OutName, need83 ? "True" : "False", cache83 ? "True" : "False")); - if (push_ucs2_allocate((void **)&OutName_ucs2, OutName) < 0) { + if (push_ucs2_allocate(&OutName_ucs2, OutName) < 0) { DEBUG(0, ("push_ucs2_allocate failed!\n")); return; } diff --git a/source3/smbd/mangle_hash2.c b/source3/smbd/mangle_hash2.c index 6b53cc72aa4..a0a3d51139d 100644 --- a/source3/smbd/mangle_hash2.c +++ b/source3/smbd/mangle_hash2.c @@ -200,7 +200,7 @@ static BOOL is_mangled_component(const char *name) { int len, i; - M_DEBUG(0,("is_mangled_component %s ?\n", name)); + M_DEBUG(10,("is_mangled_component %s ?\n", name)); /* check the length */ len = strlen(name); @@ -234,7 +234,7 @@ static BOOL is_mangled_component(const char *name) } } - M_DEBUG(0,("is_mangled %s -> yes\n", name)); + M_DEBUG(10,("is_mangled %s -> yes\n", name)); return True; } @@ -257,7 +257,7 @@ static BOOL is_mangled(const char *name) const char *p; const char *s; - M_DEBUG(0,("is_mangled %s ?\n", name)); + M_DEBUG(10,("is_mangled %s ?\n", name)); for (s=name; (p=strchr(s, '/')); s=p+1) { char *component = strndup(s, PTR_DIFF(p, s)); @@ -367,7 +367,7 @@ static BOOL check_cache(char *name) /* make sure that this is a mangled name from this cache */ if (!is_mangled(name)) { - M_DEBUG(0,("check_cache: %s -> not mangled\n", name)); + M_DEBUG(10,("check_cache: %s -> not mangled\n", name)); return False; } @@ -382,7 +382,7 @@ static BOOL check_cache(char *name) /* now look in the prefix cache for that hash */ prefix = cache_lookup(hash); if (!prefix) { - M_DEBUG(0,("check_cache: %s -> %08X -> not found\n", name, hash)); + M_DEBUG(10,("check_cache: %s -> %08X -> not found\n", name, hash)); return False; } @@ -395,10 +395,10 @@ static BOOL check_cache(char *name) } if (extension[0]) { - M_DEBUG(0,("check_cache: %s -> %s.%s\n", name, prefix, extension)); + M_DEBUG(10,("check_cache: %s -> %s.%s\n", name, prefix, extension)); slprintf(name, sizeof(fstring), "%s.%s", prefix, extension); } else { - M_DEBUG(0,("check_cache: %s -> %s\n", name, prefix)); + M_DEBUG(10,("check_cache: %s -> %s\n", name, prefix)); fstrcpy(name, prefix); } @@ -573,7 +573,7 @@ static void name_map(char *name, BOOL need83, BOOL cache83) cache_insert(name, prefix_len, hash); } - M_DEBUG(0,("name_map: %s -> %08X -> %s (cache=%d)\n", + M_DEBUG(10,("name_map: %s -> %08X -> %s (cache=%d)\n", name, hash, new_name, cache83)); /* and overwrite the old name */ diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c index 2be04fd6860..16427b00d70 100644 --- a/source3/smbd/negprot.c +++ b/source3/smbd/negprot.c @@ -170,9 +170,9 @@ static int negprot_spnego(char *p) DATA_BLOB blob; extern pstring global_myname; uint8 guid[16]; - const char *OIDs_krb5[] = {OID_NTLMSSP, - OID_KERBEROS5, + const char *OIDs_krb5[] = {OID_KERBEROS5, OID_KERBEROS5_OLD, + OID_NTLMSSP, NULL}; const char *OIDs_plain[] = {OID_NTLMSSP, NULL}; char *principal; @@ -199,9 +199,7 @@ static int negprot_spnego(char *p) if (lp_security() != SEC_ADS) { blob = spnego_gen_negTokenInit(guid, OIDs_plain, "NONE"); } else { - /* win2000 uses host$@REALM, which we will probably use eventually, - but for now this works */ - asprintf(&principal, "HOST/%s@%s", guid, lp_realm()); + asprintf(&principal, "%s$@%s", guid, lp_realm()); blob = spnego_gen_negTokenInit(guid, OIDs_krb5, principal); free(principal); } @@ -239,7 +237,11 @@ static int reply_nt1(char *inbuf, char *outbuf) capabilities |= CAP_EXTENDED_SECURITY; } - capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNIX; + capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS; + + if (lp_unix_extensions()) { + capabilities |= CAP_UNIX; + } if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64)) capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS; diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index cf69dfddb04..1f3bbd488e5 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -371,7 +371,7 @@ static int map_share_mode( char *fname, uint32 create_options, if (smb_open_mode == -1) { - if(*desired_access & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS| + if(*desired_access & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS| FILE_EXECUTE|FILE_READ_ATTRIBUTES| FILE_READ_EA|FILE_WRITE_EA|SYSTEM_SECURITY_ACCESS| FILE_WRITE_ATTRIBUTES|READ_CONTROL_ACCESS)) { @@ -548,6 +548,7 @@ int reply_ntcreate_and_X(connection_struct *conn, uint32 create_disposition = IVAL(inbuf,smb_ntcreate_CreateDisposition); uint32 create_options = IVAL(inbuf,smb_ntcreate_CreateOptions); uint16 root_dir_fid = (uint16)IVAL(inbuf,smb_ntcreate_RootDirectoryFid); + SMB_OFF_T allocation_size = 0; int smb_ofun; int smb_open_mode; int smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK); @@ -563,8 +564,16 @@ int reply_ntcreate_and_X(connection_struct *conn, files_struct *fsp=NULL; char *p = NULL; time_t c_time; + BOOL extended_oplock_granted = False; + START_PROFILE(SMBntcreateX); + DEBUG(10,("reply_ntcreateX: flags = 0x%x, desired_access = 0x%x \ +file_attributes = 0x%x, share_access = 0x%x, create_disposition = 0x%x \ +create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attributes, + share_access, create_disposition, + create_options, root_dir_fid )); + /* If it's an IPC, use the pipe handler. */ if (IS_IPC(conn)) { @@ -573,10 +582,14 @@ int reply_ntcreate_and_X(connection_struct *conn, return do_ntcreate_pipe_open(conn,inbuf,outbuf,length,bufsize); } else { END_PROFILE(SMBntcreateX); - return(ERROR_DOS(ERRDOS,ERRbadaccess)); + return(ERROR_DOS(ERRDOS,ERRnoaccess)); } } + if (create_options & FILE_OPEN_BY_FILE_ID) { + END_PROFILE(SMBntcreateX); + return ERROR_NT(NT_STATUS_NOT_SUPPORTED); + } /* * We need to construct the open_and_X ofun value from the @@ -585,7 +598,7 @@ int reply_ntcreate_and_X(connection_struct *conn, if((smb_ofun = map_create_disposition( create_disposition )) == -1) { END_PROFILE(SMBntcreateX); - return(ERROR_DOS(ERRDOS,ERRbadaccess)); + return(ERROR_DOS(ERRDOS,ERRnoaccess)); } /* @@ -660,7 +673,7 @@ int reply_ntcreate_and_X(connection_struct *conn, share_access, file_attributes)) == -1) { END_PROFILE(SMBntcreateX); - return ERROR_DOS(ERRDOS,ERRbadaccess); + return ERROR_DOS(ERRDOS,ERRnoaccess); } oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0; @@ -689,6 +702,12 @@ int reply_ntcreate_and_X(connection_struct *conn, if(create_options & FILE_DIRECTORY_FILE) { oplock_request = 0; + /* Can't open a temp directory. IFS kit test. */ + if (file_attributes & FILE_ATTRIBUTE_TEMPORARY) { + END_PROFILE(SMBntcreateX); + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } + fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, unixmode, &smb_action); restore_case_semantics(file_attributes); @@ -787,6 +806,22 @@ int reply_ntcreate_and_X(connection_struct *conn, return ERROR_DOS(ERRDOS,ERRnoaccess); } + /* Save the requested allocation size. */ + allocation_size = IVAL(inbuf,smb_ntcreate_AllocationSize); +#ifdef LARGE_SMB_OFF_T + allocation_size |= (((SMB_OFF_T)IVAL(inbuf,smb_ntcreate_AllocationSize + 4)) << 32); +#endif + if (allocation_size && (allocation_size > file_len)) { + fsp->initial_allocation_size = SMB_ROUNDUP(allocation_size,SMB_ROUNDUP_ALLOCATION_SIZE); + if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) { + close_file(fsp,False); + END_PROFILE(SMBntcreateX); + return ERROR_NT(NT_STATUS_DISK_FULL); + } + } else { + fsp->initial_allocation_size = SMB_ROUNDUP(file_len,SMB_ROUNDUP_ALLOCATION_SIZE); + } + /* * If the caller set the extended oplock request bit * and we granted one (by whatever means) - set the @@ -794,10 +829,10 @@ int reply_ntcreate_and_X(connection_struct *conn, */ if (oplock_request && lp_fake_oplocks(SNUM(conn))) - smb_action |= EXTENDED_OPLOCK_GRANTED; + extended_oplock_granted = True; if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) - smb_action |= EXTENDED_OPLOCK_GRANTED; + extended_oplock_granted = True; #if 0 /* W2K sends back 42 words here ! If we do the same it breaks offline sync. Go figure... ? JRA. */ @@ -813,7 +848,7 @@ int reply_ntcreate_and_X(connection_struct *conn, * exclusive & batch here. */ - if (smb_action & EXTENDED_OPLOCK_GRANTED) { + if (extended_oplock_granted) { if (flags & REQUEST_BATCH_OPLOCK) { SCVAL(p,0, BATCH_OPLOCK_RETURN); } else { @@ -828,7 +863,10 @@ int reply_ntcreate_and_X(connection_struct *conn, p++; SSVAL(p,0,fsp->fnum); p += 2; - SIVAL(p,0,smb_action); + if ((create_disposition == FILE_SUPERSEDE) && (smb_action == FILE_WAS_OVERWRITTEN)) + SIVAL(p,0,FILE_WAS_SUPERSEDED); + else + SIVAL(p,0,smb_action); p += 4; /* Create time. */ @@ -851,7 +889,7 @@ int reply_ntcreate_and_X(connection_struct *conn, p += 8; SIVAL(p,0,fmode); /* File Attributes. */ p += 4; - SOFF_T(p, 0, get_allocation_size(&sbuf)); + SOFF_T(p, 0, get_allocation_size(fsp,&sbuf)); p += 8; SOFF_T(p,0,file_len); p += 12; @@ -886,7 +924,7 @@ static int do_nt_transact_create_pipe( connection_struct *conn, if(total_parameter_count < 54) { DEBUG(0,("do_nt_transact_create_pipe - insufficient parameters (%u)\n", (unsigned int)total_parameter_count)); - return ERROR_DOS(ERRDOS,ERRbadaccess); + return ERROR_DOS(ERRDOS,ERRnoaccess); } srvstr_pull(inbuf, fname, params+53, sizeof(fname), total_parameter_count-53, STR_TERMINATE); @@ -1018,6 +1056,7 @@ static int call_nt_transact_create(connection_struct *conn, BOOL bad_path = False; files_struct *fsp = NULL; char *p = NULL; + BOOL extended_oplock_granted = False; uint32 flags; uint32 desired_access; uint32 file_attributes; @@ -1026,6 +1065,7 @@ static int call_nt_transact_create(connection_struct *conn, uint32 create_options; uint32 sd_len; uint16 root_dir_fid; + SMB_OFF_T allocation_size = 0; int smb_ofun; int smb_open_mode; int smb_attr; @@ -1043,7 +1083,7 @@ static int call_nt_transact_create(connection_struct *conn, return do_nt_transact_create_pipe(conn, inbuf, outbuf, length, bufsize, ppsetup, ppparams, ppdata); else - return ERROR_DOS(ERRDOS,ERRbadaccess); + return ERROR_DOS(ERRDOS,ERRnoaccess); } /* @@ -1052,7 +1092,7 @@ static int call_nt_transact_create(connection_struct *conn, if(total_parameter_count < 54) { DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)total_parameter_count)); - return ERROR_DOS(ERRDOS,ERRbadaccess); + return ERROR_DOS(ERRDOS,ERRnoaccess); } flags = IVAL(params,0); @@ -1065,6 +1105,11 @@ static int call_nt_transact_create(connection_struct *conn, root_dir_fid = (uint16)IVAL(params,4); smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK); + if (create_options & FILE_OPEN_BY_FILE_ID) { + END_PROFILE(SMBntcreateX); + return ERROR_NT(NT_STATUS_NOT_SUPPORTED); + } + /* * We need to construct the open_and_X ofun value from the * NT values, as that's what our code is structured to accept. @@ -1138,7 +1183,7 @@ static int call_nt_transact_create(connection_struct *conn, if((smb_open_mode = map_share_mode( fname, create_options, &desired_access, share_access, file_attributes)) == -1) - return ERROR_DOS(ERRDOS,ERRbadaccess); + return ERROR_DOS(ERRDOS,ERRnoaccess); oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0; oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0; @@ -1161,6 +1206,12 @@ static int call_nt_transact_create(connection_struct *conn, if(create_options & FILE_DIRECTORY_FILE) { + /* Can't open a temp directory. IFS kit test. */ + if (file_attributes & FILE_ATTRIBUTE_TEMPORARY) { + END_PROFILE(SMBntcreateX); + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } + oplock_request = 0; /* @@ -1234,10 +1285,10 @@ static int call_nt_transact_create(connection_struct *conn, */ if (oplock_request && lp_fake_oplocks(SNUM(conn))) - smb_action |= EXTENDED_OPLOCK_GRANTED; + extended_oplock_granted = True; if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) - smb_action |= EXTENDED_OPLOCK_GRANTED; + extended_oplock_granted = True; } /* @@ -1252,6 +1303,22 @@ static int call_nt_transact_create(connection_struct *conn, restore_case_semantics(file_attributes); + /* Save the requested allocation size. */ + allocation_size = IVAL(params,12); +#ifdef LARGE_SMB_OFF_T + allocation_size |= (((SMB_OFF_T)IVAL(params,16)) << 32); +#endif + if (allocation_size && (allocation_size > file_len)) { + fsp->initial_allocation_size = SMB_ROUNDUP(allocation_size,SMB_ROUNDUP_ALLOCATION_SIZE); + if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) { + close_file(fsp,False); + END_PROFILE(SMBntcreateX); + return ERROR_NT(NT_STATUS_DISK_FULL); + } + } else { + fsp->initial_allocation_size = SMB_ROUNDUP(file_len,SMB_ROUNDUP_ALLOCATION_SIZE); + } + /* Realloc the size of parameters and data we will return */ params = Realloc(*ppparams, 69); if(params == NULL) @@ -1262,7 +1329,7 @@ static int call_nt_transact_create(connection_struct *conn, memset((char *)params,'\0',69); p = params; - if (smb_action & EXTENDED_OPLOCK_GRANTED) + if (extended_oplock_granted) SCVAL(p,0, BATCH_OPLOCK_RETURN); else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) SCVAL(p,0, LEVEL_II_OPLOCK_RETURN); @@ -1272,7 +1339,10 @@ static int call_nt_transact_create(connection_struct *conn, p += 2; SSVAL(p,0,fsp->fnum); p += 2; - SIVAL(p,0,smb_action); + if ((create_disposition == FILE_SUPERSEDE) && (smb_action == FILE_WAS_OVERWRITTEN)) + SIVAL(p,0,FILE_WAS_SUPERSEDED); + else + SIVAL(p,0,smb_action); p += 8; /* Create time. */ @@ -1295,7 +1365,7 @@ static int call_nt_transact_create(connection_struct *conn, p += 8; SIVAL(p,0,fmode); /* File Attributes. */ p += 4; - SOFF_T(p, 0, get_allocation_size(&sbuf)); + SOFF_T(p, 0, get_allocation_size(fsp,&sbuf)); p += 8; SOFF_T(p,0,file_len); @@ -1582,7 +1652,7 @@ static int call_nt_transact_set_security_desc(connection_struct *conn, (unsigned int)security_info_sent )); if (total_data_count == 0) - return ERROR_DOS(ERRDOS, ERRbadaccess); + return ERROR_DOS(ERRDOS, ERRnoaccess); if (!NT_STATUS_IS_OK(nt_status = set_sd( fsp, data, total_data_count, security_info_sent))) return ERROR_NT(nt_status); diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 8c6e8ed805c..a95793a0505 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -139,18 +139,31 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn, * as we always opened files read-write in that release. JRA. */ - if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) + if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) { + DEBUG(10,("open_file: truncate requested on read-only open for file %s\n",fname )); local_flags = (flags & ~O_ACCMODE)|O_RDWR; + } - /* - * We can't actually truncate here as the file may be locked. - * open_file_shared will take care of the truncate later. JRA. - */ + if ((desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) || + (local_flags & O_CREAT) || ((local_flags & O_TRUNC) == O_TRUNC) ) { - local_flags &= ~O_TRUNC; + /* + * We can't actually truncate here as the file may be locked. + * open_file_shared will take care of the truncate later. JRA. + */ - if ((desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) || - (local_flags & O_CREAT)) { + local_flags &= ~O_TRUNC; + +#if defined(O_NONBLOCK) && defined(S_ISFIFO) + /* + * We would block on opening a FIFO with no one else on the + * other end. Do what we used to do and add O_NONBLOCK to the + * open flags. JRA. + */ + + if (VALID_STAT(*psbuf) && S_ISFIFO(psbuf->st_mode)) + local_flags |= O_NONBLOCK; +#endif /* actually do the open */ fsp->fd = fd_open(conn, fname, local_flags, mode); @@ -679,6 +692,31 @@ static void kernel_flock(files_struct *fsp, int deny_mode) } +static BOOL open_match_attributes(connection_struct *conn, char *path, mode_t existing_mode, mode_t new_mode) +{ + uint32 old_dos_mode, new_dos_mode; + SMB_STRUCT_STAT sbuf; + + ZERO_STRUCT(sbuf); + + sbuf.st_mode = existing_mode; + old_dos_mode = dos_mode(conn, path, &sbuf); + + sbuf.st_mode = new_mode; + new_dos_mode = dos_mode(conn, path, &sbuf); + + /* If we're mapping SYSTEM and HIDDEN ensure they match. */ + if (lp_map_system(SNUM(conn))) { + if ((old_dos_mode & FILE_ATTRIBUTE_SYSTEM) != (new_dos_mode & FILE_ATTRIBUTE_SYSTEM)) + return False; + } + if (lp_map_hidden(SNUM(conn))) { + if ((old_dos_mode & FILE_ATTRIBUTE_HIDDEN) != (new_dos_mode & FILE_ATTRIBUTE_HIDDEN)) + return False; + } + return True; +} + /**************************************************************************** Open a file with a share mode. On output from this open we are guarenteeing that @@ -773,6 +811,17 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_ if (CAN_WRITE(conn) && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE)) flags2 |= O_TRUNC; + /* We only care about matching attributes on file exists and truncate. */ + if (file_existed && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE)) { + if (!open_match_attributes(conn, fname, psbuf->st_mode, mode)) { + DEBUG(5,("open_file_shared: attributes missmatch for file %s (0%o, 0%o)\n", + fname, psbuf->st_mode, mode )); + file_free(fsp); + errno = EACCES; + return NULL; + } + } + if (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL) flags2 |= O_EXCL; diff --git a/source3/smbd/password.c b/source3/smbd/password.c index cfac7cf695f..f2956237dd2 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -69,6 +69,10 @@ void invalidate_vuid(uint16 vuid) DLIST_REMOVE(validated_users, vuser); + /* clear the vuid from the 'cache' on each connection, and + from the vuid 'owner' of connections */ + conn_clear_vuid_cache(vuid); + SAFE_FREE(vuser->groups); delete_nt_token(&vuser->nt_user_token); SAFE_FREE(vuser); @@ -89,95 +93,6 @@ void invalidate_all_vuids(void) } } -/**************************************************************************** - Create the SID list for this user. -****************************************************************************/ - -NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, BOOL is_guest, NT_USER_TOKEN *sup_tok) -{ - extern DOM_SID global_sid_World; - extern DOM_SID global_sid_Network; - extern DOM_SID global_sid_Builtin_Guests; - extern DOM_SID global_sid_Authenticated_Users; - NT_USER_TOKEN *token; - DOM_SID *psids; - int i, psid_ndx = 0; - size_t num_sids = 0; - fstring sid_str; - - if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) - return NULL; - - ZERO_STRUCTP(token); - - /* We always have uid/gid plus World and Network and Authenticated Users or Guest SIDs. */ - num_sids = 5 + ngroups; - - if (sup_tok && sup_tok->num_sids) - num_sids += sup_tok->num_sids; - - if ((token->user_sids = (DOM_SID *)malloc( num_sids*sizeof(DOM_SID))) == NULL) { - SAFE_FREE(token); - return NULL; - } - - psids = token->user_sids; - - /* - * Note - user SID *MUST* be first in token ! - * se_access_check depends on this. - */ - - uid_to_sid( &psids[PRIMARY_USER_SID_INDEX], uid); - psid_ndx++; - - /* - * Primary group SID is second in token. Convention. - */ - - gid_to_sid( &psids[PRIMARY_GROUP_SID_INDEX], gid); - psid_ndx++; - - /* Now add the group SIDs. */ - - for (i = 0; i < ngroups; i++) { - if (groups[i] != gid) { - gid_to_sid( &psids[psid_ndx++], groups[i]); - } - } - - if (sup_tok) { - /* Now add the additional SIDs from the supplimentary token. */ - for (i = 0; i < sup_tok->num_sids; i++) - sid_copy( &psids[psid_ndx++], &sup_tok->user_sids[i] ); - } - - /* - * Finally add the "standard" SIDs. - * The only difference between guest and "anonymous" (which we - * don't really support) is the addition of Authenticated_Users. - */ - - sid_copy( &psids[psid_ndx++], &global_sid_World); - sid_copy( &psids[psid_ndx++], &global_sid_Network); - - if (is_guest) - sid_copy( &psids[psid_ndx++], &global_sid_Builtin_Guests); - else - sid_copy( &psids[psid_ndx++], &global_sid_Authenticated_Users); - - token->num_sids = psid_ndx; - - /* Dump list of sids in token */ - - for (i = 0; i < token->num_sids; i++) { - DEBUG(5, ("user token sid %s\n", - sid_to_string(sid_str, &token->user_sids[i]))); - } - - return token; -} - /**************************************************************************** register a uid/name pair as being valid and that a valid password has been given. vuid is biased by an offset. This allows us to @@ -187,8 +102,6 @@ tell random client vuid's (normally zero) from valid vuids. int register_vuid(auth_serversupplied_info *server_info, const char *smb_name) { user_struct *vuser = NULL; - uid_t uid; - gid_t gid; /* Ensure no vuid gets registered in share level security. */ if(lp_security() == SEC_SHARE) @@ -205,15 +118,6 @@ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name) ZERO_STRUCTP(vuser); - if (!IS_SAM_UNIX_USER(server_info->sam_account)) { - DEBUG(0,("Attempted session setup with invalid user. No uid/gid in SAM_ACCOUNT (flags:%x)\n", pdb_get_init_flag(server_info->sam_account))); - free(vuser); - return UID_FIELD_INVALID; - } - - uid = pdb_get_uid(server_info->sam_account); - gid = pdb_get_gid(server_info->sam_account); - /* Allocate a free vuid. Yes this is a linear search... :-) */ while( get_valid_user_struct(next_vuid) != NULL ) { next_vuid++; @@ -225,18 +129,38 @@ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name) DEBUG(10,("register_vuid: allocated vuid = %u\n", (unsigned int)next_vuid )); vuser->vuid = next_vuid; - vuser->uid = uid; - vuser->gid = gid; + + /* the next functions should be done by a SID mapping system (SMS) as + * the new real sam db won't have reference to unix uids or gids + */ + if (!IS_SAM_UNIX_USER(server_info->sam_account)) { + DEBUG(0,("Attempted session setup with invalid user. No uid/gid in SAM_ACCOUNT (flags:%x)\n", pdb_get_init_flag(server_info->sam_account))); + free(vuser); + return UID_FIELD_INVALID; + } + + vuser->uid = pdb_get_uid(server_info->sam_account); + vuser->gid = pdb_get_gid(server_info->sam_account); + + vuser->n_groups = server_info->n_groups; + if (vuser->n_groups) { + if (!(vuser->groups = memdup(server_info->groups, sizeof(gid_t) * vuser->n_groups))) { + DEBUG(0,("register_vuid: failed to memdup vuser->groups\n")); + free(vuser); + return UID_FIELD_INVALID; + } + } + vuser->guest = server_info->guest; - fstrcpy(vuser->user.unix_name, pdb_get_username(server_info->sam_account)); - fstrcpy(vuser->user.smb_name, smb_name); + fstrcpy(vuser->user.unix_name, pdb_get_username(server_info->sam_account)); + fstrcpy(vuser->user.smb_name, smb_name); fstrcpy(vuser->user.domain, pdb_get_domain(server_info->sam_account)); fstrcpy(vuser->user.full_name, pdb_get_fullname(server_info->sam_account)); { /* Keep the homedir handy */ const char *homedir = pdb_get_homedir(server_info->sam_account); - const char *unix_homedir = pdb_get_unix_homedir(server_info->sam_account); + const char *unix_homedir = pdb_get_unix_homedir(server_info->sam_account); /* should be optained by SMS */ const char *logon_script = pdb_get_logon_script(server_info->sam_account); if (homedir) { vuser->homedir = smb_xstrdup(homedir); @@ -260,19 +184,13 @@ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name) DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,vuser->user.full_name)); - vuser->n_groups = 0; - vuser->groups = NULL; - - /* Find all the groups this uid is in and store them. - Used by change_to_user() */ - initialise_groups(vuser->user.unix_name, vuser->uid, vuser->gid); - get_current_groups(vuser->gid, &vuser->n_groups, &vuser->groups); - - if (server_info->ptok) - add_supplementary_nt_login_groups(&vuser->n_groups, &vuser->groups, &server_info->ptok); - - /* Create an NT_USER_TOKEN struct for this user. */ - vuser->nt_user_token = create_nt_token(vuser->uid, vuser->gid, vuser->n_groups, vuser->groups, vuser->guest, server_info->ptok); + if (server_info->ptok) { + vuser->nt_user_token = dup_nt_token(server_info->ptok); + } else { + DEBUG(1, ("server_info does not contain a user_token - cannot continue\n")); + free(vuser); + return UID_FIELD_INVALID; + } DEBUG(3,("UNIX uid %d is UNIX user %s, and will be vuid %u\n",(int)vuser->uid,vuser->user.unix_name, vuser->vuid)); @@ -306,9 +224,11 @@ add a name to the session users list void add_session_user(const char *user) { fstring suser; - StrnCpy(suser,user,sizeof(suser)-1); + struct passwd *passwd; + + if (!(passwd = Get_Pwnam(user))) return; - if (!Get_Pwnam_Modify(suser)) return; + StrnCpy(suser,passwd->pw_name,sizeof(suser)-1); if (suser && *suser && !in_list(suser,session_users,False)) { @@ -451,7 +371,7 @@ static char *validate_group(char *group, DATA_BLOB password,int snum) Note this is *NOT* used when logging on using sessionsetup_and_X. ****************************************************************************/ -BOOL authorise_login(int snum,char *user, DATA_BLOB password, +BOOL authorise_login(int snum, fstring user, DATA_BLOB password, BOOL *guest) { BOOL ok = False; diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 043e33e8367..e6ae1c7d799 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -1881,6 +1881,8 @@ static int nt_ace_comp( SEC_ACE *a1, SEC_ACE *a2) size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc) { + extern DOM_SID global_sid_Builtin_Administrators; + extern DOM_SID global_sid_Builtin_Users; connection_struct *conn = fsp->conn; SMB_STRUCT_STAT sbuf; SEC_ACE *nt_ace_list = NULL; @@ -1895,6 +1897,7 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc) SMB_ACL_T dir_acl = NULL; canon_ace *file_ace = NULL; canon_ace *dir_ace = NULL; + size_t num_profile_acls = 0; *ppdesc = NULL; @@ -1939,7 +1942,14 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc) * Get the owner, group and world SIDs. */ - create_file_sids(&sbuf, &owner_sid, &group_sid); + if (lp_profile_acls(SNUM(fsp->conn))) { + /* For WXP SP1 the owner must be administrators. */ + sid_copy(&owner_sid, &global_sid_Builtin_Administrators); + sid_copy(&group_sid, &global_sid_Builtin_Users); + num_profile_acls = 2; + } else { + create_file_sids(&sbuf, &owner_sid, &group_sid); + } /* Create the canon_ace lists. */ file_ace = canonicalise_acl( fsp, posix_acl, &sbuf, &owner_sid, &group_sid); @@ -1963,7 +1973,7 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc) } /* Allocate the ace list. */ - if ((nt_ace_list = (SEC_ACE *)malloc((num_acls + num_dir_acls)* sizeof(SEC_ACE))) == NULL) { + if ((nt_ace_list = (SEC_ACE *)malloc((num_acls + num_profile_acls + num_dir_acls)* sizeof(SEC_ACE))) == NULL) { DEBUG(0,("get_nt_acl: Unable to malloc space for nt_ace_list.\n")); goto done; } @@ -1986,6 +1996,13 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc) init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc, 0); } + /* The User must have access to a profile share - even if we can't map the SID. */ + if (lp_profile_acls(SNUM(fsp->conn))) { + SEC_ACCESS acc; + init_sec_access(&acc,FILE_GENERIC_ALL); + init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, acc, 0); + } + ace = dir_ace; for (i = 0; i < num_dir_acls; i++, ace = ace->next) { @@ -1994,6 +2011,15 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc) SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY); } + /* The User must have access to a profile share - even if we can't map the SID. */ + if (lp_profile_acls(SNUM(fsp->conn))) { + SEC_ACCESS acc; + init_sec_access(&acc,FILE_GENERIC_ALL); + init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, acc, + SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT| + SEC_ACE_FLAG_INHERIT_ONLY); + } + /* * Sort to force deny entries to the front. */ diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 55234ec896e..0f7cfd0e9cb 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -42,8 +42,8 @@ extern int last_message; extern int global_oplock_break; extern userdom_struct current_user_info; extern int smb_read_error; -SIG_ATOMIC_T reload_after_sighup; -SIG_ATOMIC_T got_sig_term; +SIG_ATOMIC_T reload_after_sighup = 0; +SIG_ATOMIC_T got_sig_term = 0; extern BOOL global_machine_password_needs_changing; extern fstring global_myworkgroup; extern pstring global_myname; @@ -609,8 +609,9 @@ const static struct smb_message_struct }; /******************************************************************* -dump a prs to a file - ********************************************************************/ + Dump a packet to a file. +********************************************************************/ + static void smb_dump(const char *name, int type, char *data, ssize_t len) { int fd, i; @@ -635,178 +636,171 @@ static void smb_dump(const char *name, int type, char *data, ssize_t len) /**************************************************************************** -do a switch on the message type, and return the response size + Do a switch on the message type, and return the response size ****************************************************************************/ + static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize) { - static pid_t pid= (pid_t)-1; - int outsize = 0; - extern uint16 global_smbpid; - - type &= 0xff; + static pid_t pid= (pid_t)-1; + int outsize = 0; + extern uint16 global_smbpid; - if (pid == (pid_t)-1) - pid = sys_getpid(); + type &= 0xff; - errno = 0; - last_message = type; - - /* make sure this is an SMB packet */ - if (strncmp(smb_base(inbuf),"\377SMB",4) != 0) - { - DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf))); - return(-1); - } + if (pid == (pid_t)-1) + pid = sys_getpid(); - /* yuck! this is an interim measure before we get rid of our - current inbuf/outbuf system */ - global_smbpid = SVAL(inbuf,smb_pid); + errno = 0; + last_message = type; - if (smb_messages[type].fn == NULL) - { - DEBUG(0,("Unknown message type %d!\n",type)); - smb_dump("Unknown", 1, inbuf, size); - outsize = reply_unknown(inbuf,outbuf); - } - else - { - int flags = smb_messages[type].flags; - static uint16 last_session_tag = UID_FIELD_INVALID; - /* In share mode security we must ignore the vuid. */ - uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid); - connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); + /* Make sure this is an SMB packet. smb_size contains NetBIOS header so subtract 4 from it. */ + if ((strncmp(smb_base(inbuf),"\377SMB",4) != 0) || (size < (smb_size - 4))) { + DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",smb_len(inbuf))); + exit_server("Non-SMB packet"); + return(-1); + } - DEBUG(3,("switch message %s (pid %d)\n",smb_fn_name(type),(int)pid)); + /* yuck! this is an interim measure before we get rid of our + current inbuf/outbuf system */ + global_smbpid = SVAL(inbuf,smb_pid); + + if (smb_messages[type].fn == NULL) { + DEBUG(0,("Unknown message type %d!\n",type)); + smb_dump("Unknown", 1, inbuf, size); + outsize = reply_unknown(inbuf,outbuf); + } else { + int flags = smb_messages[type].flags; + static uint16 last_session_tag = UID_FIELD_INVALID; + /* In share mode security we must ignore the vuid. */ + uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid); + connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); + + DEBUG(3,("switch message %s (pid %d)\n",smb_fn_name(type),(int)pid)); + + smb_dump(smb_fn_name(type), 1, inbuf, size); + if(global_oplock_break) { + if(flags & QUEUE_IN_OPLOCK) { + /* + * Queue this message as we are the process of an oplock break. + */ + + DEBUG( 2, ( "switch_message: queueing message due to being in " ) ); + DEBUGADD( 2, ( "oplock break state.\n" ) ); + + push_oplock_pending_smb_message( inbuf, size ); + return -1; + } + } - smb_dump(smb_fn_name(type), 1, inbuf, size); - if(global_oplock_break) - { - if(flags & QUEUE_IN_OPLOCK) - { - /* - * Queue this message as we are the process of an oplock break. - */ - - DEBUG( 2, ( "switch_message: queueing message due to being in " ) ); - DEBUGADD( 2, ( "oplock break state.\n" ) ); - - push_oplock_pending_smb_message( inbuf, size ); - return -1; - } - } + /* Ensure this value is replaced in the incoming packet. */ + SSVAL(inbuf,smb_uid,session_tag); - /* Ensure this value is replaced in the incoming packet. */ - SSVAL(inbuf,smb_uid,session_tag); + /* + * Ensure the correct username is in current_user_info. + * This is a really ugly bugfix for problems with + * multiple session_setup_and_X's being done and + * allowing %U and %G substitutions to work correctly. + * There is a reason this code is done here, don't + * move it unless you know what you're doing... :-). + * JRA. + */ - /* - * Ensure the correct username is in current_user_info. - * This is a really ugly bugfix for problems with - * multiple session_setup_and_X's being done and - * allowing %U and %G substitutions to work correctly. - * There is a reason this code is done here, don't - * move it unless you know what you're doing... :-). - * JRA. - */ + if (session_tag != last_session_tag) { + user_struct *vuser = NULL; - if (session_tag != last_session_tag) { - user_struct *vuser = NULL; + last_session_tag = session_tag; + if(session_tag != UID_FIELD_INVALID) + vuser = get_valid_user_struct(session_tag); + if(vuser != NULL) + current_user_info = vuser->user; + } - last_session_tag = session_tag; - if(session_tag != UID_FIELD_INVALID) - vuser = get_valid_user_struct(session_tag); - if(vuser != NULL) - current_user_info = vuser->user; - } + /* does this protocol need to be run as root? */ + if (!(flags & AS_USER)) + change_to_root_user(); - /* does this protocol need to be run as root? */ - if (!(flags & AS_USER)) - change_to_root_user(); + /* does this protocol need a valid tree connection? */ + if ((flags & AS_USER) && !conn) + return ERROR_DOS(ERRSRV, ERRinvnid); - /* does this protocol need a valid tree connection? */ - if ((flags & AS_USER) && !conn) { - return ERROR_DOS(ERRSRV, ERRinvnid); - } + /* does this protocol need to be run as the connected user? */ + if ((flags & AS_USER) && !change_to_user(conn,session_tag)) { + if (flags & AS_GUEST) + flags &= ~AS_USER; + else + return(ERROR_DOS(ERRSRV,ERRaccess)); + } - /* does this protocol need to be run as the connected user? */ - if ((flags & AS_USER) && !change_to_user(conn,session_tag)) { - if (flags & AS_GUEST) - flags &= ~AS_USER; - else - return(ERROR_DOS(ERRSRV,ERRaccess)); - } - - /* this code is to work around a bug is MS client 3 without - introducing a security hole - it needs to be able to do - print queue checks as guest if it isn't logged in properly */ - if (flags & AS_USER) - flags &= ~AS_GUEST; + /* this code is to work around a bug is MS client 3 without + introducing a security hole - it needs to be able to do + print queue checks as guest if it isn't logged in properly */ + if (flags & AS_USER) + flags &= ~AS_GUEST; - /* does it need write permission? */ - if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) - return(ERROR_DOS(ERRSRV,ERRaccess)); + /* does it need write permission? */ + if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) + return(ERROR_DOS(ERRSRV,ERRaccess)); - /* ipc services are limited */ - if (IS_IPC(conn) && (flags & AS_USER) && !(flags & CAN_IPC)) { - return(ERROR_DOS(ERRSRV,ERRaccess)); - } + /* ipc services are limited */ + if (IS_IPC(conn) && (flags & AS_USER) && !(flags & CAN_IPC)) + return(ERROR_DOS(ERRSRV,ERRaccess)); - /* load service specific parameters */ - if (conn && !set_current_service(conn,(flags & AS_USER)?True:False)) { - return(ERROR_DOS(ERRSRV,ERRaccess)); - } + /* load service specific parameters */ + if (conn && !set_current_service(conn,(flags & AS_USER)?True:False)) + return(ERROR_DOS(ERRSRV,ERRaccess)); - /* does this protocol need to be run as guest? */ - if ((flags & AS_GUEST) && - (!change_to_guest() || - !check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1)))) { - return(ERROR_DOS(ERRSRV,ERRaccess)); - } + /* does this protocol need to be run as guest? */ + if ((flags & AS_GUEST) && (!change_to_guest() || + !check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1)))) + return(ERROR_DOS(ERRSRV,ERRaccess)); - last_inbuf = inbuf; + last_inbuf = inbuf; - outsize = smb_messages[type].fn(conn, inbuf,outbuf,size,bufsize); - } + outsize = smb_messages[type].fn(conn, inbuf,outbuf,size,bufsize); + } - smb_dump(smb_fn_name(type), 0, outbuf, outsize); + smb_dump(smb_fn_name(type), 0, outbuf, outsize); - return(outsize); + return(outsize); } /**************************************************************************** - construct a reply to the incoming packet + Construct a reply to the incoming packet. ****************************************************************************/ + static int construct_reply(char *inbuf,char *outbuf,int size,int bufsize) { - int type = CVAL(inbuf,smb_com); - int outsize = 0; - int msg_type = CVAL(inbuf,0); + int type = CVAL(inbuf,smb_com); + int outsize = 0; + int msg_type = CVAL(inbuf,0); - GetTimeOfDay(&smb_last_time); + GetTimeOfDay(&smb_last_time); - chain_size = 0; - file_chain_reset(); - reset_chain_p(); + chain_size = 0; + file_chain_reset(); + reset_chain_p(); - if (msg_type != 0) - return(reply_special(inbuf,outbuf)); + if (msg_type != 0) + return(reply_special(inbuf,outbuf)); - construct_reply_common(inbuf, outbuf); + construct_reply_common(inbuf, outbuf); - outsize = switch_message(type,inbuf,outbuf,size,bufsize); + outsize = switch_message(type,inbuf,outbuf,size,bufsize); - outsize += chain_size; + outsize += chain_size; - if(outsize > 4) - smb_setlen(outbuf,outsize - 4); - return(outsize); + if(outsize > 4) + smb_setlen(outbuf,outsize - 4); + return(outsize); } /**************************************************************************** - Keep track of the number of running smbd's. This functionality is used to - 'hard' limit Samba overhead on resource constrained systems. + Keep track of the number of running smbd's. This functionality is used to + 'hard' limit Samba overhead on resource constrained systems. ****************************************************************************/ + static BOOL smbd_process_limit(void) { int32 total_smbds; @@ -1032,16 +1026,15 @@ static int setup_select_timeout(void) int select_timeout; int t; - /* - * Increase the select timeout back to SMBD_SELECT_TIMEOUT if we - * have removed any blocking locks. JRA. - */ - - select_timeout = blocking_locks_pending() ? SMBD_SELECT_TIMEOUT_WITH_PENDING_LOCKS*1000 : - SMBD_SELECT_TIMEOUT*1000; + select_timeout = blocking_locks_timeout(SMBD_SELECT_TIMEOUT); + select_timeout *= 1000; t = change_notify_timeout(); - if (t != -1) select_timeout = MIN(select_timeout, t*1000); + if (t != -1) + select_timeout = MIN(select_timeout, t*1000); + + if (print_notify_messages_pending()) + select_timeout = MIN(select_timeout, 1000); return select_timeout; } @@ -1161,9 +1154,16 @@ static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_t * First, open the machine password file with an exclusive lock. */ + if (secrets_lock_trust_account_password(global_myworkgroup, True) == False) { + DEBUG(0,("process: unable to lock the machine account password for \ +machine %s in domain %s.\n", global_myname, global_myworkgroup )); + return True; + } + if(!secrets_fetch_trust_account_password(global_myworkgroup, trust_passwd_hash, &lct)) { DEBUG(0,("process: unable to read the machine account password for \ machine %s in domain %s.\n", global_myname, global_myworkgroup )); + secrets_lock_trust_account_password(global_myworkgroup, False); return True; } @@ -1173,6 +1173,7 @@ machine %s in domain %s.\n", global_myname, global_myworkgroup )); if(t < lct + lp_machine_password_timeout()) { global_machine_password_needs_changing = False; + secrets_lock_trust_account_password(global_myworkgroup, False); return True; } @@ -1180,6 +1181,7 @@ machine %s in domain %s.\n", global_myname, global_myworkgroup )); change_trust_account_password( global_myworkgroup, remote_machine_list); global_machine_password_needs_changing = False; + secrets_lock_trust_account_password(global_myworkgroup, False); } /* @@ -1201,6 +1203,10 @@ machine %s in domain %s.\n", global_myname, global_myworkgroup )); force_check_log_size(); check_log_size(); + /* Send any queued printer notify message to interested smbd's. */ + + print_notify_send_messages(); + /* * Modify the select timeout depending upon * what we have remaining in our queues. diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index c6a082d7d89..a881e135c08 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -23,7 +23,6 @@ makes to handle specific protocols */ - #include "includes.h" /* look in server.c for some explanation of these variables */ @@ -40,9 +39,8 @@ unsigned int smb_echo_count = 0; extern BOOL global_encrypted_passwords_negotiated; - /**************************************************************************** - reply to an special message + Reply to an special message. ****************************************************************************/ int reply_special(char *inbuf,char *outbuf) @@ -113,7 +111,7 @@ int reply_special(char *inbuf,char *outbuf) reload_services(True); reopen_logs(); - claim_connection(NULL,"",MAXSTATUS,True); + claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD); already_got_session = True; break; @@ -141,7 +139,6 @@ int reply_special(char *inbuf,char *outbuf) return(outsize); } - /**************************************************************************** Reply to a tcon. ****************************************************************************/ @@ -307,10 +304,10 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt return chain_reply(inbuf,outbuf,length,bufsize); } - /**************************************************************************** - reply to an unknown type + Reply to an unknown type. ****************************************************************************/ + int reply_unknown(char *inbuf,char *outbuf) { int type; @@ -322,10 +319,10 @@ int reply_unknown(char *inbuf,char *outbuf) return(ERROR_DOS(ERRSRV,ERRunknownsmb)); } - /**************************************************************************** - reply to an ioctl + Reply to an ioctl. ****************************************************************************/ + int reply_ioctl(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { @@ -339,8 +336,7 @@ int reply_ioctl(connection_struct *conn, DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code)); - switch (ioctl_code) - { + switch (ioctl_code) { case IOCTL_QUERY_JOB_INFO: replysize = 32; break; @@ -355,16 +351,15 @@ int reply_ioctl(connection_struct *conn, SSVAL(outbuf,smb_vwv6,52); /* Offset to data */ p = smb_buf(outbuf) + 1; /* Allow for alignment */ - switch (ioctl_code) - { - case IOCTL_QUERY_JOB_INFO: - { - uint16 rap_jobid = pjobid_to_rap(SNUM(fsp->conn), fsp->print_jobid); - SSVAL(p,0,rap_jobid); /* Job number */ - srvstr_push(outbuf, p+2, global_myname, 15, STR_TERMINATE|STR_ASCII); - srvstr_push(outbuf, p+18, lp_servicename(SNUM(conn)), 13, STR_TERMINATE|STR_ASCII); - break; - } + switch (ioctl_code) { + case IOCTL_QUERY_JOB_INFO: + { + uint16 rap_jobid = pjobid_to_rap(SNUM(fsp->conn), fsp->print_jobid); + SSVAL(p,0,rap_jobid); /* Job number */ + srvstr_push(outbuf, p+2, global_myname, 15, STR_TERMINATE|STR_ASCII); + srvstr_push(outbuf, p+18, lp_servicename(SNUM(conn)), 13, STR_TERMINATE|STR_ASCII); + break; + } } END_PROFILE(SMBioctl); @@ -372,56 +367,56 @@ int reply_ioctl(connection_struct *conn, } /**************************************************************************** - reply to a chkpth + Reply to a chkpth. ****************************************************************************/ + int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int outsize = 0; - int mode; - pstring name; - BOOL ok = False; - BOOL bad_path = False; - SMB_STRUCT_STAT sbuf; - START_PROFILE(SMBchkpth); + int outsize = 0; + int mode; + pstring name; + BOOL ok = False; + BOOL bad_path = False; + SMB_STRUCT_STAT sbuf; + START_PROFILE(SMBchkpth); - srvstr_pull_buf(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), STR_TERMINATE); + srvstr_pull_buf(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), STR_TERMINATE); - RESOLVE_DFSPATH(name, conn, inbuf, outbuf); + RESOLVE_DFSPATH(name, conn, inbuf, outbuf); - unix_convert(name,conn,0,&bad_path,&sbuf); + unix_convert(name,conn,0,&bad_path,&sbuf); - mode = SVAL(inbuf,smb_vwv0); + mode = SVAL(inbuf,smb_vwv0); - if (check_name(name,conn)) { - if (VALID_STAT(sbuf) || vfs_stat(conn,name,&sbuf) == 0) - ok = S_ISDIR(sbuf.st_mode); - } + if (check_name(name,conn)) { + if (VALID_STAT(sbuf) || vfs_stat(conn,name,&sbuf) == 0) + ok = S_ISDIR(sbuf.st_mode); + } - if (!ok) { - /* We special case this - as when a Windows machine - is parsing a path is steps through the components - one at a time - if a component fails it expects - ERRbadpath, not ERRbadfile. - */ - if(errno == ENOENT) { - return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); - } + if (!ok) { + /* We special case this - as when a Windows machine + is parsing a path is steps through the components + one at a time - if a component fails it expects + ERRbadpath, not ERRbadfile. + */ + if(errno == ENOENT) + return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); - return(UNIXERROR(ERRDOS,ERRbadpath)); - } + return(UNIXERROR(ERRDOS,ERRbadpath)); + } - outsize = set_message(outbuf,0,0,True); + outsize = set_message(outbuf,0,0,True); - DEBUG(3,("chkpth %s mode=%d\n", name, mode)); + DEBUG(3,("chkpth %s mode=%d\n", name, mode)); - END_PROFILE(SMBchkpth); - return(outsize); + END_PROFILE(SMBchkpth); + return(outsize); } - /**************************************************************************** - reply to a getatr + Reply to a getatr. ****************************************************************************/ + int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { pstring fname; @@ -494,10 +489,10 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size return(outsize); } - /**************************************************************************** - reply to a setatr + Reply to a setatr. ****************************************************************************/ + int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { pstring fname; @@ -543,10 +538,10 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size return(outsize); } - /**************************************************************************** - reply to a dskattr + Reply to a dskattr. ****************************************************************************/ + int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { int outsize = 0; @@ -591,11 +586,11 @@ int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz return(outsize); } - /**************************************************************************** - reply to a search - Can be called from SMBsearch, SMBffirst or SMBfunique. + Reply to a search. + Can be called from SMBsearch, SMBffirst or SMBfunique. ****************************************************************************/ + int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { pstring mask; @@ -673,12 +668,16 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size if (strlen(directory) == 0) pstrcpy(directory,"./"); memset((char *)status,'\0',21); - SCVAL(status,0,dirtype); + SCVAL(status,0,(dirtype & 0x1F)); } else { + int status_dirtype; memcpy(status,p,21); - dirtype = CVAL(status,0) & 0x1F; + status_dirtype = CVAL(status,0) & 0x1F; + if (status_dirtype != (dirtype & 0x1F)) + dirtype = status_dirtype; + conn->dirptr = dptr_fetch(status+12,&dptr_num); if (!conn->dirptr) goto SearchEmpty; @@ -796,10 +795,10 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size return(outsize); } - /**************************************************************************** - reply to a fclose (stop directory search) + Reply to a fclose (stop directory search). ****************************************************************************/ + int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { int outsize = 0; @@ -838,9 +837,8 @@ int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size return(outsize); } - /**************************************************************************** - reply to an open + Reply to an open. ****************************************************************************/ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) @@ -910,10 +908,10 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, return(outsize); } - /**************************************************************************** - reply to an open and X + Reply to an open and X. ****************************************************************************/ + int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { pstring fname; @@ -1019,10 +1017,10 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt return chain_reply(inbuf,outbuf,length,bufsize); } - /**************************************************************************** - reply to a SMBulogoffX + Reply to a SMBulogoffX. ****************************************************************************/ + int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { uint16 vuid = SVAL(inbuf,smb_uid); @@ -1049,10 +1047,10 @@ int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length, return chain_reply(inbuf,outbuf,length,bufsize); } - /**************************************************************************** - reply to a mknew or a create + Reply to a mknew or a create. ****************************************************************************/ + int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { pstring fname; @@ -1122,10 +1120,10 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, return(outsize); } - /**************************************************************************** - reply to a create temporary file + Reply to a create temporary file. ****************************************************************************/ + int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { pstring fname; @@ -1433,6 +1431,59 @@ void fail_readraw(void) exit_server(errstr); } +/**************************************************************************** + Use sendfile in readbraw. +****************************************************************************/ + +void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T startpos, size_t nread, + ssize_t mincount, char *outbuf) +{ + ssize_t ret=0; + +#if defined(WITH_SENDFILE) + /* + * We can only use sendfile on a non-chained packet and on a file + * that is exclusively oplocked. reply_readbraw has already checked the length. + */ + + if ((nread > 0) && (lp_write_cache_size(SNUM(conn)) == 0) && + EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && lp_use_sendfile(SNUM(conn)) ) { + DATA_BLOB header; + + _smb_setlen(outbuf,nread); + header.data = outbuf; + header.length = 4; + header.free = NULL; + + if ( conn->vfs_ops.sendfile( smbd_server_fd(), fsp, fsp->fd, &header, startpos, nread) == -1) { + /* + * Special hack for broken Linux with no 64 bit clean sendfile. If we + * return ENOSYS then pretend we just got a normal read. + */ + if (errno == ENOSYS) + goto normal_read; + + DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n", + fsp->fsp_name, strerror(errno) )); + exit_server("send_file_readbraw sendfile failed"); + } + + } + + normal_read: +#endif + + if (nread > 0) { + ret = read_file(fsp,outbuf+4,startpos,nread); + if (ret < mincount) + ret = 0; + } + + _smb_setlen(outbuf,ret); + if (write_data(smbd_server_fd(),outbuf,4+ret) != 4+ret) + fail_readraw(); +} + /**************************************************************************** Reply to a readbraw (core+ protocol). ****************************************************************************/ @@ -1443,7 +1494,6 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s size_t nread = 0; SMB_OFF_T startpos; char *header = outbuf; - ssize_t ret=0; files_struct *fsp; START_PROFILE(SMBreadbraw); @@ -1547,15 +1597,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n", fsp->fnum, (double)startpos, (int)maxcount, (int)mincount, (int)nread ) ); - if (nread > 0) { - ret = read_file(fsp,header+4,startpos,nread); - if (ret < mincount) - ret = 0; - } - - _smb_setlen(header,ret); - if (write_data(smbd_server_fd(),header,4+ret) != 4+ret) - fail_readraw(); + send_file_readbraw(conn, fsp, startpos, nread, mincount, outbuf); DEBUG(5,("readbraw finished\n")); END_PROFILE(SMBreadbraw); @@ -1563,8 +1605,9 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s } /**************************************************************************** - reply to a lockread (core+ protocol) + Reply to a lockread (core+ protocol). ****************************************************************************/ + int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length, int dum_buffsiz) { ssize_t nread = -1; @@ -1599,15 +1642,16 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, WRITE_LOCK); if (NT_STATUS_V(status)) { - if (lp_blocking_locks(SNUM(conn))) { + if (lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) { /* * A blocking lock was requested. Package up * this smb into a queued request and push it * onto the blocking lock queue. */ - if(push_blocking_lock_request(inbuf, length, -1, 0)) + if(push_blocking_lock_request(inbuf, length, -1, 0)) { END_PROFILE(SMBlockread); - return -1; + return -1; + } } END_PROFILE(SMBlockread); return ERROR_NT(status); @@ -1632,132 +1676,209 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length return(outsize); } - /**************************************************************************** - reply to a read + Reply to a read. ****************************************************************************/ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize) { - size_t numtoread; - ssize_t nread = 0; - char *data; - SMB_OFF_T startpos; - int outsize = 0; - files_struct *fsp = file_fsp(inbuf,smb_vwv0); - START_PROFILE(SMBread); - - CHECK_FSP(fsp,conn); - CHECK_READ(fsp); + size_t numtoread; + ssize_t nread = 0; + char *data; + SMB_OFF_T startpos; + int outsize = 0; + files_struct *fsp = file_fsp(inbuf,smb_vwv0); + START_PROFILE(SMBread); - numtoread = SVAL(inbuf,smb_vwv1); - startpos = IVAL(inbuf,smb_vwv2); + CHECK_FSP(fsp,conn); + CHECK_READ(fsp); + numtoread = SVAL(inbuf,smb_vwv1); + startpos = IVAL(inbuf,smb_vwv2); - outsize = set_message(outbuf,5,3,True); - numtoread = MIN(BUFFER_SIZE-outsize,numtoread); - data = smb_buf(outbuf) + 3; + outsize = set_message(outbuf,5,3,True); + numtoread = MIN(BUFFER_SIZE-outsize,numtoread); + data = smb_buf(outbuf) + 3; - if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK,False)) { - END_PROFILE(SMBread); - return ERROR_DOS(ERRDOS,ERRlock); - } + if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK,False)) { + END_PROFILE(SMBread); + return ERROR_DOS(ERRDOS,ERRlock); + } - if (numtoread > 0) - nread = read_file(fsp,data,startpos,numtoread); + if (numtoread > 0) + nread = read_file(fsp,data,startpos,numtoread); - if (nread < 0) { - END_PROFILE(SMBread); - return(UNIXERROR(ERRDOS,ERRnoaccess)); - } + if (nread < 0) { + END_PROFILE(SMBread); + return(UNIXERROR(ERRDOS,ERRnoaccess)); + } - outsize += nread; - SSVAL(outbuf,smb_vwv0,nread); - SSVAL(outbuf,smb_vwv5,nread+3); - SCVAL(smb_buf(outbuf),0,1); - SSVAL(smb_buf(outbuf),1,nread); + outsize += nread; + SSVAL(outbuf,smb_vwv0,nread); + SSVAL(outbuf,smb_vwv5,nread+3); + SCVAL(smb_buf(outbuf),0,1); + SSVAL(smb_buf(outbuf),1,nread); - DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n", - fsp->fnum, (int)numtoread, (int)nread ) ); + DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n", + fsp->fnum, (int)numtoread, (int)nread ) ); - END_PROFILE(SMBread); - return(outsize); + END_PROFILE(SMBread); + return(outsize); } +/**************************************************************************** + Reply to a read and X - possibly using sendfile. +****************************************************************************/ + +int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length, + files_struct *fsp, SMB_OFF_T startpos, size_t smb_maxcnt) +{ + ssize_t nread = -1; + char *data = smb_buf(outbuf); + +#if defined(WITH_SENDFILE) + /* + * We can only use sendfile on a non-chained packet and on a file + * that is exclusively oplocked. + */ + + if ((CVAL(inbuf,smb_vwv0) == 0xFF) && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && + lp_use_sendfile(SNUM(conn)) && (lp_write_cache_size(SNUM(conn)) == 0) ) { + SMB_STRUCT_STAT sbuf; + DATA_BLOB header; + + if(vfs_fstat(fsp,fsp->fd, &sbuf) == -1) + return(UNIXERROR(ERRDOS,ERRnoaccess)); + + if (startpos > sbuf.st_size) + goto normal_read; + + if (smb_maxcnt > (sbuf.st_size - startpos)) + smb_maxcnt = (sbuf.st_size - startpos); + + if (smb_maxcnt == 0) + goto normal_read; + + /* + * Set up the packet header before send. We + * assume here the sendfile will work (get the + * correct amount of data). + */ + + SSVAL(outbuf,smb_vwv5,smb_maxcnt); + SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf)); + SSVAL(smb_buf(outbuf),-2,smb_maxcnt); + SCVAL(outbuf,smb_vwv0,0xFF); + set_message(outbuf,12,smb_maxcnt,False); + header.data = outbuf; + header.length = data - outbuf; + header.free = NULL; + + if ( conn->vfs_ops.sendfile( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt) == -1) { + /* + * Special hack for broken Linux with no 64 bit clean sendfile. If we + * return ENOSYS then pretend we just got a normal read. + */ + if (errno == ENOSYS) + goto normal_read; + + DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n", + fsp->fsp_name, strerror(errno) )); + exit_server("send_file_readX sendfile failed"); + } + + DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n", + fsp->fnum, (int)smb_maxcnt, (int)nread ) ); + return -1; + } + + normal_read: + +#endif + + nread = read_file(fsp,data,startpos,smb_maxcnt); + + if (nread < 0) { + END_PROFILE(SMBreadX); + return(UNIXERROR(ERRDOS,ERRnoaccess)); + } + + SSVAL(outbuf,smb_vwv5,nread); + SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf)); + SSVAL(smb_buf(outbuf),-2,nread); + + DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n", + fsp->fnum, (int)smb_maxcnt, (int)nread ) ); + + return nread; +} /**************************************************************************** - reply to a read and X + Reply to a read and X. ****************************************************************************/ + int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { - files_struct *fsp = file_fsp(inbuf,smb_vwv2); - SMB_OFF_T startpos = IVAL(inbuf,smb_vwv3); - size_t smb_maxcnt = SVAL(inbuf,smb_vwv5); - size_t smb_mincnt = SVAL(inbuf,smb_vwv6); - ssize_t nread = -1; - char *data; - START_PROFILE(SMBreadX); + files_struct *fsp = file_fsp(inbuf,smb_vwv2); + SMB_OFF_T startpos = IVAL(inbuf,smb_vwv3); + ssize_t nread = -1; + size_t smb_maxcnt = SVAL(inbuf,smb_vwv5); +#if 0 + size_t smb_mincnt = SVAL(inbuf,smb_vwv6); +#endif - /* If it's an IPC, pass off the pipe handler. */ - if (IS_IPC(conn)) { - END_PROFILE(SMBreadX); - return reply_pipe_read_and_X(inbuf,outbuf,length,bufsize); - } + START_PROFILE(SMBreadX); - CHECK_FSP(fsp,conn); - CHECK_READ(fsp); + /* If it's an IPC, pass off the pipe handler. */ + if (IS_IPC(conn)) { + END_PROFILE(SMBreadX); + return reply_pipe_read_and_X(inbuf,outbuf,length,bufsize); + } + + CHECK_FSP(fsp,conn); + CHECK_READ(fsp); - set_message(outbuf,12,0,True); - data = smb_buf(outbuf); + set_message(outbuf,12,0,True); - if(CVAL(inbuf,smb_wct) == 12) { + if(CVAL(inbuf,smb_wct) == 12) { #ifdef LARGE_SMB_OFF_T - /* - * This is a large offset (64 bit) read. - */ - startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv10)) << 32); + /* + * This is a large offset (64 bit) read. + */ + startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv10)) << 32); #else /* !LARGE_SMB_OFF_T */ - /* - * Ensure we haven't been sent a >32 bit offset. - */ + /* + * Ensure we haven't been sent a >32 bit offset. + */ - if(IVAL(inbuf,smb_vwv10) != 0) { - DEBUG(0,("reply_read_and_X - large offset (%x << 32) used and we don't support \ + if(IVAL(inbuf,smb_vwv10) != 0) { + DEBUG(0,("reply_read_and_X - large offset (%x << 32) used and we don't support \ 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv10) )); - END_PROFILE(SMBreadX); - return ERROR_DOS(ERRDOS,ERRbadaccess); - } + END_PROFILE(SMBreadX); + return ERROR_DOS(ERRDOS,ERRbadaccess); + } #endif /* LARGE_SMB_OFF_T */ - } + } - if (is_locked(fsp,conn,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK,False)) { - END_PROFILE(SMBreadX); - return ERROR_DOS(ERRDOS,ERRlock); - } - nread = read_file(fsp,data,startpos,smb_maxcnt); + if (is_locked(fsp,conn,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK,False)) { + END_PROFILE(SMBreadX); + return ERROR_DOS(ERRDOS,ERRlock); + } - if (nread < 0) { - END_PROFILE(SMBreadX); - return(UNIXERROR(ERRDOS,ERRnoaccess)); - } - - SSVAL(outbuf,smb_vwv5,nread); - SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf)); - SSVAL(smb_buf(outbuf),-2,nread); - - DEBUG( 3, ( "readX fnum=%d min=%d max=%d nread=%d\n", - fsp->fnum, (int)smb_mincnt, (int)smb_maxcnt, (int)nread ) ); + nread = send_file_readX(conn, inbuf, outbuf, length, fsp, startpos, smb_maxcnt); + if (nread != -1) + nread = chain_reply(inbuf,outbuf,length,bufsize); - END_PROFILE(SMBreadX); - return chain_reply(inbuf,outbuf,length,bufsize); + END_PROFILE(SMBreadX); + return nread; } /**************************************************************************** - reply to a writebraw (core+ or LANMAN1.0 protocol) + Reply to a writebraw (core+ or LANMAN1.0 protocol). ****************************************************************************/ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize) @@ -1888,7 +2009,7 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, } /**************************************************************************** - reply to a writeunlock (core+) + Reply to a writeunlock (core+). ****************************************************************************/ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, @@ -1950,7 +2071,6 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, return outsize; } - /**************************************************************************** Reply to a write. ****************************************************************************/ @@ -2029,10 +2149,10 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d return(outsize); } - /**************************************************************************** - reply to a write and X + Reply to a write and X. ****************************************************************************/ + int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { files_struct *fsp = file_fsp(inbuf,smb_vwv2); @@ -2129,9 +2249,8 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng return chain_reply(inbuf,outbuf,length,bufsize); } - /**************************************************************************** - reply to a lseek + Reply to a lseek. ****************************************************************************/ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize) @@ -2212,7 +2331,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int } /**************************************************************************** - reply to a flush + Reply to a flush. ****************************************************************************/ int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize) @@ -2234,10 +2353,10 @@ int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int return(outsize); } - /**************************************************************************** - reply to a exit + Reply to a exit. ****************************************************************************/ + int reply_exit(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { @@ -2251,10 +2370,10 @@ int reply_exit(connection_struct *conn, return(outsize); } - /**************************************************************************** Reply to a close - has to deal with closing a directory opened by NT SMB's. ****************************************************************************/ + int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize) { @@ -2336,9 +2455,8 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size, return(outsize); } - /**************************************************************************** - reply to a writeclose (Core+ protocol) + Reply to a writeclose (Core+ protocol). ****************************************************************************/ int reply_writeclose(connection_struct *conn, @@ -2395,10 +2513,10 @@ int reply_writeclose(connection_struct *conn, return(outsize); } - /**************************************************************************** - reply to a lock + Reply to a lock. ****************************************************************************/ + int reply_lock(connection_struct *conn, char *inbuf,char *outbuf, int length, int dum_buffsize) { @@ -2420,7 +2538,7 @@ int reply_lock(connection_struct *conn, status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK); if (NT_STATUS_V(status)) { - if (lp_blocking_locks(SNUM(conn))) { + if (lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) { /* * A blocking lock was requested. Package up * this smb into a queued request and push it @@ -2439,10 +2557,10 @@ int reply_lock(connection_struct *conn, return(outsize); } - /**************************************************************************** - reply to a unlock + Reply to a unlock. ****************************************************************************/ + int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize) { @@ -2470,10 +2588,10 @@ int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size, return(outsize); } - /**************************************************************************** - reply to a tdis + Reply to a tdis. ****************************************************************************/ + int reply_tdis(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { @@ -2497,11 +2615,10 @@ int reply_tdis(connection_struct *conn, return outsize; } - - /**************************************************************************** - reply to a echo + Reply to a echo. ****************************************************************************/ + int reply_echo(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { @@ -2539,10 +2656,10 @@ int reply_echo(connection_struct *conn, return -1; } - /**************************************************************************** - reply to a printopen + Reply to a printopen. ****************************************************************************/ + int reply_printopen(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { @@ -2573,9 +2690,8 @@ int reply_printopen(connection_struct *conn, return(outsize); } - /**************************************************************************** - reply to a printclose + Reply to a printclose. ****************************************************************************/ int reply_printclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) @@ -2607,10 +2723,10 @@ int reply_printclose(connection_struct *conn, return(outsize); } - /**************************************************************************** - reply to a printqueue + Reply to a printqueue. ****************************************************************************/ + int reply_printqueue(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { @@ -2678,10 +2794,10 @@ int reply_printqueue(connection_struct *conn, return(outsize); } - /**************************************************************************** - reply to a printwrite + Reply to a printwrite. ****************************************************************************/ + int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { int numtowrite; @@ -2712,11 +2828,11 @@ int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_ return(outsize); } - /**************************************************************************** The guts of the mkdir command, split out so it may be called by the NT SMB code. ****************************************************************************/ + NTSTATUS mkdir_internal(connection_struct *conn, pstring directory) { BOOL bad_path = False; @@ -2939,10 +3055,10 @@ int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, return(outsize); } - /******************************************************************* -resolve wildcards in a filename rename + Resolve wildcards in a filename rename. ********************************************************************/ + static BOOL resolve_wildcards(char *name1,char *name2) { fstring root1,root2; @@ -3378,8 +3494,9 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun, } /**************************************************************************** - reply to a file copy. - ****************************************************************************/ + Reply to a file copy. +****************************************************************************/ + int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { int outsize = 0; @@ -3542,8 +3659,9 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, } /**************************************************************************** - reply to a setdir + Reply to a setdir. ****************************************************************************/ + int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { int snum; @@ -3637,6 +3755,7 @@ SMB_BIG_UINT get_lock_count( char *data, int data_offset, BOOL large_file_format /**************************************************************************** Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-). ****************************************************************************/ + static uint32 map_lock_offset(uint32 high, uint32 low) { unsigned int i; @@ -3716,7 +3835,7 @@ SMB_BIG_UINT get_lock_offset( char *data, int data_offset, BOOL large_file_forma } /**************************************************************************** - reply to a lockingX request + Reply to a lockingX request. ****************************************************************************/ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) @@ -3827,7 +3946,7 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name)); /* Setup the timeout in seconds. */ - lock_timeout = ((lock_timeout == -1) ? -1 : lock_timeout/1000); + lock_timeout = ((lock_timeout == -1) ? -1 : (lock_timeout+999)/1000); /* Now do any requested locks */ data += ((large_file_format ? 20 : 10)*num_ulocks); @@ -3855,7 +3974,7 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name)); status = do_lock_spin(fsp,conn,lock_pid, count,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK)); if (NT_STATUS_V(status)) { - if ((lock_timeout != 0) && lp_blocking_locks(SNUM(conn))) { + if ((lock_timeout != 0) && lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) { /* * A blocking lock was requested. Package up * this smb into a queued request and push it diff --git a/source3/smbd/sec_ctx.c b/source3/smbd/sec_ctx.c index bdcdce6e145..411ece52495 100644 --- a/source3/smbd/sec_ctx.c +++ b/source3/smbd/sec_ctx.c @@ -287,17 +287,8 @@ void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN DEBUG(3, ("setting sec ctx (%u, %u) - sec_ctx_stack_ndx = %d\n", (unsigned int)uid, (unsigned int)gid, sec_ctx_stack_ndx)); - if (ngroups) { - int i; - - DEBUG(3, ("%d user groups: \n", ngroups)); - for (i = 0; i < ngroups; i++) { - DEBUGADD(3, ("%u ", (unsigned int)groups[i])); - } - - DEBUG(3, ("\n")); - } - + debug_nt_user_token(DBGC_CLASS, 5, token); + debug_unix_user_token(DBGC_CLASS, 5, uid, gid, ngroups, groups); gain_root(); diff --git a/source3/smbd/server.c b/source3/smbd/server.c index b2b905cec35..39d5e3bcd3f 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -33,6 +33,8 @@ int last_message = -1; #define LAST_MESSAGE() smb_fn_name(last_message) extern pstring user_socket_options; +extern SIG_ATOMIC_T got_sig_term; +extern SIG_ATOMIC_T reload_after_sighup; #ifdef WITH_DFS extern int dcelogin_atmost_once; @@ -61,8 +63,6 @@ static void smbd_set_server_fd(int fd) Terminate signal. ****************************************************************************/ -SIG_ATOMIC_T got_sig_term = 0; - static void sig_term(void) { got_sig_term = 1; @@ -73,8 +73,6 @@ static void sig_term(void) Catch a sighup. ****************************************************************************/ -SIG_ATOMIC_T reload_after_sighup = 0; - static void sig_hup(int sig) { reload_after_sighup = 1; @@ -542,6 +540,8 @@ void exit_server(char *reason) invalidate_all_vuids(); + print_notify_send_messages(); + /* delete our entry in the connections database. */ yield_connection(NULL,""); @@ -860,7 +860,7 @@ static void usage(char *pname) register_dmalloc_msgs(); /* Setup the main smbd so that we can get messages. */ - claim_connection(NULL,"",0,True); + claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD); /* DO NOT ENABLE THIS TILL YOU COPE WITH KILLING THESE TASKS AND INETD diff --git a/source3/smbd/service.c b/source3/smbd/service.c index 6f83a2d3b75..a8a590da804 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -305,6 +305,7 @@ static void set_admin_user(connection_struct *conn) #endif ) { conn->admin_user = True; + conn->force_user = True; /* Admin users are effectivly 'forced' */ DEBUG(0,("%s logged in as admin user (root privileges)\n",conn->user)); } else { conn->admin_user = False; @@ -329,7 +330,6 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, { struct passwd *pass = NULL; BOOL guest = False; - BOOL force = False; connection_struct *conn; struct stat st; fstring user; @@ -349,7 +349,6 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, if (lp_guest_only(snum)) { const char *guestname = lp_guestaccount(); guest = True; - force = True; pass = getpwnam_alloc(guestname); if (!pass) { DEBUG(0,("authorise_login: Invalid guest account %s??\n",guestname)); @@ -397,7 +396,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, return NULL; } pass = Get_Pwnam(user); - conn->force_user = force; + conn->force_user = True; conn->uid = pass->pw_uid; conn->gid = pass->pw_gid; string_set(&conn->user, pass->pw_name); @@ -434,7 +433,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, /* * If force user is true, then store the - * given userid and also the primary groupid + * given userid and also the groups * of the user we're forcing. */ @@ -492,6 +491,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, gid = nametogid(gname); if (gid != (gid_t)-1) { + /* * If the user has been forced and the forced group starts * with a '+', then we only set the group to be the forced @@ -507,6 +507,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, conn->gid = gid; DEBUG(3,("Forced group %s\n",gname)); } + conn->force_group = True; } else { DEBUG(1,("Couldn't find group %s\n",gname)); conn_free(conn); @@ -524,23 +525,27 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, DEBUG(3,("Connect path is '%s' for service [%s]\n",s, lp_servicename(snum))); } - /* groups stuff added by ih */ - conn->ngroups = 0; - conn->groups = NULL; - - /* Find all the groups this uid is in and - store them. Used by change_to_user() */ - initialise_groups(conn->user, conn->uid, conn->gid); - get_current_groups(conn->gid, &conn->ngroups,&conn->groups); + if (conn->force_user || conn->force_group) { + + /* groups stuff added by ih */ + conn->ngroups = 0; + conn->groups = NULL; + + /* Find all the groups this uid is in and + store them. Used by change_to_user() */ + initialise_groups(conn->user, conn->uid, conn->gid); + get_current_groups(conn->gid, &conn->ngroups,&conn->groups); - conn->nt_user_token = create_nt_token(conn->uid, conn->gid, - conn->ngroups, conn->groups, - guest, NULL); + conn->nt_user_token = create_nt_token(conn->uid, conn->gid, + conn->ngroups, conn->groups, + guest); + } /* * New code to check if there's a share security descripter * added from NT server manager. This is done after the * smb.conf checks are done as we need a uid and token. JRA. + * */ { @@ -573,7 +578,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, if (!claim_connection(conn, lp_servicename(SNUM(conn)), lp_max_connections(SNUM(conn)), - False)) { + False,0)) { DEBUG(1,("too many connections - rejected\n")); conn_free(conn); *status = NT_STATUS_INSUFFICIENT_RESOURCES; @@ -803,7 +808,7 @@ connection_struct *make_connection(const char *service_in, DATA_BLOB password, } else if ((lp_security() != SEC_SHARE) && (vuser->homes_snum != -1) && strequal(service_in, lp_servicename(vuser->homes_snum))) { DATA_BLOB no_pw = data_blob(NULL, 0); - DEBUG(5, ("making a connection to 'homes' service [%s] created at session setup time\n", service)); + DEBUG(5, ("making a connection to 'homes' service [%s] created at session setup time\n", service_in)); return make_connection_snum(vuser->homes_snum, vuser, no_pw, dev, status); diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 77f93812dd5..b9af7200089 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -160,12 +160,12 @@ static int reply_spnego_kerberos(connection_struct *conn, ads_destroy(&ads); /* the password is good - let them in */ - pw = smb_getpwnam(user,False); + pw = Get_Pwnam(user); if (!pw && !strstr(user, lp_winbind_separator())) { char *user2; /* try it with a winbind domain prefix */ asprintf(&user2, "%s%s%s", lp_workgroup(), lp_winbind_separator(), user); - pw = smb_getpwnam(user2,False); + pw = Get_Pwnam(user2); if (pw) { free(user); user = user2; @@ -177,9 +177,9 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(NT_STATUS_NO_SUCH_USER); } - if (!make_server_info_pw(&server_info,pw)) { + if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info,pw))) { DEBUG(1,("make_server_info_from_pw failed!\n")); - return ERROR_NT(NT_STATUS_NO_MEMORY); + return ERROR_NT(ret); } sess_vuid = register_vuid(server_info, user); @@ -294,8 +294,6 @@ static int reply_spnego_negotiate(connection_struct *conn, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - DEBUG(3,("Got neg_flags=0x%08x\n", neg_flags)); - debug_ntlmssp_flags(neg_flags); if (ntlmssp_auth_context) { @@ -324,12 +322,12 @@ static int reply_spnego_negotiate(connection_struct *conn, "U", lp_workgroup()); - fstrcpy(dnsdomname, lp_realm()); + fstrcpy(dnsdomname, (SEC_ADS == lp_security())?lp_realm():""); strlower(dnsdomname); fstrcpy(dnsname, global_myname); fstrcat(dnsname, "."); - fstrcat(dnsname, lp_realm()); + fstrcat(dnsname, dnsdomname); strlower(dnsname); msrpc_gen(&struct_blob, "aaaaa", @@ -441,14 +439,14 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, auth_flags |= AUTH_FLAG_NTLM_RESP; } else if (nthash.length > 24) { auth_flags |= AUTH_FLAG_NTLMv2_RESP; - } + }; + + nt_status = make_user_info_map(&user_info, user, workgroup, machine, + lmhash, nthash, plaintext_password, + auth_flags, True); - if (!make_user_info_map(&user_info, - user, workgroup, - machine, - lmhash, nthash, - plaintext_password, - auth_flags, True)) { + /* it looks a bit weird, but this function returns int type... */ + if (!NT_STATUS_IS_OK(nt_status)) { return ERROR_NT(NT_STATUS_NO_MEMORY); } @@ -623,7 +621,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, NTSTATUS nt_status; BOOL doencrypt = global_encrypted_passwords_negotiated; - + START_PROFILE(SMBsesssetupX); ZERO_STRUCT(lm_resp); @@ -736,7 +734,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, /* don't allow for weird usernames or domains */ alpha_strcpy(user, user, ". _-$", sizeof(user)); - alpha_strcpy(domain, domain, ". _-", sizeof(domain)); + alpha_strcpy(domain, domain, ". _-@", sizeof(domain)); if (strstr(user, "..") || strstr(domain,"..")) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); } @@ -778,11 +776,9 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, nt_status = check_guest_password(&server_info); } else if (doencrypt) { - if (!make_user_info_for_reply_enc(&user_info, - user, domain, - lm_resp, nt_resp)) { - nt_status = NT_STATUS_NO_MEMORY; - } else { + nt_status = make_user_info_for_reply_enc(&user_info, user, domain, + lm_resp, nt_resp); + if (NT_STATUS_IS_OK(nt_status)) { nt_status = negprot_global_auth_context->check_ntlm_password(negprot_global_auth_context, user_info, &server_info); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index a66c0292863..de65cda2d09 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -30,19 +30,26 @@ extern int global_oplock_break; extern uint32 global_client_caps; extern pstring global_myname; +#define get_file_size(sbuf) (sbuf.st_size) + /* given a stat buffer return the allocated size on disk, taking into account sparse files */ -SMB_OFF_T get_allocation_size(SMB_STRUCT_STAT *sbuf) +SMB_OFF_T get_allocation_size(files_struct *fsp, SMB_STRUCT_STAT *sbuf) { SMB_OFF_T ret; +#if defined(HAVE_STAT_ST_BLKSIZE) && defined(HAVE_STAT_ST_BLOCKS) ret = sbuf->st_blksize * (SMB_OFF_T)sbuf->st_blocks; - ret = SMB_ROUNDUP_ALLOCATION(ret); +#elif defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE) + ret = (SMB_OFF_T)STAT_ST_BLOCKSIZE * (SMB_OFF_T)sbuf->st_blocks; +#else + ret = get_file_size(*sbuf); +#endif + if (!ret && fsp && fsp->initial_allocation_size) + ret = fsp->initial_allocation_size; + ret = SMB_ROUNDUP(ret,SMB_ROUNDUP_ALLOCATION_SIZE); return ret; } -#define get_file_size(sbuf) (sbuf.st_size) - - /**************************************************************************** Send the required number of replies back. We assume all fields other than the data fields are @@ -579,7 +586,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, } file_size = get_file_size(sbuf); - allocation_size = get_allocation_size(&sbuf); + allocation_size = get_allocation_size(NULL,&sbuf); mdate = sbuf.st_mtime; adate = sbuf.st_atime; cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))); @@ -660,6 +667,11 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, SIVAL(p,0,nt_extmode); p += 4; q = p; p += 4; SIVAL(p,0,0); p += 4; + /* Clear the short name buffer. This is + * IMPORTANT as not doing so will trigger + * a Win2k client bug. JRA. + */ + memset(p,'\0',26); if (!was_8_3) { pstring mangled_name; pstrcpy(mangled_name, fname); @@ -751,12 +763,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, SOFF_T(p,0,get_file_size(sbuf)); /* File size 64 Bit */ p+= 8; -#if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE) - SOFF_T(p,0,sbuf.st_blocks*STAT_ST_BLOCKSIZE); /* Number of bytes used on disk - 64 Bit */ -#else - /* Can't get the value - fake it using size. */ - SOFF_T(p,0,get_file_size(sbuf)); /* Number of bytes used on disk - 64 Bit */ -#endif + SOFF_T(p,0,get_allocation_size(NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */ p+= 8; put_long_date(p,sbuf.st_ctime); /* Creation Time 64 Bit */ @@ -899,7 +906,11 @@ close_if_end = %d requires_resume_key = %d level = %d, max_data_bytes = %d\n", p = strrchr_m(directory,'/'); if(p == NULL) { - pstrcpy(mask,directory); + /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */ + if((directory[0] == '.') && (directory[1] == '\0')) + pstrcpy(mask,"*"); + else + pstrcpy(mask,directory); pstrcpy(directory,"./"); } else { pstrcpy(mask,p+1); @@ -1554,12 +1565,16 @@ static int call_trans2qfilepathinfo(connection_struct *conn, BOOL delete_pending = False; int len; time_t c_time; + files_struct *fsp = NULL; if (!params) return ERROR_NT(NT_STATUS_INVALID_PARAMETER); if (tran_call == TRANSACT2_QFILEINFO) { - files_struct *fsp = file_fsp(params,0); + if (total_params < 4) + return(ERROR_DOS(ERRDOS,ERRinvalidparam)); + + fsp = file_fsp(params,0); info_level = SVAL(params,2); DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level)); @@ -1657,7 +1672,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, mode = dos_mode(conn,fname,&sbuf); fullpathname = fname; file_size = get_file_size(sbuf); - allocation_size = get_allocation_size(&sbuf); + allocation_size = get_allocation_size(fsp,&sbuf); if (mode & aDIR) file_size = 0; @@ -1842,7 +1857,12 @@ static int call_trans2qfilepathinfo(connection_struct *conn, break; case SMB_FILE_INTERNAL_INFORMATION: - /* This should be an index number - looks like dev/ino to me :-) */ + /* This should be an index number - looks like + dev/ino to me :-) + + I think this causes us to fail the IFSKIT + BasicFileInformationTest. -tpot */ + SIVAL(pdata,0,sbuf.st_dev); SIVAL(pdata,4,sbuf.st_ino); data_size = 8; @@ -1972,12 +1992,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, SOFF_T(pdata,0,get_file_size(sbuf)); /* File size 64 Bit */ pdata += 8; -#if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE) - SOFF_T(pdata,0,sbuf.st_blocks*STAT_ST_BLOCKSIZE); /* Number of bytes used on disk - 64 Bit */ -#else - /* Can't get the value - fake it using size. */ - SOFF_T(pdata,0,get_file_size(sbuf)); /* Number of bytes used on disk - 64 Bit */ -#endif + SOFF_T(pdata,0,get_allocation_size(fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */ pdata += 8; put_long_date(pdata,sbuf.st_ctime); /* Creation Time 64 Bit */ @@ -2334,7 +2349,6 @@ static int call_trans2setfilepathinfo(connection_struct *conn, switch (info_level) { case SMB_INFO_STANDARD: - case SMB_INFO_QUERY_EA_SIZE: { if (total_data < l1_cbFile+4) return(ERROR_DOS(ERRDOS,ERRinvalidparam)); @@ -2351,6 +2365,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn, break; } + case SMB_INFO_SET_EA: + return(ERROR_DOS(ERRDOS,ERReasnotsupported)); + /* XXXX um, i don't think this is right. it's also not in the cifs6.txt spec. */ @@ -2412,11 +2429,12 @@ static int call_trans2setfilepathinfo(connection_struct *conn, case SMB_SET_FILE_ALLOCATION_INFO: { int ret = -1; - SMB_OFF_T allocation_size = IVAL(pdata,0); + SMB_OFF_T allocation_size; if (total_data < 8) return(ERROR_DOS(ERRDOS,ERRinvalidparam)); + allocation_size = IVAL(pdata,0); #ifdef LARGE_SMB_OFF_T allocation_size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32); #else /* LARGE_SMB_OFF_T */ @@ -2426,6 +2444,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn, DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n", fname, (double)allocation_size )); + if (allocation_size) + allocation_size = SMB_ROUNDUP(allocation_size,SMB_ROUNDUP_ALLOCATION_SIZE); + if(allocation_size != get_file_size(sbuf)) { SMB_STRUCT_STAT new_sbuf; diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index c0bacf8f910..2bda26aa510 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -59,18 +59,26 @@ BOOL change_to_guest(void) static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) { int i; - for (i=0;iuid_cache.entries;i++) - if (conn->uid_cache.list[i] == vuser->uid) + for (i=0;ivuid_cache.entries && i< VUID_CACHE_SIZE;i++) + if (conn->vuid_cache.list[i] == vuser->vuid) return(True); + if ((conn->force_user || conn->force_group) + && (conn->vuid != vuser->vuid)) { + return False; + } + if (!user_ok(vuser->user.unix_name,snum)) return(False); - i = conn->uid_cache.entries % UID_CACHE_SIZE; - conn->uid_cache.list[i] = vuser->uid; + if (!share_access_check(conn, snum, vuser, conn->read_only ? FILE_READ_DATA : FILE_WRITE_DATA)) { + return False; + } + + i = conn->vuid_cache.entries % VUID_CACHE_SIZE; + conn->vuid_cache.list[i] = vuser->vuid; - if (conn->uid_cache.entries < UID_CACHE_SIZE) - conn->uid_cache.entries++; + conn->vuid_cache.entries++; return(True); } @@ -115,27 +123,21 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) snum = SNUM(conn); - if((vuser != NULL) && !check_user_ok(conn, vuser, snum)) - return False; - - if (conn->force_user || - conn->admin_user || - (lp_security() == SEC_SHARE)) { + if (conn->force_user) /* security = share sets this too */ { uid = conn->uid; gid = conn->gid; current_user.groups = conn->groups; current_user.ngroups = conn->ngroups; token = conn->nt_user_token; - } else { - if (!vuser) { - DEBUG(2,("change_to_user: Invalid vuid used %d\n",vuid)); - return(False); - } + } else if ((vuser) && check_user_ok(conn, vuser, snum)) { uid = vuser->uid; gid = vuser->gid; current_user.ngroups = vuser->n_groups; current_user.groups = vuser->groups; token = vuser->nt_user_token; + } else { + DEBUG(2,("change_to_user: Invalid vuid used %d or vuid not permitted access to share.\n",vuid)); + return False; } /* @@ -175,7 +177,11 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) if (vuser && vuser->guest) is_guest = True; - token = create_nt_token(uid, gid, current_user.ngroups, current_user.groups, is_guest, NULL); + token = create_nt_token(uid, gid, current_user.ngroups, current_user.groups, is_guest); + if (!token) { + DEBUG(1, ("change_to_user: create_nt_token failed!\n")); + return False; + } must_free_token = True; } diff --git a/source3/smbd/vfs-wrap.c b/source3/smbd/vfs-wrap.c index 394086dc075..bae304096ce 100644 --- a/source3/smbd/vfs-wrap.c +++ b/source3/smbd/vfs-wrap.c @@ -20,6 +20,10 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_VFS + + /* Check for NULL pointer parameters in vfswrap_* functions */ /* We don't want to have NULL function pointers lying around. Someone @@ -188,6 +192,17 @@ SMB_OFF_T vfswrap_lseek(files_struct *fsp, int filedes, SMB_OFF_T offset, int wh return result; } +ssize_t vfswrap_sendfile(int tofd, struct files_struct *fsp, int fromfd, const DATA_BLOB *hdr, + SMB_OFF_T offset, size_t n) +{ + ssize_t result; + + START_PROFILE_BYTES(syscall_sendfile, n); + result = sys_sendfile(tofd, fromfd, hdr, offset, n); + END_PROFILE(syscall_sendfile); + return result; +} + int vfswrap_rename(connection_struct *conn, const char *old, const char *new) { int result; diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index a2291eba08f..a0a7b920b8b 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -24,6 +24,10 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_VFS + + /* Some structures to help us initialise the vfs operations table */ struct vfs_syminfo { @@ -64,6 +68,7 @@ static struct vfs_ops default_vfs_ops = { vfswrap_read, vfswrap_write, vfswrap_lseek, + vfswrap_sendfile, vfswrap_rename, vfswrap_fsync, vfswrap_stat, @@ -138,7 +143,7 @@ static void vfs_init_default(connection_struct *conn) initialise custom vfs hooks ****************************************************************************/ -static BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object) +BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object) { int vfs_version = -1; vfs_op_tuple *ops, *(*init_fptr)(int *, const struct vfs_ops *, struct smb_vfs_handle_struct *); @@ -259,6 +264,7 @@ BOOL smbd_vfs_init(connection_struct *conn) /******************************************************************* Create vfs_ops reflecting current vfs_opaque_ops *******************************************************************/ + struct vfs_ops *smb_vfs_get_opaque_ops(void) { int i; @@ -297,6 +303,7 @@ BOOL vfs_directory_exist(connection_struct *conn, const char *dname, SMB_STRUCT_ /******************************************************************* vfs getwd wrapper ********************************************************************/ + static char *vfs_getwd(connection_struct *conn, char *path) { return conn->vfs_ops.getwd(conn,path); diff --git a/source3/tdb/spinlock.c b/source3/tdb/spinlock.c index 74472854cf2..2370ce3bdd9 100644 --- a/source3/tdb/spinlock.c +++ b/source3/tdb/spinlock.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "tdb.h" #include "spinlock.h" diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c index ed75a55e3e9..5bb75ffe077 100644 --- a/source3/tdb/tdb.c +++ b/source3/tdb/tdb.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "tdb.h" #include "spinlock.h" #else @@ -160,6 +161,18 @@ struct list_struct { */ }; +/*************************************************************** + Allow a caller to set a "alarm" flag that tdb can check to abort + a blocking lock on SIGALRM. +***************************************************************/ + +static sig_atomic_t *palarm_fired; + +void tdb_set_lock_alarm(sig_atomic_t *palarm) +{ + palarm_fired = palarm; +} + /* a byte range locking function - return 0 on success this functions locks/unlocks 1 byte at the specified offset. @@ -186,6 +199,8 @@ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset, do { ret = fcntl(tdb->fd,lck_type,&fl); + if (ret == -1 && errno == EINTR && palarm_fired && *palarm_fired) + break; } while (ret == -1 && errno == EINTR); if (ret == -1) { @@ -517,17 +532,20 @@ int tdb_printfreelist(TDB_CONTEXT *tdb) /* read in the freelist top */ if (ofs_read(tdb, offset, &rec_ptr) == -1) { + tdb_unlock(tdb, -1, F_WRLCK); return 0; } printf("freelist top=[0x%08x]\n", rec_ptr ); while (rec_ptr) { if (tdb_read(tdb, rec_ptr, (char *)&rec, sizeof(rec), DOCONV()) == -1) { + tdb_unlock(tdb, -1, F_WRLCK); return -1; } if (rec.magic != TDB_FREE_MAGIC) { printf("bad magic 0x%08x in free list\n", rec.magic); + tdb_unlock(tdb, -1, F_WRLCK); return -1; } diff --git a/source3/tdb/tdb.h b/source3/tdb/tdb.h index 8cc908703f8..42b88aeb161 100644 --- a/source3/tdb/tdb.h +++ b/source3/tdb/tdb.h @@ -126,6 +126,7 @@ int tdb_lockall(TDB_CONTEXT *tdb); void tdb_unlockall(TDB_CONTEXT *tdb); /* Low level locking functions: use with care */ +void tdb_set_lock_alarm(sig_atomic_t *palarm); int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key); int tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key); diff --git a/source3/tdb/tdbbackup.c b/source3/tdb/tdbbackup.c index f59f98a90f5..36ba7db9188 100644 --- a/source3/tdb/tdbbackup.c +++ b/source3/tdb/tdbbackup.c @@ -53,6 +53,7 @@ #include #include #include +#include #include "tdb.h" static int failed; diff --git a/source3/tdb/tdbdump.c b/source3/tdb/tdbdump.c index 66642132093..9c1dc2761b6 100644 --- a/source3/tdb/tdbdump.c +++ b/source3/tdb/tdbdump.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "tdb.h" static void print_data(TDB_DATA d) diff --git a/source3/tdb/tdbtest.c b/source3/tdb/tdbtest.c index 0741073ce11..89295a3291f 100644 --- a/source3/tdb/tdbtest.c +++ b/source3/tdb/tdbtest.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "tdb.h" #include diff --git a/source3/tdb/tdbtool.c b/source3/tdb/tdbtool.c index ba0fb48957d..f529c6e6eeb 100644 --- a/source3/tdb/tdbtool.c +++ b/source3/tdb/tdbtool.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "tdb.h" /* a tdb tool for manipulating a tdb database */ diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 101f4071cbb..fb62b13657f 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -785,6 +785,7 @@ static BOOL run_locktest1(int dummy) char *fname = "\\lockt1.lck"; int fnum1, fnum2, fnum3; time_t t1, t2; + unsigned lock_timeout; if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) { return False; @@ -827,9 +828,10 @@ static BOOL run_locktest1(int dummy) } - printf("Testing lock timeouts\n"); + lock_timeout = (1 + (random() % 20)); + printf("Testing lock timeout with timeout=%u\n", lock_timeout); t1 = time(NULL); - if (cli_lock(&cli2, fnum3, 0, 4, 10*1000, WRITE_LOCK)) { + if (cli_lock(&cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) { printf("lock3 succeeded! This is a locking bug\n"); return False; } else { @@ -841,6 +843,8 @@ static BOOL run_locktest1(int dummy) if (t2 - t1 < 5) { printf("error: This server appears not to support timed lock requests\n"); } + printf("server slept for %u seconds for a %u second timeout\n", + (unsigned int)(t2-t1), lock_timeout); if (!cli_close(&cli1, fnum2)) { printf("close1 failed (%s)\n", cli_errstr(&cli1)); @@ -3413,6 +3417,52 @@ static BOOL run_opentest(int dummy) cli_unlink(&cli1, fname); + /* Test 8 - attributes test test... */ + fnum1 = cli_nt_create_full(&cli1, fname,FILE_WRITE_DATA, FILE_ATTRIBUTE_HIDDEN, + FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0); + + if (fnum1 == -1) { + printf("test 8 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1)); + return False; + } + + if (!cli_close(&cli1, fnum1)) { + printf("test 8 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1)); + return False; + } + + /* FILE_SUPERSEDE && FILE_OVERWRITE_IF have the same effect here. */ + fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0); + + if (fnum1 == -1) { + printf("test 8 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli1)); + return False; + } + + if (!cli_close(&cli1, fnum1)) { + printf("test 8 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli1)); + return False; + } + + /* This open should fail with ACCESS_DENIED for FILE_SUPERSEDE, FILE_OVERWRITE and FILE_OVERWRITE_IF. */ + fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_NONE, FILE_OVERWRITE, 0); + + if (fnum1 != -1) { + printf("test 8 open 3 of %s succeeded - should have failed with (NT_STATUS_ACCESS_DENIED)\n", fname); + correct = False; + cli_close(&cli1, fnum1); + } else { + if (check_error(__LINE__, &cli1, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED)) { + printf("correct error code NT_STATUS_ACCESS_DENIED/ERRDOS:ERRnoaccess returned\n"); + } + } + + printf("Attribute open test #8 %s.\n", correct ? "passed" : "failed"); + + cli_unlink(&cli1, fname); + if (!torture_close_connection(&cli1)) { correct = False; } @@ -3483,6 +3533,105 @@ static BOOL run_dirtest(int dummy) return correct; } +static void del_fn(file_info *finfo, const char *mask, void *state) +{ + struct cli_state *pcli = (struct cli_state *)state; + fstring fname; + slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name); + + if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0) + return; + + if (finfo->mode & aDIR) { + if (!cli_rmdir(pcli, fname)) + printf("del_fn: failed to rmdir %s\n,", fname ); + } else { + if (!cli_unlink(pcli, fname)) + printf("del_fn: failed to unlink %s\n,", fname ); + } +} + +static BOOL run_dirtest1(int dummy) +{ + int i; + static struct cli_state cli; + int fnum, num_seen; + BOOL correct = True; + + printf("starting directory test\n"); + + if (!torture_open_connection(&cli)) { + return False; + } + + cli_sockopt(&cli, sockops); + + cli_list(&cli, "\\LISTDIR\\*", 0, del_fn, &cli); + cli_list(&cli, "\\LISTDIR\\*", aDIR, del_fn, &cli); + cli_rmdir(&cli, "\\LISTDIR"); + cli_mkdir(&cli, "\\LISTDIR"); + + /* Create 1000 files and 1000 directories. */ + for (i=0;i<1000;i++) { + fstring fname; + slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i); + fnum = cli_nt_create_full(&cli, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE, + FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0); + if (fnum == -1) { + fprintf(stderr,"Failed to open %s\n", fname); + return False; + } + cli_close(&cli, fnum); + } + for (i=0;i<1000;i++) { + fstring fname; + slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i); + if (!cli_mkdir(&cli, fname)) { + fprintf(stderr,"Failed to open %s\n", fname); + return False; + } + } + + /* Now ensure that doing an old list sees both files and directories. */ + num_seen = cli_list_old(&cli, "\\LISTDIR\\*", aDIR, list_fn, NULL); + printf("num_seen = %d\n", num_seen ); + /* We should see 100 files + 1000 directories + . and .. */ + if (num_seen != 2002) + correct = False; + + /* Ensure if we have the "must have" bits we only see the + * relevent entries. + */ + num_seen = cli_list_old(&cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL); + printf("num_seen = %d\n", num_seen ); + if (num_seen != 1002) + correct = False; + + num_seen = cli_list_old(&cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL); + printf("num_seen = %d\n", num_seen ); + if (num_seen != 1000) + correct = False; + + /* Delete everything. */ + cli_list(&cli, "\\LISTDIR\\*", 0, del_fn, &cli); + cli_list(&cli, "\\LISTDIR\\*", aDIR, del_fn, &cli); + cli_rmdir(&cli, "\\LISTDIR"); + +#if 0 + printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn, NULL)); + printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn, NULL)); + printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn, NULL)); +#endif + + if (!torture_close_connection(&cli)) { + correct = False; + } + + printf("finished dirtest1\n"); + + return correct; +} + static BOOL run_error_map_extract(int dummy) { static struct cli_state c_dos; @@ -3711,6 +3860,7 @@ static struct { {"OPLOCK2", run_oplock2, 0}, {"OPLOCK3", run_oplock3, 0}, {"DIR", run_dirtest, 0}, + {"DIR1", run_dirtest1, 0}, {"DENY1", torture_denytest1, 0}, {"DENY2", torture_denytest2, 0}, {"TCON", run_tcon_test, 0}, @@ -3863,6 +4013,7 @@ static void usage(void) argc--; argv++; + srandom(time(NULL)); fstrcpy(workgroup, lp_workgroup()); diff --git a/source3/utils/net.c b/source3/utils/net.c index fc7094bcf77..800aeded0a6 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -329,6 +329,74 @@ static int net_file(int argc, const char **argv) return net_rap_file(argc, argv); } +/* + Retrieve our local SID or the SID for the specified name + */ +static int net_getlocalsid(int argc, const char **argv) +{ + DOM_SID sid; + const char *name; + fstring sid_str; + + if (argc >= 1) { + name = argv[0]; + } + else { + name = global_myname; + } + + if (!secrets_fetch_domain_sid(name, &sid)) { + DEBUG(0, ("Can't fetch domain SID for name: %s\n", name)); + return 1; + } + sid_to_string(sid_str, &sid); + d_printf("SID for domain %s is: %s\n", name, sid_str); + return 0; +} + +static int net_setlocalsid(int argc, const char **argv) +{ + DOM_SID sid; + + if ( (argc != 1) + || (strncmp(argv[0], "S-1-5-21-", strlen("S-1-5-21-")) != 0) + || (!string_to_sid(&sid, argv[0])) + || (sid.num_auths != 4)) { + d_printf("usage: net setlocalsid S-1-5-21-x-y-z\n"); + return 1; + } + + if (!secrets_store_domain_sid(global_myname, &sid)) { + DEBUG(0,("Can't store domain SID as a pdc/bdc.\n")); + return 1; + } + + return 0; +} + +static int net_getdomainsid(int argc, const char **argv) +{ + DOM_SID domain_sid; + fstring sid_str; + + if (!secrets_fetch_domain_sid(global_myname, &domain_sid)) { + d_printf("Could not fetch local SID\n"); + return 1; + } + sid_to_string(sid_str, &domain_sid); + d_printf("SID for domain %s is: %s\n", global_myname, sid_str); + + if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) { + d_printf("Could not fetch domain SID\n"); + return 1; + } + + sid_to_string(sid_str, &domain_sid); + d_printf("SID for domain %s is: %s\n", lp_workgroup(), sid_str); + + return 0; +} + /* main function table */ static struct functable net_func[] = { {"RPC", net_rpc}, @@ -352,6 +420,10 @@ static struct functable net_func[] = { {"TIME", net_time}, {"LOOKUP", net_lookup}, {"JOIN", net_join}, + {"CACHE", net_cache}, + {"GETLOCALSID", net_getlocalsid}, + {"SETLOCALSID", net_setlocalsid}, + {"GETDOMAINSID", net_getdomainsid}, {"HELP", net_help}, {NULL, NULL} @@ -391,7 +463,7 @@ static struct functable net_func[] = { {"force", 'f', POPT_ARG_NONE, &opt_force}, {"timeout", 't', POPT_ARG_INT, &opt_timeout}, {"machine-pass",'P', POPT_ARG_NONE, &opt_machine_pass}, - { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_debug }, + {"debuglevel", 'D', POPT_ARG_STRING, &debuglevel}, { 0, 0, 0, 0} }; @@ -469,7 +541,7 @@ static struct functable net_func[] = { if (!*global_myname) { char *p2; - fstrcpy(global_myname, myhostname()); + pstrcpy(global_myname, myhostname()); p2 = strchr_m(global_myname, '.'); if (p2) *p2 = 0; diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index ad405fe68c3..af290ce83c6 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -56,6 +56,31 @@ int net_ads_usage(int argc, const char **argv) } +/* + this implements the CLDAP based netlogon lookup requests + for finding the domain controller of a ADS domain +*/ +static int net_ads_lookup(int argc, const char **argv) +{ + ADS_STRUCT *ads; + + ads = ads_init(NULL, NULL, opt_host); + if (ads) { + ads->auth.flags |= ADS_AUTH_NO_BIND; + } + + ads_connect(ads); + + if (!ads || !ads->config.realm) { + d_printf("Didn't find the cldap server!\n"); + return -1; + } + + return ads_cldap_netlogon(ads); +} + + + static int net_ads_info(int argc, const char **argv) { ADS_STRUCT *ads; @@ -63,7 +88,7 @@ static int net_ads_info(int argc, const char **argv) ads = ads_init(NULL, NULL, opt_host); if (ads) { - ads->auth.no_bind = 1; + ads->auth.flags |= ADS_AUTH_NO_BIND; } ads_connect(ads); @@ -78,6 +103,7 @@ static int net_ads_info(int argc, const char **argv) d_printf("Realm: %s\n", ads->config.realm); d_printf("Bind Path: %s\n", ads->config.bind_path); d_printf("LDAP port: %d\n", ads->ldap_port); + d_printf("Server time: %s\n", http_timestring(ads->config.current_time)); return 0; } @@ -174,7 +200,7 @@ static int net_ads_workgroup(int argc, const char **argv) -static void usergrp_display(char *field, void **values, void *data_area) +static BOOL usergrp_display(char *field, void **values, void *data_area) { char **disp_fields = (char **) data_area; @@ -188,15 +214,16 @@ static void usergrp_display(char *field, void **values, void *data_area) } SAFE_FREE(disp_fields[0]); SAFE_FREE(disp_fields[1]); - return; + return True; } if (!values) /* must be new field, indicate string field */ - return; + return True; if (StrCaseCmp(field, "sAMAccountName") == 0) { disp_fields[0] = strdup((char *) values[0]); } if (StrCaseCmp(field, "description") == 0) disp_fields[1] = strdup((char *) values[0]); + return True; } static int net_ads_user_usage(int argc, const char **argv) @@ -245,7 +272,7 @@ static int ads_user_add(int argc, const char **argv) /* try setting the password */ asprintf(&upn, "%s@%s", argv[0], ads->config.realm); - status = krb5_set_password(ads->auth.kdc_server, upn, argv[1]); + status = krb5_set_password(ads->auth.kdc_server, upn, argv[1], ads->auth.time_offset); safe_free(upn); if (ADS_ERR_OK(status)) { d_printf("User %s added\n", argv[0]); @@ -610,7 +637,7 @@ int net_ads_join(int argc, const char **argv) rc = ads_search_dn(ads, &res, dn, NULL); ads_msgfree(ads, res); - if (rc.error_type == ADS_ERROR_LDAP && rc.rc == LDAP_NO_SUCH_OBJECT) { + if (rc.error_type == ADS_ERROR_LDAP && rc.err.rc == LDAP_NO_SUCH_OBJECT) { d_printf("ads_join_realm: organizational unit %s does not exist (dn:%s)\n", org_unit, dn); return -1; @@ -628,15 +655,15 @@ int net_ads_join(int argc, const char **argv) return -1; } - rc = ads_set_machine_password(ads, global_myname, password); + rc = ads_domain_sid(ads, &dom_sid); if (!ADS_ERR_OK(rc)) { - d_printf("ads_set_machine_password: %s\n", ads_errstr(rc)); + d_printf("ads_domain_sid: %s\n", ads_errstr(rc)); return -1; } - rc = ads_domain_sid(ads, &dom_sid); + rc = ads_set_machine_password(ads, global_myname, password); if (!ADS_ERR_OK(rc)) { - d_printf("ads_domain_sid: %s\n", ads_errstr(rc)); + d_printf("ads_set_machine_password: %s\n", ads_errstr(rc)); return -1; } @@ -856,7 +883,7 @@ static int net_ads_password(int argc, const char **argv) new_password = getpass(prompt); ret = kerberos_set_password(ads->auth.kdc_server, auth_principal, - auth_password, argv[0], new_password); + auth_password, argv[0], new_password, ads->auth.time_offset); if (!ADS_ERR_OK(ret)) { d_printf("Password change failed :-( ...\n"); ads_destroy(&ads); @@ -1009,6 +1036,7 @@ int net_ads(int argc, const char **argv) {"PRINTER", net_ads_printer}, {"SEARCH", net_ads_search}, {"WORKGROUP", net_ads_workgroup}, + {"LOOKUP", net_ads_lookup}, {"HELP", net_ads_help}, {NULL, NULL} }; diff --git a/source3/utils/net_help.c b/source3/utils/net_help.c index ab3eac4b434..262670cb2a3 100644 --- a/source3/utils/net_help.c +++ b/source3/utils/net_help.c @@ -58,7 +58,7 @@ static int help_usage(int argc, const char **argv) "\n"\ "Valid functions are:\n"\ " RPC RAP ADS FILE SHARE SESSION SERVER DOMAIN PRINTQ USER GROUP VALIDATE\n"\ -" GROUPMEMBER ADMIN SERVICE PASSWORD TIME LOOKUP\n"); +" GROUPMEMBER ADMIN SERVICE PASSWORD TIME LOOKUP GETLOCALSID SETLOCALSID\n"); return -1; } @@ -135,6 +135,9 @@ static int net_usage(int argc, const char **argv) " net user\t\tto manage users\n"\ " net group\t\tto manage groups\n"\ " net join\t\tto join a domain\n"\ + " net cache\t\tto operate on cache tdb file\n"\ + " net getlocalsid [NAME]\tto get the SID for local name\n"\ + " net setlocalsid SID\tto set the local domain SID\n"\ "\n"\ " net ads \tto run ADS commands\n"\ " net rap \tto run RAP (pre-RPC) commands\n"\ diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 55e8a497cca..8b8278b053e 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -178,7 +178,7 @@ static int run_rpc_command(struct cli_state *cli_arg, const char *pipe_name, int /** * Force a change of the trust acccount password. * - * All paramaters are provided by the run_rpc_command funcion, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid aquired from the remote server @@ -224,7 +224,7 @@ static int rpc_changetrustpw(int argc, const char **argv) * * The password should be created with 'server manager' or eqiv first. * - * All paramaters are provided by the run_rpc_command funcion, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid aquired from the remote server @@ -243,6 +243,7 @@ static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cl extern pstring global_myname; fstring trust_passwd; unsigned char orig_trust_passwd_hash[16]; + NTSTATUS result; fstrcpy(trust_passwd, global_myname); strlower(trust_passwd); @@ -256,7 +257,12 @@ static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cl E_md4hash(trust_passwd, orig_trust_passwd_hash); - return trust_pw_change_and_store_it(cli, mem_ctx, orig_trust_passwd_hash); + result = trust_pw_change_and_store_it(cli, mem_ctx, orig_trust_passwd_hash); + + if (NT_STATUS_IS_OK(result)) + printf("Joined domain %s.\n",lp_workgroup()); + + return result; } /** @@ -319,7 +325,7 @@ int net_rpc_join(int argc, const char **argv) /** * display info about a rpc domain * - * All paramaters are provided by the run_rpc_command function, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid acquired from the remote server @@ -339,6 +345,9 @@ rpc_info_internals(const DOM_SID *domain_sid, struct cli_state *cli, POLICY_HND connect_pol, domain_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; SAM_UNK_CTR ctr; + fstring sid_str; + + sid_to_string(sid_str, domain_sid); /* Get sam policy handle */ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, @@ -361,6 +370,7 @@ rpc_info_internals(const DOM_SID *domain_sid, struct cli_state *cli, if (NT_STATUS_IS_OK(result)) { TALLOC_CTX *ctx = talloc_init(); d_printf("Domain Name: %s\n", unistr2_tdup(ctx, &ctr.info.inf2.uni_domain)); + d_printf("Domain SID: %s\n", sid_str); d_printf("Sequence number: %u\n", ctr.info.inf2.seq_num); d_printf("Num users: %u\n", ctr.info.inf2.num_domain_usrs); d_printf("Num domain groups: %u\n", ctr.info.inf2.num_domain_grps); @@ -387,6 +397,53 @@ int net_rpc_info(int argc, const char **argv) } +/** + * Fetch domain SID into the local secrets.tdb + * + * All parameters are provided by the run_rpc_command function, except for + * argc, argv which are passes through. + * + * @param domain_sid The domain sid acquired from the remote server + * @param cli A cli_state connected to the server. + * @param mem_ctx Talloc context, destoyed on completion 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_getsid_internals(const DOM_SID *domain_sid, struct cli_state *cli, + TALLOC_CTX *mem_ctx, int argc, const char **argv) +{ + fstring sid_str; + + sid_to_string(sid_str, domain_sid); + d_printf("Storing SID %s for Domain %s in secrets.tdb\n", + sid_str, lp_workgroup()); + + if (!secrets_store_domain_sid(global_myname, domain_sid)) { + DEBUG(0,("Can't store domain SID\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + return NT_STATUS_OK; +} + + +/** + * 'net rpc getsid' entrypoint. + * @param argc Standard main() style argc + * @param argc Standard main() style argv. Initial components are already + * stripped + **/ +int net_rpc_getsid(int argc, const char **argv) +{ + return run_rpc_command(NULL, PIPE_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, + rpc_getsid_internals, + argc, argv); +} /****************************************************************************/ @@ -406,7 +463,7 @@ static int rpc_user_usage(int argc, const char **argv) /** * Add a new user to a remote RPC server * - * All paramaters are provided by the run_rpc_command funcion, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid acquired from the remote server @@ -494,7 +551,7 @@ static int rpc_user_add(int argc, const char **argv) /** * Delete a user from a remote RPC server * - * All paramaters are provided by the run_rpc_command funcion, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid acquired from the remote server @@ -595,7 +652,7 @@ static int rpc_user_delete(int argc, const char **argv) /** * List user's groups on a remote RPC server * - * All paramaters are provided by the run_rpc_command funcion, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid acquired from the remote server @@ -697,7 +754,7 @@ static int rpc_user_info(int argc, const char **argv) /** * List users on a remote RPC server * - * All paramaters are provided by the run_rpc_command function, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid acquired from the remote server @@ -811,7 +868,7 @@ static int rpc_group_usage(int argc, const char **argv) /** * List groups on a remote RPC server * - * All paramaters are provided by the run_rpc_command funcion, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid acquired from the remote server @@ -954,7 +1011,7 @@ static int rpc_share_usage(int argc, const char **argv) /** * Add a share on a remote RPC server * - * All paramaters are provided by the run_rpc_command function, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid acquired from the remote server @@ -1002,7 +1059,7 @@ static int rpc_share_add(int argc, const char **argv) /** * Delete a share on a remote RPC server * - * All paramaters are provided by the run_rpc_command function, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid acquired from the remote server @@ -1070,7 +1127,7 @@ static void display_share_info_1(SRV_SHARE_INFO_1 *info1) /** * List shares on a remote RPC server * - * All paramaters are provided by the run_rpc_command function, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid acquired from the remote server @@ -1147,7 +1204,7 @@ static int rpc_file_usage(int argc, const char **argv) /** * Close a file on a remote RPC server * - * All paramaters are provided by the run_rpc_command function, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid acquired from the remote server @@ -1210,7 +1267,7 @@ static void display_file_info_3(FILE_INFO_3 *info3, FILE_INFO_3_STR *str3) /** * List open files on a remote RPC server * - * All paramaters are provided by the run_rpc_command funcion, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid acquired from the remote server @@ -1314,7 +1371,7 @@ int net_rpc_file(int argc, const char **argv) /** * ABORT the shutdown of a remote RPC Server * - * All paramaters are provided by the run_rpc_command function, except for + * 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 @@ -1362,7 +1419,7 @@ static int rpc_shutdown_abort(int argc, const char **argv) /** * Shut down a remote RPC Server * - * All paramaters are provided by the run_rpc_command funcion, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid aquired from the remote server @@ -1914,6 +1971,12 @@ static int rpc_trustdom_list(int argc, const char **argv) d_printf("%s%s%s\n", trusted_dom_names[i], padding, ascii_sid); }; + + /* + * in case of no trusted domains say something rather + * than just display blank line + */ + if (!num_domains) d_printf("none\n"); } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES)); @@ -2018,6 +2081,8 @@ static int rpc_trustdom_list(int argc, const char **argv) }; }; + if (!num_domains) d_printf("none\n"); + } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES)); /* close opened samr and domain policy handles */ @@ -2083,7 +2148,7 @@ BOOL net_rpc_check(unsigned flags) /* flags (i.e. server type) may depend on command */ if (!net_find_server(flags, &server_ip, &server_name)) - goto done; + return False; ZERO_STRUCT(cli); if (cli_initialise(&cli) == False) @@ -2120,12 +2185,13 @@ int net_rpc_usage(int argc, const char **argv) { d_printf(" net rpc info \t\t\tshow basic info about a domain \n"); d_printf(" net rpc join \t\t\tto join a domain \n"); - d_printf(" net rpc testjoin \t\t\ttests that a join is valid\n"); + d_printf(" net rpc testjoin \t\ttests that a join is valid\n"); d_printf(" net rpc user \t\t\tto add, delete and list users\n"); d_printf(" net rpc group \t\tto list groups\n"); d_printf(" net rpc share \t\tto add, delete, and list shares\n"); d_printf(" net rpc file \t\t\tto list open files\n"); d_printf(" net rpc changetrustpw \tto change the trust account password\n"); + d_printf(" net rpc getsid \t\tfetch the domain sid into the local secrets.tdb\n"); d_printf(" net rpc trustdom \t\tto create trusting domain's account\n" "\t\t\t\t\tor establish trust\n"); d_printf(" net rpc abortshutdown \tto abort the shutdown of a remote server\n"); @@ -2192,6 +2258,9 @@ int net_rpc(int argc, const char **argv) {"trustdom", rpc_trustdom}, {"abortshutdown", rpc_shutdown_abort}, {"shutdown", rpc_shutdown}, + {"samdump", rpc_samdump}, + {"vampire", rpc_vampire}, + {"getsid", net_rpc_getsid}, {"help", net_rpc_help}, {NULL, NULL} }; diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c index c8be93c39cc..b08095f1ccb 100644 --- a/source3/utils/net_rpc_join.c +++ b/source3/utils/net_rpc_join.c @@ -49,6 +49,7 @@ int net_rpc_join_ok(const char *domain) int retval = 1; uint32 channel; NTSTATUS result; + uint32 neg_flags = 0x000001ff; /* Connect to remote machine */ if (!(cli = net_make_ipc_connection(NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC))) { @@ -75,7 +76,7 @@ int net_rpc_join_ok(const char *domain) CHECK_RPC_ERR(cli_nt_setup_creds(cli, channel, - stored_md4_trust_password), + stored_md4_trust_password, &neg_flags, 2), "error in domain join verification"); retval = 0; /* Success! */ diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index 51dbbb98c06..7c61e6d8be4 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -508,6 +508,17 @@ int main (int argc, char **argv) exit(1); } + if (!*global_myname) { + char *p2; + + pstrcpy(global_myname, myhostname()); + p2 = strchr_m(global_myname, '.'); + if (p2) + *p2 = 0; + } + + strupper(global_myname); + setparms = (config_file ? BIT_CONFIGFILE : 0) + (new_debuglevel ? BIT_DEBUGLEVEL : 0) + (backend ? BIT_BACKEND : 0) + @@ -544,7 +555,7 @@ int main (int argc, char **argv) /* the lowest bit options are always accepted */ checkparms = setparms & ~MASK_ALWAYS_GOOD; - /* accoun tpolicy operations */ + /* account policy operations */ if ((checkparms & BIT_ACCPOLICY) && !(checkparms & ~(BIT_ACCPOLICY + BIT_ACCPOLVAL))) { uint32 value; int field = account_policy_name_to_fieldnum(account_policy); diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c index 2d78b21dcc8..5401755376d 100644 --- a/source3/utils/smbcontrol.c +++ b/source3/utils/smbcontrol.c @@ -42,6 +42,7 @@ static struct { {"dmalloc-mark", MSG_REQ_DMALLOC_MARK }, {"dmalloc-log-changed", MSG_REQ_DMALLOC_LOG_CHANGED }, {"shutdown", MSG_SHUTDOWN }, + {"change_id", MSG_PRINTER_DRVUPGRADE}, {NULL, -1} }; @@ -553,6 +554,10 @@ static BOOL do_command(char *dest, char *msg_name, int iparams, char **params) if (!send_message(dest, MSG_SHUTDOWN, NULL, 0, False)) return False; break; + case MSG_PRINTER_DRVUPGRADE: + if (!send_message(dest, MSG_PRINTER_DRVUPGRADE, params[0], 0, False)) + return False; + break; } return (True); diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c index 98993676c98..75a4319cb96 100644 --- a/source3/utils/smbpasswd.c +++ b/source3/utils/smbpasswd.c @@ -217,23 +217,23 @@ static int process_options(int argc, char **argv, int local_flags) *************************************************************/ static char *stdin_new_passwd(void) { - static fstring new_passwd; + static fstring new_pw; size_t len; - ZERO_ARRAY(new_passwd); + ZERO_ARRAY(new_pw); /* * if no error is reported from fgets() and string at least contains * the newline that ends the password, then replace the newline with * a null terminator. */ - if ( fgets(new_passwd, sizeof(new_passwd), stdin) != NULL) { - if ((len = strlen(new_passwd)) > 0) { - if(new_passwd[len-1] == '\n') - new_passwd[len - 1] = 0; + if ( fgets(new_pw, sizeof(new_pw), stdin) != NULL) { + if ((len = strlen(new_pw)) > 0) { + if(new_pw[len-1] == '\n') + new_pw[len - 1] = 0; } } - return(new_passwd); + return(new_pw); } @@ -259,20 +259,20 @@ static char *get_pass( char *prompt, BOOL stdin_get) static char *prompt_for_new_password(BOOL stdin_get) { char *p; - fstring new_passwd; + fstring new_pw; - ZERO_ARRAY(new_passwd); + ZERO_ARRAY(new_pw); p = get_pass("New SMB password:", stdin_get); - fstrcpy(new_passwd, p); + fstrcpy(new_pw, p); SAFE_FREE(p); p = get_pass("Retype new SMB password:", stdin_get); - if (strcmp(p, new_passwd)) { + if (strcmp(p, new_pw)) { fprintf(stderr, "Mismatch - password unchanged.\n"); - ZERO_ARRAY(new_passwd); + ZERO_ARRAY(new_pw); SAFE_FREE(p); return NULL; } @@ -285,27 +285,27 @@ static char *prompt_for_new_password(BOOL stdin_get) Change a password either locally or remotely. *************************************************************/ -static BOOL password_change(const char *remote_machine, char *user_name, - char *old_passwd, char *new_passwd, int local_flags) +static BOOL password_change(const char *remote_mach, char *username, + char *old_passwd, char *new_pw, int local_flags) { BOOL ret; pstring err_str; pstring msg_str; - if (remote_machine != NULL) { + if (remote_mach != NULL) { if (local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER|LOCAL_DISABLE_USER|LOCAL_ENABLE_USER| LOCAL_TRUST_ACCOUNT|LOCAL_SET_NO_PASSWORD)) { /* these things can't be done remotely yet */ return False; } - ret = remote_password_change(remote_machine, user_name, - old_passwd, new_passwd, err_str, sizeof(err_str)); + ret = remote_password_change(remote_mach, username, + old_passwd, new_pw, err_str, sizeof(err_str)); if(*err_str) fprintf(stderr, err_str); return ret; } - ret = local_password_change(user_name, local_flags, new_passwd, + ret = local_password_change(username, local_flags, new_pw, err_str, sizeof(err_str), msg_str, sizeof(msg_str)); if(*msg_str) diff --git a/source3/utils/status.c b/source3/utils/status.c index 0b0c591cb16..d87497f2fa3 100644 --- a/source3/utils/status.c +++ b/source3/utils/status.c @@ -146,6 +146,7 @@ static void print_brl(SMB_DEV_T dev, SMB_INO_T ino, int pid, ******************************************************************/ static int profile_dump(void) { +#ifdef WITH_PROFILE if (!profile_setup(True)) { fprintf(stderr,"Failed to initialise profile memory\n"); return -1; @@ -482,6 +483,9 @@ static int profile_dump(void) d_printf("run_elections_time: %u\n", profile_p->run_elections_time); d_printf("election_count: %u\n", profile_p->election_count); d_printf("election_time: %u\n", profile_p->election_time); +#else /* WITH_PROFILE */ + fprintf(stderr, "Profile data unavailable\n"); +#endif /* WITH_PROFILE */ return 0; } @@ -549,7 +553,9 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo {"conf", 's', POPT_ARG_STRING, 0, 's'}, {"user", 'u', POPT_ARG_STRING, 0, 'u'}, {"brief", 'b', POPT_ARG_NONE, &brief}, +#ifdef WITH_PROFILE {"profile", 'P', POPT_ARG_NONE, &profile_only}, +#endif /* WITH_PROFILE */ {"byterange", 'B', POPT_ARG_NONE, &show_brl}, { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_debug }, { 0, 0, 0, 0} diff --git a/source3/utils/testparm.c b/source3/utils/testparm.c index 3086019467d..d48cecba47b 100644 --- a/source3/utils/testparm.c +++ b/source3/utils/testparm.c @@ -48,7 +48,7 @@ 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 also be set to 'true'.\n"); + printf("ERROR: in 'security=domain' mode the 'encrypt passwords' parameter must always be set to 'true'.\n"); ret = 1; } @@ -171,7 +171,7 @@ via the %%o substitution. With encrypted passwords this is not possible.\n", lp_ return ret; } -int main(int argc, char *argv[]) +int main(int argc, const char *argv[]) { extern char *optarg; extern int optind; @@ -185,17 +185,19 @@ int main(int argc, char *argv[]) static char *new_local_machine = NULL; const char *cname; const char *caddr; + static int show_defaults; struct poptOption long_options[] = { POPT_AUTOHELP {"suppress-prompt", 's', POPT_ARG_VAL, &silent_mode, 1, "Suppress prompt for enter"}, + {"verbose", 'v', POPT_ARG_NONE, &show_defaults, 1, "Show default options too"}, {"server", 'L',POPT_ARG_STRING, &new_local_machine, 0, "Set %%L macro to servername\n"}, {"encoding", 't', POPT_ARG_STRING, &term_code, 0, "Print parameters with encoding"}, {0,0,0,0} }; - pc = poptGetContext(NULL, argc, (const char **) argv, long_options, - POPT_CONTEXT_KEEP_FIRST); + pc = poptGetContext(NULL, argc, argv, long_options, + POPT_CONTEXT_KEEP_FIRST); while((opt = poptGetNextOpt(pc)) != -1); @@ -276,7 +278,7 @@ int main(int argc, char *argv[]) fflush(stdout); getc(stdin); } - lp_dump(stdout,True, lp_numservices()); + lp_dump(stdout, show_defaults, lp_numservices()); } if(cname && caddr){ diff --git a/source3/web/swat.c b/source3/web/swat.c index 80d3232d2bf..af6fa82ffe5 100644 --- a/source3/web/swat.c +++ b/source3/web/swat.c @@ -1,7 +1,9 @@ /* Unix SMB/CIFS implementation. Samba Web Administration Tool - Copyright (C) Andrew Tridgell 1997-1998 + Version 3.0.0 + Copyright (C) Andrew Tridgell 1997-2002 + Copyright (C) John H Terpstra 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -297,7 +299,7 @@ static void show_parameter(int snum, struct parm_struct *parm) /**************************************************************************** display a set of parameters for a service ****************************************************************************/ -static void show_parameters(int snum, int allparameters, int advanced, int printers) +static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers) { int i = 0; struct parm_struct *parm; @@ -316,7 +318,7 @@ static void show_parameters(int snum, int allparameters, int advanced, int print if (printers & !(parm->flags & FLAG_PRINT)) continue; if (!printers & !(parm->flags & FLAG_SHARE)) continue; } - if (!advanced) { + if (parm_filter == FLAG_BASIC) { if (!(parm->flags & FLAG_BASIC)) { void *ptr = parm->ptr; @@ -363,6 +365,12 @@ static void show_parameters(int snum, int allparameters, int advanced, int print } if (printers && !(parm->flags & FLAG_PRINT)) continue; } + if (parm_filter == FLAG_WIZARD) { + if (!((parm->flags & FLAG_WIZARD))) continue; + } + if (parm_filter == FLAG_ADVANCED) { + if (!((parm->flags & FLAG_ADVANCED))) continue; + } if (heading && heading != last_heading) { d_printf("%s\n", _(heading)); last_heading = heading; @@ -393,7 +401,7 @@ static void write_config(FILE *f, BOOL show_defaults) } /**************************************************************************** - save and reoad the smb.conf config file + save and reload the smb.conf config file ****************************************************************************/ static int save_reload(int snum) { @@ -497,6 +505,7 @@ static void show_main_buttons(void) image_link(_("Globals"), "globals", "images/globals.gif"); image_link(_("Shares"), "shares", "images/shares.gif"); image_link(_("Printers"), "printers", "images/printers.gif"); + image_link(_("Wizard"), "wizard", "images/wizard.gif"); } if (have_read_access) { image_link(_("Status"), "status", "images/status.gif"); @@ -507,6 +516,18 @@ static void show_main_buttons(void) d_printf("
\n"); } +/**************************************************************************** + * Handle Display/Edit Mode CGI + ****************************************************************************/ +static void ViewModeBoxes(int mode) +{ + d_printf("

%s\n", _("Configuration View: ")); + d_printf("Basic\n", (mode == 0) ? "checked" : ""); + d_printf("Advanced\n", (mode == 1) ? "checked" : ""); + d_printf("Developer\n", (mode == 2) ? "checked" : ""); + d_printf("


\n"); +} + /**************************************************************************** display a welcome page ****************************************************************************/ @@ -541,25 +562,240 @@ static void viewconfig_page(void) d_printf("\n"); } +/**************************************************************************** + second screen of the wizard ... Fetch Configuration Parameters +****************************************************************************/ +static void wizard_params_page(void) +{ + unsigned int parm_filter = FLAG_WIZARD; + + /* Here we first set and commit all the parameters that were selected + in the previous screen. */ + + d_printf("

Wizard Parameter Edit Page

\n"); + + if (cgi_variable("Commit")) { + commit_parameters(GLOBALS_SNUM); + save_reload(0); + } + + d_printf("
\n"); + + if (have_write_access) { + d_printf("\n"); + } + + d_printf("\n"); + d_printf("

\n"); + + d_printf("\n"); + show_parameters(GLOBALS_SNUM, 1, parm_filter, 0); + d_printf("
\n"); + d_printf("

\n"); +} + +/**************************************************************************** + Utility to just rewrite the smb.conf file - effectively just cleans it up +****************************************************************************/ +static void rewritecfg_file(void) +{ + commit_parameters(GLOBALS_SNUM); + save_reload(0); + d_printf("

Note: smb.conf %s

\n", _("file has been read and rewritten")); +} + +/**************************************************************************** + wizard to create/modify the smb.conf file +****************************************************************************/ +static void wizard_page(void) +{ + /* Set some variables to collect data from smb.conf */ + int role = 0; + int winstype = 0; + int have_home = -1; + int HomeExpo = 0; + int SerType = 0; + + if (cgi_variable("Rewrite")) { + (void) rewritecfg_file(); + return; + } + + if (cgi_variable("GetWizardParams")){ + (void) wizard_params_page(); + return; + } + + if (cgi_variable("Commit")){ + SerType = atoi(cgi_variable("ServerType")); + winstype = atoi(cgi_variable("WINSType")); + have_home = lp_servicenumber(HOMES_NAME); + HomeExpo = atoi(cgi_variable("HomeExpo")); + + /* Plain text passwords are too badly broken - use encrypted passwords only */ + lp_do_parameter( GLOBALS_SNUM, "encrypt passwords", "Yes"); + + switch ( SerType ){ + case 0: + /* Stand-alone Server */ + lp_do_parameter( GLOBALS_SNUM, "security", "USER" ); + lp_do_parameter( GLOBALS_SNUM, "domain logons", "No" ); + break; + case 1: + /* Domain Member */ + lp_do_parameter( GLOBALS_SNUM, "security", "DOMAIN" ); + lp_do_parameter( GLOBALS_SNUM, "domain logons", "No" ); + break; + case 2: + /* Domain Controller */ + lp_do_parameter( GLOBALS_SNUM, "security", "USER" ); + lp_do_parameter( GLOBALS_SNUM, "domain logons", "Yes" ); + break; + } + switch ( winstype ) { + case 0: + lp_do_parameter( GLOBALS_SNUM, "wins support", "No" ); + lp_do_parameter( GLOBALS_SNUM, "wins server", "" ); + break; + case 1: + lp_do_parameter( GLOBALS_SNUM, "wins support", "Yes" ); + lp_do_parameter( GLOBALS_SNUM, "wins server", "" ); + break; + case 2: + lp_do_parameter( GLOBALS_SNUM, "wins support", "No" ); + lp_do_parameter( GLOBALS_SNUM, "wins server", cgi_variable("WINSAddr")); + break; + } + + /* Have to create Homes share? */ + if ((HomeExpo == 1) && (have_home == -1)) { + pstring unix_share; + + pstrcpy(unix_share,HOMES_NAME); + load_config(False); + lp_copy_service(GLOBALS_SNUM, unix_share); + iNumNonAutoPrintServices = lp_numservices(); + have_home = lp_servicenumber(HOMES_NAME); + lp_do_parameter( have_home, "read only", "No"); + lp_do_parameter( have_home, "valid users", "%S"); + lp_do_parameter( have_home, "browseable", "No"); + commit_parameters(have_home); + } + + /* Need to Delete Homes share? */ + if ((HomeExpo == 0) && (have_home != -1)) { + lp_remove_service(have_home); + have_home = -1; + } + + commit_parameters(GLOBALS_SNUM); + save_reload(0); + } + else + { + /* Now determine smb.conf WINS settings */ + if (lp_wins_support()) + winstype = 1; +/* if (strlen(lp_wins_server_list()) != 0 ) + * winstype = 2; + */ + + /* Do we have a homes share? */ + have_home = lp_servicenumber(HOMES_NAME); + } + if ((winstype == 2) && lp_wins_support()) + winstype = 3; + + role = lp_server_role(); + + /* Here we go ... */ + d_printf("

Samba Configuration Wizard

\n"); + d_printf("
\n"); + + if (have_write_access) { + d_printf(_("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments.\n")); + d_printf(_("The same will happen if you press the commit button.")); + d_printf("

"); + d_printf("
"); + d_printf("   ",_("Rewrite smb.conf file")); + d_printf("   ",_("Commit")); + d_printf("", _("Edit Parameter Values")); + d_printf("
"); + } + + d_printf("
"); + d_printf("
"); + d_printf("\n", "Server Type: "); + d_printf("", (role == ROLE_STANDALONE) ? "checked" : ""); + d_printf("", (role == ROLE_DOMAIN_MEMBER) ? "checked" : ""); + d_printf("", (role == ROLE_DOMAIN_PDC) ? "checked" : ""); + d_printf(""); + if (role == ROLE_DOMAIN_BDC) { + d_printf(""); + } + d_printf("\n", "Configure WINS As: "); + d_printf("", (winstype == 0) ? "checked" : ""); + d_printf("", (winstype == 1) ? "checked" : ""); + d_printf("", (winstype == 2) ? "checked" : ""); + d_printf("",lp_wins_server_list()); + if (winstype == 3) { + d_printf(""); + d_printf(""); + } + d_printf(""); + d_printf("\n","Expose Home Directories: "); + d_printf("", (have_home == -1) ? "" : "checked "); + d_printf("", (have_home == -1 ) ? "checked" : ""); + d_printf(""); + + /* Enable this when we are ready .... + * d_printf("\n","Is Print Server: "); + * d_printf(""); + * d_printf(""); + * d_printf(""); + */ + + d_printf("
%s Stand Alone  Domain Member  Domain Controller 
Unusual Type in smb.conf - Please Select New Mode
%s Not Used  Server for client use  Client of another WINS server 
Remote WINS Server 
Error: WINS Server Mode and WINS Support both set in smb.conf
Please Select desired WINS mode above.
%s Yes No
%s Yes No
"); + d_printf("
"); + + d_printf(_("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment.\n")); + d_printf("
\n"); +} + + /**************************************************************************** display a globals editing page ****************************************************************************/ static void globals_page(void) { - int advanced = 0; + unsigned int parm_filter = FLAG_BASIC; + int mode = 0; d_printf("

%s

\n", _("Global Variables")); - if (cgi_variable("Advanced") && !cgi_variable("Basic")) - advanced = 1; - if (cgi_variable("Commit")) { commit_parameters(GLOBALS_SNUM); save_reload(0); } - d_printf("
\n"); - + if ( cgi_variable("ViewMode") ) + mode = atoi(cgi_variable("ViewMode")); + + d_printf("\n"); + + ViewModeBoxes( mode ); + switch ( mode ) { + case 0: + parm_filter = FLAG_BASIC; + break; + case 1: + parm_filter = FLAG_ADVANCED; + break; + case 2: + parm_filter = FLAG_DEVELOPER; + break; + } + d_printf("
\n"); if (have_write_access) { d_printf("\n", _("Commit Changes")); @@ -567,22 +803,12 @@ static void globals_page(void) d_printf("\n", _("Reset Values")); - if (advanced == 0) { - d_printf("\n", _("Advanced View")); - } else { - d_printf("\n", _("Basic View")); - } + d_printf("

\n"); - d_printf("\n"); - show_parameters(GLOBALS_SNUM, 1, advanced, 0); + show_parameters(GLOBALS_SNUM, 1, parm_filter, 0); d_printf("
\n"); - - if (advanced) { - d_printf("\n"); - } - - d_printf("

\n"); + d_printf("\n"); } /**************************************************************************** @@ -595,16 +821,14 @@ static void shares_page(void) char *s; int snum = -1; int i; - int advanced = 0; + int mode = 0; + unsigned int parm_filter = FLAG_BASIC; if (share) snum = lp_servicenumber(share); d_printf("

%s

\n", _("Share Parameters")); - if (cgi_variable("Advanced") && !cgi_variable("Basic")) - advanced = 1; - if (cgi_variable("Commit") && snum >= 0) { commit_parameters(snum); save_reload(0); @@ -628,7 +852,21 @@ static void shares_page(void) d_printf("
\n"); d_printf("\n"); - d_printf("\n"); + if ( cgi_variable("ViewMode") ) + mode = atoi(cgi_variable("ViewMode")); + ViewModeBoxes( mode ); + switch ( mode ) { + case 0: + parm_filter = FLAG_BASIC; + break; + case 1: + parm_filter = FLAG_ADVANCED; + break; + case 2: + parm_filter = FLAG_DEVELOPER; + break; + } + d_printf("
\n"); d_printf("\n", _("Choose Share")); d_printf("
\n", _("Reset Values")); - if (advanced == 0) { - d_printf("\n", _("Advanced View")); - } else { - d_printf("\n", _("Basic View")); - } d_printf("

\n"); } if (snum >= 0) { d_printf("\n"); - show_parameters(snum, 1, advanced, 0); + show_parameters(snum, 1, parm_filter, 0); d_printf("
\n"); } - if (advanced) { - d_printf("\n"); - } - d_printf("\n"); } @@ -922,7 +1151,8 @@ static void printers_page(void) char *s; int snum=-1; int i; - int advanced = 0; + int mode = 0; + unsigned int parm_filter = FLAG_BASIC; if (share) snum = lp_servicenumber(share); @@ -935,9 +1165,6 @@ static void printers_page(void) d_printf("%s\n", _("Printcap Name")); d_printf(_("Attempting to delete these printers from SWAT will have no effect.\n")); - if (cgi_variable("Advanced") && !cgi_variable("Basic")) - advanced = 1; - if (cgi_variable("Commit") && snum >= 0) { commit_parameters(snum); if (snum >= iNumNonAutoPrintServices) @@ -965,6 +1192,20 @@ static void printers_page(void) d_printf("

\n"); + if ( cgi_variable("ViewMode") ) + mode = atoi(cgi_variable("ViewMode")); + ViewModeBoxes( mode ); + switch ( mode ) { + case 0: + parm_filter = FLAG_BASIC; + break; + case 1: + parm_filter = FLAG_ADVANCED; + break; + case 2: + parm_filter = FLAG_DEVELOPER; + break; + } d_printf("\n"); d_printf("\n", _("Choose Printer")); d_printf("
\n", _("Commit Changes")); } d_printf("\n", _("Reset Values")); - if (advanced == 0) { - d_printf("\n", _("Advanced View")); - } else { - d_printf("\n", _("Basic View")); - } d_printf("

\n"); } if (snum >= 0) { d_printf("\n"); - show_parameters(snum, 1, advanced, 1); + show_parameters(snum, 1, parm_filter, 1); d_printf("
\n"); } - - if (advanced) { - d_printf("\n"); - } - d_printf("\n"); } @@ -1109,6 +1340,12 @@ static void printers_page(void) viewconfig_page(); } else if (strcmp(page,"passwd")==0) { passwd_page(); + } else if (have_read_access && strcmp(page,"wizard")==0) { + wizard_page(); + } else if (have_read_access && strcmp(page,"wizard_params")==0) { + wizard_params_page(); + } else if (have_read_access && strcmp(page,"rewritecfg")==0) { + rewritecfg_file(); } else { welcome_page(); } -- 2.34.1